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

int coid;

coid = ConnectAttach(0, 77, 1, 0, 0);

Можно видеть, что присвоением идентификатору узла (nd) нулевого значения мы сообщаем ядру о том, что мы желаем установить соединение на локальном узле.

Как я узнал, что соединиться надо с процессом 77 и по каналу 1? К этому мы скоро вернемся (см. ниже «Поиск сервера по ND/PID/CHID»).

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

Я смогу применять этот идентификатор для отправки запросов серверу сколько угодно раз. Выполнив все, для чего предназначалось соединение, я смогу уничтожить его с помощью функции:

ConnectDetach(coid);

Итак, давайте рассмотрим, как я воспользуюсь этим на практике.

Передача сообщений (sending)

Передача сообщения со стороны клиента осуществляется применением какой-либо функции из семейства MsgSend*().

Мы рассмотрим это на примере простейшей из них — MsgSend():

#include <sys/neutrino.h>


int MsgSend(int coid, const void *smsg, int sbytes,

 void *rmsg, int rbytes);

Аргументами функции MsgSend() являются :

• идентификатор соединения с целевым сервером (coid);

• указатель на передаваемое сообщение (smsg);

• размер передаваемого сообщения (sbytes);

• указатель на буфер для ответного сообщения (rmsg);

• размер ответного сообщения (rbytes);

Что может быть проще!

Передадим сообщение процессу с идентификатором 77 по каналу 1:

#include <sys/neutrino.h>


char *smsg = "Это буфер вывода";

char rmsg[200];

int coid;


// Установить соединение

coid = ConnectAttach(0, 77, 1, 0, 0);

if (coid == -1) {

 fprintf(stderr, "Ошибка ConnectAttach к 0/77/1!n");

 perror(NULL);

 exit(EXIT_FAILURE);

}


// Послать сообщение

if (MsgSend(

 coid, smsg, strlen(smsg) + 1, rmsg, sizeof(rmsg)) == -1) {

 fprintf (stderr, "Ошибка MsgSendn");

 perror(NULL);

 exit (EXIT_FAILURE);

}

if (strlen(rmsg) > 0) {

 printf("Процесс с ID 77 возвратил "%s"n", rmsg);

}

Предположим, что процесс с идентификатором 77 был действительно активным сервером, ожидающим сообщение именно такого формата по каналу с идентификатором 1. После приема сообщения сервер обрабатывает его и в некоторый момент времени выдает ответ с результатами обработки. В этот момент функция MsgSend() должна возвратить ноль (0), указывая этим, что все прошло успешно. Если бы сервер послал нам в ответ какие-то данные, мы смогли бы вывести их на экран с помощью последней строки в программе (с тем предположением, что обратно мы получаем корректную ASCIIZ-строку).

Сервер

Теперь, когда мы рассмотрели клиента, перейдем к серверу. Клиент использовал функцию ConnectAttach() для создания соединения с сервером, а затем использовал функцию MsgSend() для передачи сообщений.

Создание канала

Под этим подразумевается, что сервер должен создать канал — то, к чему присоединялся клиент, когда вызывал функцию ConnectAttach(). Обычно сервер, однажды создав канал, приберегает его «впрок».

Канал создается с помощью функции ChannelCreate() и уничтожается с помощью функции ChannelDestroy():

#include <sys/neutrino.h>


int ChannelCreate(unsigned flags);

int ChannelDestroy(int chid);

Мы еще вернемся к обсуждению аргумента flags (в разделе «Флаги каналов», см. ниже), а покамест будем использовать для него значение 0 (ноль). Таким образом, для создания канала сервер должен сделать так:

int chid;

chid = ChannelCreate(0);

Теперь у нас есть канал. В этом пункте клиенты могут подсоединиться (с помощью функции ConnectAttach()) к этому каналу и начать передачу сообщений:

Связь между каналом сервера и клиентским соединением.

Обработка сообщений

В терминах обмена сообщениями, сервер отрабатывает схему обмена в два этапа — этап «приема» (receive) и этап «ответа» (reply).

Взаимосвязь функций клиента и сервера при обмене сообщениями.

Обсудим сначала два простейших варианта соответствующих функций, MsgReceive() и MsgReply(), а далее посмотрим, какие есть варианты.

#include <sys/neutrino.h>


int MsgReceive(int chid, void *rmsg, int rbytes,

 struct _msg_info *info);

int MsgReply(int rcvid, int status, const void *msg,

 int nbytes);

Посмотрим, как соотносятся параметры:

Поток данных при обмене сообщениями.

Как видно из рисунка, имеются четыре элемента, которые мы должны обсудить:

1. Клиент вызывает функцию MsgSend() и указывает ей на буфер передачи (указателем smsg и длиной sbytes). Данные передаются в буфер функции MsgReceive() на стороне сервера, по адресу rmsg и длиной rbytes. Клиент блокируется.

2. Функция MsgReceive() сервера разблокируется и возвращает идентификатор отправителя rcvid, который будет впоследствии использован для ответа. Теперь сервер может использовать полученные от клиента данные.

3. Сервер завершил обработку сообщения и теперь использует идентификатор отправителя rcvid, полученный от функции MsgReceive(), передавая его функции MsgReply(). Заметьте, что местоположение данных для передачи функции MsgReply() задается как указатель на буфер (smsg) определенного размера (sbytes). Ядро передает данные клиенту.

4. Наконец, ядро передает параметр sts, который используется функцией MsgSend() клиента как возвращаемое значение. После этого клиент разблокируется.

Вы, возможно, заметили, что для каждой буферной передачи указываются два размера (в случае запроса от клиента клиента это sbytes на стороне клиента и rbytes на стороне сервера; в случае ответа сервера это sbytes на стороне сервера и rbytes на стороне клиента). Это сделано для того, чтобы разработчики каждого компонента смогли определить размеры своих буферов — из соображений дополнительной безопасности.

В нашем примере размер буфера функции MsgSend() совпадал с длиной строки сообщения. Давайте теперь рассмотрим, что происходит в сервере и как размер используется там.

Структура сервера

Вот общая структура сервера:

#include <sys/neutrino.h>


...


void server(void) {

 int rcvid; // Указывает, кому надо отвечать

 int chid; // Идентификатор канала

 char message[512]; // Достаточно велик

 // Создать канал

 chid = ChannelCreate(0);

 // Выполняться вечно — для сервера это обычное дело

 while (1) {

  // Получить и вывести сообщение

  rcvid = MsgReceive(chid, message, sizeof(message), NULL);

  printf("Получил сообщение, rcvid %Xn", rcvid);

  printf("Сообщение такое: "%s".n", message);

  // Подготовить ответ — используем тот же буфер

  strcpy(message, "Это ответ");

  MsgReply(rcvid, EOK, message, sizeof(message));

 }

}

Как видно из программы, функция MsgReceive() сообщает ядру о том, что она может обрабатывать сообщения размером вплоть до sizeof(message) (или 512 байт). Наш клиент (представленный выше) передал только 28 байт (длина строки). На приведенном ниже рисунке это и показано:

Передача меньшего объема данных, чем предполагается.

Ядро реально передает минимум из двух указанных размеров. В нашем случае ядро передало бы 28 байт, сервер бы разблокировался и отобразил сообщение клиента. Оставшиеся 484 байта (из буфера длиной 512 байт) остались бы нетронутыми.

Аналогичная ситуация с функцией MsgReply(). Функция MsgReply() информирует, что собирается передать 512 байт, но функция MsgSend() определила, что может принять максимум 200 байт. Ядро опять передает минимум. В этом случае 200 байтов, которые клиент может принять, ограничивают размер передачи. (Один интересный аспект здесь состоит в том, что когда сервер передаст данные, то если клиент не примет их целиком, как в нашем примере, их уже нельзя будет вернуть — они будут потеряны.).

Имейте в виду, что такое «урезание» является стандартным и ожидаемым поведением.

Когда мы будем обсуждать обмен сообщениями по сети, вы увидите, что в количестве передаваемых данных есть кое-какое «ага». Мы проанализируем это далее в разделе «Особенности обмена сообщениями в сети».


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

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


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

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

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