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

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

Жанры

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

Кёртен Роб

Шрифт:

Обмен специализированными сообщениями происходит в функции CLID_IPC. Она берет значение глобальной переменной CLID_IPCData и пробует переслать его серверу, используя функцию QNX4 Send.

Специализированные сообщения могут быть обработаны о из двух способов. Можно:

1. транслировать их в стандартные вызовы функций POSIX основанные на файловых дескрипторах;

2. инкапсулировать их в сообщение типа devctl, либо в специализированное сообщение, используя тип _IO_MSG.

В обоих случаях вы перестраиваете клиента на обмен сообщениями стандартными

для администраторов ресурсов средствами. Как? У вас нет файлового дескриптора? Есть только идентификатор соединения? Или наоборот? Ну, это как раз не проблема. В QNX/Neutrino дескриптор файла в действительности является идентификатором соединения!

Трансляция сообщений в стандартные вызовы POSIX на основе файловых дескрипторов

В случае CLID-сервера это не вариант. Не существует стандартного POSIX-вызова на основе файлового дескриптора, который мог бы «добавить к администратору ресурса CLID пару NPA/NXX». Однако, существует стандартный механизм devctl, так что если ваши отношения клиент/сервер требуют такой формы, смотрите ниже.

Прежде чем броситься реализовывать этот подход (трансляцию в стандартные сообщения на основе файловых дескрипторов), давайте остановимся и подумаем, где это может оказаться полезным. В аудиодрайвере QNX4 вы могли бы использовать нестандартные сообщения для передачи аудиоданных администратору и от него. При ближайшем рассмотрении здесь, для задачи блочной передачи данных, вероятно, наиболее бы подошли функции read и write. Установку частоты оцифровки, с другой стороны, можно было бы гораздо удачнее реализовать с применением функции devctl.

Хорошо, но ведь не каждое взаимодействие клиент/сервер сводится к блочной передаче данных (тот же сервер CLID — тому пример).

Трансляция сообщений в вызовы devctl или _IO_MSG

Итак, возник вопрос — как выполнять операции управления? Самый простой способ состоит в применении POSIX-вызова devctl. Наш пример из библиотеки CLID примет вид:

/*

 * CLID_AddSingleNPANXX(npa, nxx)

*/

int CLID_AddSingleNPANXX(int npa, int nxx) {

 struct clid_addnpanxx_t msg;

 checkAttach; // Оставить или нет — дело вкуса

 msg.npa = npa;

 msg.nxx = nxx;

 return

(devctl(clid_pid, DCMD_CLID_ADD_NPANXX,

&msg, sizeof(msg), NULL));

}

Как видите, операция относительно безболезненная. (Для тех, кто не любит devctl за то, что приходится отправлять в обе стороны блоки данных одного и того же размера, см. ниже обсуждение сообщений _IO_MSG.). Опять же, если вы пишете программу, которая должна работать в обеих операционных системах, вам следует выделить функцию обмена сообщениями в отдельный библиотечный модуль и предоставить несколько вариантов реализации, в зависимости от применяемой операционной системы.

Реально мы убили двух зайцев:

1. отказались от глобальной переменной и стали собирать сообщения на основе стековой переменной — это делает нашу программу безопасной в многопоточной среде (thread- safe);

2. передали

структуру данных нужного размера вместо структуры данных максимального размера, как мы это делали в предыдущем примере с QNX4.

Заметьте, что нам пришлось определить константу DCMD_CLID_ADD_NPANXX — в принципе, мы могли бы для этих же целей применить константу CLID_MsgAddSingleNPANXX (сделав соответствующее изменение в заголовочном файле), но я просто хотел подчеркнуть тот факт, что эти две константы не являются одинаковыми.

Второй убитый заяц заключался в том, что мы передали «структуру данных нужного размера». На самом деле, мы тут немножко приврали. Обратите внимание на то, что функция devctl имеет только один параметр размера (четвертый, который мы установили в

sizeof(msg)
). Как на самом деле происходит пересылка данных? Второй параметр функции devctl содержит команду для устройства (поэтому и «DCMD»). Двумя старшими битами команды кодируется направление, которое может быть одним из четырех:

1. «00» — передачи данных нет;

2. «01» — передача от драйвера клиенту;

3. «10» — передача от клиента драйверу;

4. «11» — двунаправленная передача.

Если вы не передаете данные (то есть достаточно просто команды) или передаете их в одном направлении, то применение функции devctl — прекрасный выбор. Интересен тот вариант, когда вы передаете данные в обоих направлениях. Интересен он тем, что, поскольку у функции devctl только один параметр размера, обе пересылки данных (как драйверу, так и от драйвера) передадут весь буфер данных целиком! Это хорошо в том частном случае, когда размеры буферов «ввода» и «вывода» одинаковы, но представьте себе, что буфер принимаемых драйвером данных имеет размер в несколько байт, а буфер передаваемых данных гораздо больше. Поскольку у нас есть только один параметр размера, мы вынуждены будем каждый раз передавать драйверу полный буфер данных, хотя требовалось передать всего несколько байт!

Эта проблема может быть решена применением «своих собственных» сообщений на основе общего механизма управляющих последовательностей, поддерживаемого в сообщениях типа _IO_MSG.

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

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

typedef struct {

 int data_rate;

 int more_stuff;

} my_input_xyz_t;

typedef struct {

 int old_data_rate;

 int new_data_rate;

 int more_stuff;

} my_output_xyz_t;

typedef union {

 my_input_xyz_t i;

 my_output_xyz_t o;

} my_message_xyz_t;

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

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Бестужев. Служба Государевой Безопасности. Книга четвертая

Измайлов Сергей
4. Граф Бестужев
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга четвертая

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Лисья нора

Сакавич Нора
1. Всё ради игры
Фантастика:
боевая фантастика
8.80
рейтинг книги
Лисья нора

Калибр Личности 5

Голд Джон
5. Калибр Личности
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Калибр Личности 5

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Сердце Дракона. Том 10

Клеванский Кирилл Сергеевич
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Сердце Дракона. Том 10

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Как я строил магическую империю

Зубов Константин
1. Как я строил магическую империю
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Как я строил магическую империю

Повелитель механического легиона. Том VII

Лисицин Евгений
7. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VII

Я князь. Книга XVIII

Дрейк Сириус
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я князь. Книга XVIII

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

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 10. Часть 2

Вечный. Книга I

Рокотов Алексей
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга I

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3