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

Кёртен Роб

Шрифт:

Пример функции io_devctl, имеющей дело с данными

В предыдущем примере io_devctl мы подняли вопрос о том, как устанавливать произвольные значения частоты дискретизации, Очевидно, создание большого количества констант DCMD_AUDIO_SET_SAMPLE_RATE_* было бы не самым оптимальным решением — у нас бы просто не хватило разрядности поля dcmd.

С клиентской стороны мы будем использовать указатель на частоту дискретизации, dev_data_ptr, которую мы просто передадим как целое, поэтому поле nbytes будет содержать число байт в целом числе (для 32-разрядных машин это 4). Будем предполагать, что для этих целей определена константа DCMD_AUDIO_SET_SAMPLE_RATE.

Также неплохо было бы уметь считывать текущее значение частоты дискретизации. Для этого мы также будем использовать переменные dev_data_ptr и nbytes, как описано выше, но в обратном направлении — администратор ресурсов запишет nbytes данных в ячейку памяти, на которую указывает dev_data_ptr, вместо чтения данных из этой ячейки. Предположим, что для этого определена константа DCMD_AUDIO_GET_SAMPLE_RATE.

Давайте посмотрим, что в таком случае происходит в функции io_devctl администратора ресурсов (того, что обсуждалось в предыдущем примере, мы здесь касаться не будем):

/*

 * io_devctl2.с

*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <devctl.h>

#include <sys/neutrino.h>

#include <sys/iofunc.h>

#define DCMD_AUDIO_SET_SAMPLE_RATE 1

#define DCMD_AUDIO_GET_SAMPLE_RATE 2

int io_devctl(resmgr_context_t *ctp, io_devctl_t *msg,

 iofunc_ocb_t *ocb) {

 int sts;

 void *data;

 int nbytes;

 if ((sts =

iofunc_devctl_default(ctp, msg, ocb)) !=

_RESMGR_DEFAULT) {

return (sts);

 }

 // 1) Установить указатель на область данных сообщения

 data = _DEVCTL_DATA(msg);

 // 2) Установить число возвращаемых байт в 0

 nbytes = 0;

 // Проверить все команды; покажем только те, которые нам

 // здесь интересны

 switch (msg->i.dcmd) {

...

 // 3) Обработать команду SET

 case DCMD_AUDIO_SET_SAMPLE_RATE:

audio_set_samplerate(*(int*)data);

break;

 // 4) Обработать команду GET

 case DCMD_AUDIO_GET_SAMPLE_RATE:

*(int*)data = audio_get_samplerate;

nbytes = sizeof(int);

break;

...

 }

 // 5) Возвратить данные (если есть) клиенту

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

 msg->о.nbytes = nbytes;

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

 return (_RESMGR_NPARTS(1));

}

Этап 1

В «шапке» мы декларировали указатель типа

void*
по имени data («данные»), которые мы будем использовать в качестве универсального указателя на область данных. Если вы обратитесь к приведенному выше описанию io_devctl, то вы увидите, что структура данных состоит из объединения заголовков входной и выходной структур, за которым неявно следует область данных. На этапе 1 указатель на эту область данных возвращается макросом _DEVCTL_DATA.

Этап 2

Здесь мы должны указать, сколько байт мы собираемся возвратить клиенту. Я для удобства обнулил переменную nbytes перед выполнением каких-либо действий — теперь мне не придется принудительно обнулять ее в каждой ветви

switch
/
case
.

Этап 3

Пришло время для команды «set» («установить»). Мы вызываем фиктивную функцию audio_set_samplerate и передаем ей значение частоты дискретизации, полученное разыменованием указателя data (который мы коварно выставили указателем на целое число... нет, никакого коварства, обычный для Си прием приведения типов). Это ключевой механизм, потому что это и есть наш способ «интерпретации» области данных (клиентского указателя dev_data_ptr) в соответствии с командой. В более сложном случае вы, наверное, выполнили бы приведение его типа к какой-нибудь структуре побольше вместо простого целого числа. Очевидно, что описания этой структуры на стороне как клиента, так и администратора ресурсов, должны быть идентичными, поэтому лучшим местом для описания такой структуры является заголовочный файл, в котором хранятся ваши командные константы DCMD_*

  • Читать дальше
  • 1
  • ...
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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