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
Количество просмотров:
351
Читать онлайн
Роб Кёртен - Введение в 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 - читать книгу онлайн бесплатно, автор Роб Кёртен

Философия переноса программ

Давайте теперь взглянем на все «сверху». Здесь мы рассмотрим:

• обмен сообщениями и систему «клиент/сервер»;

• обработчики прерываний (ISR).

Анализ обмена сообщениями

В QNX4 клиент мог найти сервер двумя способами:

• используя глобальное пространство имен;

• выполнение open() в отношении администратора ввода/вывода.

«Клиент/сервер» с использованием глобального пространства имен

Если взаимоотношения «клиент/сервер, которые вы переносите, базируются на глобальном пространстве имен, тогда клиент использует:

qnx_name_locate()

а сервер регистрирует свое имя при помощи:

qnx_name_attach()

В этом случае у вас есть два выбора. Вы можете либо попробовать сохранить вариант с глобальными именами, либо модифицировать клиента и сервер так, чтобы они работали подобно стандартному администратору ресурсов.

Я рекомендую вам последний вариант, поскольку именно этот вариант характерен для QNX/Neutrino — сводить все к администраторам ресурсов, а не пытаться навесить кусок администратора ресурсов на службу глобальных имен.

Модификация будет достаточно проста. Скорее всего, клиентская сторона вызывает функцию, либо возвращающую идентификатор серверного процесса, либо создающую виртуальный канал («VC» — Virtual Circuit) от клиентского узла к удаленному узлу сервера. В обоих случаях как идентификатор процесса, так и идентификатор виртуального канала к удаленному процессу определяются при помощи qnx_name_locate(). «Магическим амулетом», связывающим клиента с сервером, здесь является специальная разновидность идентификатора процесса (мы считаем идентификатор виртуального канала идентификатором процесса, поскольку он берется из того же пула номеров и со всех точек зрения выглядит как идентификатор процесса).

Преодолеть основное различие можно было бы, возвращая вместо идентификатора процесса идентификатор соединения. Поскольку клиент в QNX4, вероятно, не анализирует идентификаторы процессов (да и зачем? Так, просто число), вы могли бы «обмануть» его, применив к «глобальному имени» функцию open(). В этом случае, однако, глобальное имя должно было бы быть точкой монтирования, зарегистрированной администратором ресурса в качестве своего «идентификатора». Вот, например, типовой пример клиента QNX4, взятый из моей серверной библиотеки CLID:

/*

 * CLID_Attach(ServerName)

 *

 * Эта подпрограмма отвечает за установление соединения

 * с сервером CLID.

 *

 * Возвращает PID сервера CLID или идентификатор

 * виртуального канала к нему.

*/


// Сюда запишется имя - для других библиотечных вызовов

static char CLID_serverName(MAX_CLID_SERVER_NAME + 1);


// Сюда запишется идентификатор сервера

CLID static int clid_pid = -1;


int CLID_Attach(char *serverName) {

 if (ServerName == NULL) {

  sprintf(CLID_serverName, "/PARSE/CLID");

 } else {

  strcpy(CLID_serverName, serverName);

 }

 clid_pid = qnx_name_locate(0, CLID_serverName,

  sizeof(CLID_ServerIPC), NULL);

 if (clid_pid != -1) {

  CLID_IPC(CLID_MsgAttach); // Послать сообщение ATTACH

  return (clid_pid);

 }

 return (-1);

}

Вы могли бы изменить это на следующее:

/*

 * CLID_Attach(serverName), версия для QNX/Neutrino

*/

int CLID_Attach(char *serverName) {

 if (ServerName == NULL) {

  sprintf(CLID_serverName, "/PARSE/CLID");

 } else {

  strcpy(CLID_serverName, serverName);

 }

 return (clid_pid = open(CLID_serverName, O_RDWR));

}

И клиент ничего бы не заметил.

Два замечания по реализации. В качестве зарегистрированного префикса администратора ресурса я просто оставил имя по умолчанию («/PARSE/CLID»). Вероятно, лучше было бы взять имя «/dev/clid», но насколько вы хотите следовать POSIX — это ваше личное дело. В любом случае, это незначительное изменение, и оно мало связано с тем, что здесь обсуждается.

Второе замечание касается того, что я по-прежнему назвал дескриптор файла clid_pid, хотя реально ему бы теперь следовало называться clid_fd. Это, опять же, вопрос стиля и касается только того, сколько различий вы хотите иметь между версиями кода для QNX4 и QNX/Neutrino.

В любом случае, того чтобы данная программа была переносима в обе ОС, вам придется выделить код соединения с сервером в отдельную функцию — как я это сделал выше с функцией CLID_Attach().

В какой-то момент клиент должен будет выполнить собственно операцию отправки сообщения. Здесь все становится несколько сложнее. Поскольку отношения клиент/сервер не основаны на отношениях с администраторами ввода/вывода, клиент обычно создает «нестандартные» сообщения. Снова пример из CLID-библиотеки («незащищенный» клиентский вызов здесь — CLID_AddSingleNPANXX(), я также включил функции checkAttach() и CLID_IPC() для того, чтобы продемонстрировать фактическую передачу сообщений и логику проверок):

/*

 * CLID_AddSingleNPANXX(npa, nxx)

*/


int CLID_AddSingleNPANXX(int npa, int nxx) {

 checkAttach();

 CLID_IPCData.npa = npa;

 CLID_IPCData.nxx = nxx;

 CLID_IPC(CLID_MsgAddSingleNPANXX);

 return (CLID_IPCData.returnValue);

}


/*

 * CLID_IPC(номер_сообщения_IPC)

 *

 * Эта подпрограмма вызывает сервер с глобальным буфером

 * CLID_IPCData и заносит в него номер сообщения,

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

 *

 * Если сервера нет, эта подпрограмма установит

 * поле returnValue в CLID_NoServer. Остальные

 * поля остаются как есть.

*/

void CLID_IPC(int IPCMessage) {

 if (clid_pid == -1) {

  CLID_IPCData.returnValue = CLID_NoServer;

  return;

 }

 CLID_IPCData.serverFunction = IPCMessage;

 CLID_IPCData.type = 0x8001;

 CLID_IPCData.subtype = 0;

 if (Send(clid_pid, &CLID_IPCData, &CLID_IPCData,

  sizeof(CLID_IPCData), sizeof(CLID_IPCData))) {

  CLID_IPCData.returnValue = CLID_IPCError;

  return;

 }

}


void checkAttach() {

 if (clid_pid == -1) {

  CLID_Attach(NULL);

 }

}

Как вы видите, функция checkAttach() применяется для проверки существования соединения с сервером CLID. Если бы соединения не было, это было бы подобно запросу read() по несуществующему дескриптору файла. В моем варианте программы функция checkAttach() создает соединение автоматически. Это как если бы функция read() определила, что дескриптор файла некорректен, и сама создала бы корректный. Еще один вопрос стиля.

Обмен специализированными сообщениями происходит в функции 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().


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

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


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

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

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