Чтение онлайн

на главную - закладки

Жанры

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Кёртен Роб

Шрифт:

Прежде чем рассматривать эту функцию с позиций администратора ресурсов, надо сначала понять, что это за зверь. Функция devctl применяется для «нестандартных» и «управляющих» операций. Например, вы можете записывать данные в звуковую плату (реальные оцифрованные звуковые фрагменты, которые звуковая плата должна будет конвертировать в аналоговый аудиосигнал) и принять решение об изменении числа каналов от одного (моно) до двух (стерео) или об изменении частоты дискретизации данных от стандарта CD (44.1 кГц) к стандарту DAT (48 кГц). Такие вещи было бы правильно делать при помощи функции devctl. При написании администратора ресурсов вы можете решить, что вам вообще не нужны никакие devctl, и что всю необходимую функциональность

можно свести к стандартным функциям read и write. С другой стороны, вы можете захотеть использовать как вызовы devctl наряду с вызовами read и write, так и только devctl — это будет зависеть от вашего устройства.

Функция devctl принимает 5 аргументов:

fd Дескриптор файла администратора ресурсов, которому вы посылаете команду devctl.
dcmd Собственно команда — комбинация из двух разрядов направления обмена данными и 30 разрядов команды (см. ниже).
dev_data_ptr Указатель на область данных, которые передаются, принимаются или и то, и другое.
nbytes Размер области данных, на которую указывает dev_data_ptr.
dev_info_ptr Переменная для дополнительной информации, установку которой может выполнить администратор ресурса.

Двумя старшими разрядами команды dcmd кодируется направление обмена данными, если он вообще имеет место. Подробности см. выше в описании функций ввода/вывода (параграф «io_devctl»).

Когда администратор ресурсов принимает сообщение _IO_DEVCTL, оно обрабатывается вашей функцией io_devctl. Ниже представлен очень простой пример, который предполагается использовать для настройки каналов и частоты дискретизации для аудиоустройства, как упоминалось выше.

/*

 * io_devctl1.c

*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <sys/neutrino.h>

#include <sys/iofunc.h>

#define DCMD_AUDIO_SET_CHANNEL_MONO 1

#define DCMD_AUDIO_SET_CHANNEL_STEREO 2

#define DCMD_AUDIO_SET_SAMPLE_RATE_CD 3

#define DCMD_AUDIO_SET_SAMPLE_RATE_DAT 4

int io_devctl(resmgr_context_t *ctp, io_devctl_t *msg,

 iofunc_ocb_t *ocb) {

 int sts;

 // 1) Проверить, не является ли это обычным

 // POSIX-совместимым devctl

 if ((sts =

iofunc_devctl_default(ctp, msg, ocb)) !=

_RESMGR_DEFAULT) {

return (sts);

 }

 // 2) Узнать, что за команда, и отработать ее

 switch (msg->i.dcmd) {

 case DCMD_AUDIO_SET_CHANNEL_MONO:

audio_set_nchannels(1);

break;

 case DCMD_AUDIO_SET_CHANNEL_STEREO:

audio_set_nchannels(2);

break;

 case DCMD_AUDIO_SET_SAMPLE_RATE_CD:

audio_set_samplerate(44100);

break;

 case DCMD_AUDIO_SET_SAMPLE_RATE_DAT:

audio_set_samplerate(48000);

break;

 // 3)
Если мы не знаем такой команды, отвергнуть ее

 default:

return (ENOSYS);

 }

 // 4) Сказать клиенту, что все отработано

 memset(imsg->о, 0, sizeof(msg->о));

 SETIOV(ctp->iov, &msg->o, sizeof(msg->o));

 return (_RESMGR_NPARTS(1));

}

Этап 1

На первом этапе мы снова видим применение вспомогательной функции, на этот раз — функции iofunc_devctl_default, которая используется для выполнения всей обработки по умолчанию для devctl. Если вы не поставляете свою версию io_devctl, а только инициализируете таблицы функций ввода/вывода и установления соединения при помощи iofunc_func_init, будет вызвана именно iofunc_devctl_default. Мы включаем ее в нашу версию io_devctl, потому что мы хотим, чтобы она обработала для нас все стандартные POSIX-варианты вызова devctl. Затем мы проверяем возвращаемое значение; если это не _RESMGR_DEFAULT, значит, функция iofunc_devctl_default «обработала» запрос, и нам остается только возвратить это значение, выдав его за «наше».

Если возвращенное значение является константой _RESMGR_DEFAULT, это говорит нам, что вспомогательная функция не обработала запрос, и что мы должны выяснить, является ли он одним из «наших».

Этап 2

Эта проверка выполняется на этапе 2 при помощи инструкции

switch
/
case
. Мы просто проверяем значение dcmd, которое клиентский код указал во втором параметре функции devctl, на предмет совпадения с какой-нибудь из «наших» команд. Обратите внимание, что для выполнения фактической «работы» для клиента мы вызываем фиктивные функции audio_set_nchannels и audio_set_samplerate. Здесь важно отметить, что мы преднамеренно избегаем обсуждения области данных функции devctl. Вы можете подумать: «А что если я хочу установить частоту дискретизации в некое значение n? Как это сделать?» На этот вопрос мы ответим в следующем примере io_devctl, который представлен ниже.

Этап 3

Этот этап — дань концепции защитного программирования. Мы возвращаем код ошибки ENOSYS, чтобы сообщить клиенту, что мы не распознали его запрос.

Этап 4

Наконец, мы обнуляем возвратную структуру и устанавливаем на нее одноэлементный вектор ввода/вывода. Затем мы возвращаем библиотеке администратора ресурсов единицу (1) через макрос _RESMGR_NPARTS, сообщая ей тем самым, что мы возвращаем одноэлементный вектор ввода/вывода. Это и будет возвращено клиенту. Как вариант, мы могли бы применить макрос _RESMGR_PTR:

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец