MyBooks.club
Все категории

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

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform. Жанр: Программное обеспечение издательство -,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
Автор
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
16 сентябрь 2019
Количество просмотров:
350
Читать онлайн
Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

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

Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - описание и краткое содержание, автор Роб Кёртен, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
Книга "Введение в QNX/Neutrino 2» откроет перед вами в мельчайших подробностях все секреты ОСРВ нового поколения от компании QNX Software Systems Ltd (QSSL) — QNX/Neutrino 2. Книга написана в непринужденной манере, легким для чтения и понимания стилем, и поможет любому, от начинающих программистов до опытных системотехников, получить необходимые начальные знания для проектирования надежных систем реального времени, от встраиваемых управляющих приложений до распределенных сетевых вычислительных системВ книге подробно описаны основные составляющие ОС QNX/Neutrino и их взаимосвязи. В частности, уделено особое внимание следующим темам:• обмен сообщениями: принципы функционирования и основы применения;• процессы и потоки: базовые концепции, предостережения и рекомендации;• таймеры: организация периодических событий в программах;• администраторы ресурсов: все, что относится к программированию драйверов устройств;• прерывания: рекомендации по эффективной обработке.В книге представлено множество проверенных примеров кода, подробных разъяснений и рисунков, которые помогут вам детально вникнуть в и излагаемый материал. Примеры кода и обновления к ним также можно найти на веб-сайте автора данной книги, www.parse.com.

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

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

   progname);

  perror(NULL);

  exit(EXIT_FAILURE);

 }

 // Настроить импульс и таймер

 setupPulseAndTimer();

 // Прием сообщений

 for(;;) {

  rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL));

  // Определить, от кого сообщение

  if (rcvid == 0) {

   // Здесь неплохо бы еще проверить поле «code»...

   gotAPulse();

  } else {

   gotAMessage(rcvid, &msg.msg);

  }

 }

 // Сюда мы никогда не доберемся

 return (EXIT_SUCCESS);

}

setupPulseAndTimer()

В функции setupPulseAndTimer() вы видите код, в котором определяется тип таймера и схема уведомления. Когда мы рассуждали о таймерных функциях выше, я говорил, что таймер может выдать сигнал или импульс, либо создать поток. Решение об этом принимается именно здесь, в функции setupPulseAndTimer(). Обратите внимание, что здесь мы использовали макроопределение SIGEV_PULSE_INIT(). Используя это макроопределение, мы реально присвоили элементу sigev_notify значение SIGEV_PULSE. (Если бы мы использовали одно из макроопределений семейства SIGEV_SIGNAL*_INIT(), мы получили бы уведомление при помощи соответствующего сигнала). Отметьте, что при настройке импульса мы с помощью вызова ConnectAttach() устанавливаем соединение с самим собой и даем ему уникальный код (здесь — константа CODE_TIMER; мы ее определили сами)

Последний параметр в инициализации структуры события — это приоритет импульса; здесь мы выбрали SIGEV_PULSE_PRIO_INHERIT (константа, равная -1). Это предписывает ядру не изменять приоритет принимающего импульс потока.

В конце описания функции мы вызываем timer_create() для создания таймера в ядре, после чего настраиваем его на срабатывание через одну секунду (поле it_value) и на периодическую перезагрузку односекундными интервалами (поле it_interval). Отметим, что таймер включается только по вызову timer_settime(), а не при его создании.

Схема уведомления по типу SIGEV_PULSE — расширение, свойственное только QNX/Neutrino. Концепция импульсов в POSIX отсутствует.

/*

 * setupPulseAndTimer

 *

 * Эта подпрограмма отвечает за настройку импульса, чтобы

 * тот отправлял сообщение с кодом MT_TIMER.

 * Затем устанавливается

 * периодический таймер с периодом в одну секунду.

*/

void setupPulseAndTimer(void) {

 timer_t timerid; // Идентификатор таймера

 struct sigevent event; // Генерируемое событие

 struct itimerspec timer; // Структура данных

                          // таймера

 int coid; // Будем соединяться с

           // собой

 // Создать канал к себе

 coid = ConnectAttach(0, 0, chid, 0, 0);

 if (coid == -1) {

  fprintf(stderr, "%s: ошибка ConnectAttach!n", progname);

  perror(NULL);

  exit(EXIT_FAILURE);

 }

 // Установить, какое событие мы хотим сгенерировать

 // - импульс

 SIGEV_PULSE_INIT(&event, coid, SIGEV_PULSE_PRIO_INHERIT,

  CODE_TIMER, 0);

 // Создать таймер и привязать к событию

 if (timer_create(CLOCK_REALTIME, &event, &timerid) ==

  -1) {

  fprintf(stderr,

   "%s: не удалось создать таймер, errno %dn",

   progname, errno);

  perror(NULL);

  exit(EXIT_FAILURE);

 }

 // Настроить таймер (задержка 1 с, перезагрузка через

 // 1 с) ...

 timer.it_value.tv_sec = 1;

 timer.it_value.tv_nsec = 0;

 timer.it_interval.tv_sec = 1;

 timer.it_interval.tv_nsec = 0;

 // ...и запустить его!

 timer_settime(timerid, 0, &timer, NULL);

}

gotAPulse()

В функции gotAPulse() вы можете видеть, как мы реализовали способность сервера обеспечивать тайм-ауты для клиентов. Мы последовательно просматриваем список клиентуры и, поскольку мы знаем, что импульс выдается один раз в секунду, просто уменьшаем число секунд, которое остается клиенту до тайм-аута. Если эта величина достигает нулевого значения, мы отвечаем этому клиенту сообщением «Извините, тайм-аут» (тип сообщения MT_TIMEDOUT). Обратите внимание, что мы подготавливаем это сообщение заранее (вне цикла for), а затем посылаем его по мере необходимости. Этот прием — по существу вопрос стиля: если вы предполагаете отвечать часто, возможно, имело бы смысл выполнить настройку однажды и загодя. Если же множество ответов не ожидается, то имело бы больший смысл делать настройки по мере необходимости.

Если значение оставшегося времени еще не достигло нуля, мы не делаем ничего — клиент по-прежнему заблокирован в ожидании сообщения.

/*

 * gotAPulse

 *

 * Эта подпрограмма отвечает за обработку тайм-аутов.

 * Она проверяет список клиентов на предмет тайм-аута

 * и отвечает соответствующим сообщением тем клиентам,

 * у которых тайм-аут произошел.

*/

void gotAPulse(void) {

 ClientMessageT msg;

 int i;

 if (debug) {

  time_t now;

  time(&now);

  printf("Получен импульс, время %s", ctime(&now));

 }

 // Подготовить ответное сообщение

 msg.messageType = MT_TIMEDOUT;

 // Просмотреть список клиентов

 for (i = 0; i < MAX_CLIENT; i++) {

  // Элемент используется?

  if (clients[i].in_use) {

   // Тайм-аут?

   if (--clients[i].timeout == 0) {

    // Ответить

    MsgReply(clients[i].rcvid, EOK, &msg, sizeof(msg));

    // Освободить элемент

    clients[i].in_use = 0;

   }

  }

 }

}

gotAMessage()

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

/*

 * gotAMessage

 *

 * Эта подпрограмма вызывается при каждом приеме

 * сообщения. Проверяем тип

 * сообщения (либо «жду данных», либо «вот данные»),

 * и действуем

 * соответственно. Для простоты предположим, что данные

 * никогда не ждут.

 * Более подробно об этом см. в тексте.

*/

void gotAMessage(int rcvid, ClientMessageT *msg) {

 int i;

 // Определить тип сообщения

 switch (msg->messageType) {

 // Клиент хочет ждать данных

 case MT_WAIT_DATA:

  // Посмотрим, есть ли пустое место в таблице клиентов

  for (i = 0; i < MAX_CLIENT; i++) {

   if (!clients[i].in_use) {

    // Нашли место - пометить как занятое,

    // сохранить rcvid

    // и установить тайм-аут

    clients[i].in_use = 1;

    clients[i].rcvid = rcvid;

    clients[i].timeout = 5;

    return;

   }

  }

  fprintf(stderr,

   "Таблица переполнена, сообщение от rcvid %d"

   " игнорировано, клиент заблокированn", rcvid);

  break;

  // Клиент с данными

 case MT_SEND_DATA:

  // Посмотрим, есть ли другой клиент, которому можно ответить

  // данными от этого клиента

  for (i = 0; i < MAX CLIENT; i++) {

   if (clients[i].in_use) {

    // Нашли - использовать полученное сообщение

    // в качестве ответного

    msg->messageType = MT_OK;

    // Ответить ОБОИМ КЛИЕНТАМ!

    MsgReply(clients[i].rcvid, EOK, msg, sizeof(*msg));

    MsgReply(rcvid, EOK, msg, sizeof(*msg));

    clients[i].in_use = 0;

    return;

   }

  }

  fprintf(stderr,

   "Таблица пуста, сообщение от rcvid %d игнорировано,"

   " клиент заблокированn", rcvid);

  break;

 }

}

Примечания

Несколько общих замечаний по тексту программы:

• Если сообщение с данными прибывает, когда либо никто не ждет, либо список ожидающих клиентов переполнен, в стандартный поток ошибок выводится сообщение, но клиенту при этом мы не отвечаем ничего. Это означает, что ряд клиентов может оказаться в REPLY-блокированном состоянии навсегда — идентификаторы отправителей мы потеряли, а значит, и ответ им дать не можем.


Роб Кёртен читать все книги автора по порядку

Роб Кёртен - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


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

Отзывы читателей о книге Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform, автор: Роб Кёртен. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.