- •Министерство образования и науки Украины
- •1. Определение системам реального времени
- •1.1. Основные понятия
- •1.2. Срв
- •1.3. Классификация срв
- •1.4. Структура срв
- •Основные требования к срв и их особенности
- •1.4.1. Ос
- •1.4.2. Основные архитектурные решения ос
- •1.4.3. Основные концепции ос
- •Прерывания
- •Системные вызовы
- •Файловая система
- •Процессы
- •Нити (потоки)
- •Понятие ресурса
- •1.5. Аппаратные среды срв
- •1.5.1. Мультипрограммная среда
- •Состояния процесса (см. Рисунок 4.).
- •1.5.2. Симметричная мультипроцессорная среда (рис. 5)
- •1.5.3. Распределенная среда (рис. 6)
- •1.6. Конфигурации клиент-серверных систем (рис.7.)
- •1.7. Средства ввода-вывода срв
- •2.1. Версии qnx
- •2.2. Posix-совместимость
- •2.3. Архитектура микроядра qnx
- •2.3.1. Микроядро
- •2.3.2. Системные процессы
- •2.3.3. Системные и пользовательские процессы
- •2.3.4. Драйверы устройств
- •2.3.5. Межпроцессное взаимодействие
- •2.3.6. Сеть qnx
- •2.4. Файлы и файловая система
- •2.4.1. Типы файлов
- •2.4.2. Жесткие ссылки
- •2.4.3. Символические ссылки
- •2.4.4. Named Special Device — именованные специальные устройства
- •2.4.5. Именованные программные каналы (fifo) (Именованный канал)
- •2.5. Структура файловой системы qnx
- •2.6. Концепция прав доступа
- •3. Начало работы
- •3.1. Интерфейс командной строки
- •3.2. Консоль командной строки
- •3.3. Соглашения по работе с командной строкой
- •3.4. Знакомство с shell
- •3.5. Обращение к домашнему каталогу
- •3.6. Базовые команды
- •3.6.1. Изменение текущего каталога
- •3.6.2. Просмотр содержимого каталогов
- •Жесткая ссылка обозначает ся так же, как файл, на который она ссылается, счетчик ссылок при этом будет иметь значение больше 1.
- •3.6.3. Создание новых каталогов
- •3.6.4. Копирование файлов
- •3.6.5. Перемещение файлов
- •3.6.6. Удаление файлов
- •3.6.7. Удаление каталогов
- •3.6.8. Просмотр содержимого файлов
- •3.6.9. Конкатенация (слияние) и просмотр файлов
- •3.6.10. Получение оперативной помощи
- •4. Объектно-ориентированное программирование
- •4.1. Системы программирования
- •4.2. Создание приложения
- •4.3. Средства отладки программ
- •5. Архитектура ос qnx
- •5.1. Типы процессов
- •5.2. Механизмы микроядра
- •5.3. Диспетчеризация потоков
- •5.4. Администратор процессов
- •5.5. Управление памятью
- •5.6. Управление пространством путевых имен
- •5.7. Пространство путевых имен
- •5.7.1. Файловая система qnx
- •5.7.2. Виртуальные устройства
- •Устройство /dev/null
- •Устройство /dev/zero
- •Устройство /dev/full
- •Устройства генерирования случайных чисел
- •5.8. Программы, процессы, нити
- •5.9. Свойства процессно-нитиевой структуры прв
- •5.10. Программный интерфейс qnx
- •5.10.1. Системные вызовы и функции стандартных библиотек
- •5.10.2. Обработка ошибок
- •5.11. Формальные параметры функции main
- •5.12. Разграничение доступа к файлам
- •5.13. Функции базового ввода/вывода
- •5.13.1. Открытие файла
- •5.13.2. Дублирование дескриптора файла
- •5.13.3. Доступ к файлу
- •6. Функции управления файловой системой
- •6.1. Смена корневого каталога
- •6.2. Смена текущего каталога
- •6.3. Создание каталога
- •6.4. Удаление каталога
- •6.5. Создание жесткой связи
- •6.6. Создание символической связи
- •6.7. Чтение символической связи
- •6.8. Переименование файла
- •6.9. Удаление файла
- •7. Микроядро
- •7.1. Запуск процессов
- •7.2. Запуск процесса из shell
- •7.3. Программный запуск процессов
- •7.3.1. Функция system()
- •7.3.2. Функции семейства exec*()
- •7.3.3. Функции семейства spawn*()
- •7.3.4. Функция fork()
- •7.3.5. Функция vfork()
- •7.4. Организация взаимодействия между процессами
- •7.5. Создание и удаление каналов Создание канала.
- •Удаление канала
- •7.6. Установление и удаление соединений с каналом Установление соединения
- •Int ConnectAttach(uint32_t nd, pid_t pid, int chid, unsigned index, int flags);
- •Разрыв соединения
- •Int ConnectDetach(int coid);
- •7.7. Передача сообщений
- •7.7.1. Посылка сообщения
- •IntMsgSend(int coid, constvoid* smsg, int sbytes, void* rmsg, int rbytes);
- •7.7.2. Прием сообщения
- •Int MsgReceive(int chid, void *msg, int bytes, struct _msg_info *info);
- •7.7.3. Посылка ответа
- •Int MsgReply(int rcvid,int status,const void* msg, int size);
- •7.7.4. Сценарии ответов
- •7.7.5. Управление сообщениями
- •7.7.6. Управление приемом сообщений
- •7.7.7. Управление передачей ответа
- •Int MsgSendv(int coid, const iov_t* siov, //Массив iov сообщения int sparts, //Количество iov сообщения const iov_t* riov, //Массив iov ответа int rbytes); //Количество iov ответа
- •Int MsgReceivev(int chid, const iov_t* riov, //Массив iov буфера int sparts, //Количество iov буфера struct_msg_info* riov);
7.7.2. Прием сообщения
Процесс-сервер должен принять сообщение и послать ответ клиенту. Для приема сообщения сервером используется функция:
#include <sys/neutrino.h>
Int MsgReceive(int chid, void *msg, int bytes, struct _msg_info *info);
Эта функция ожидает сообщение в канале chid. Принятое сообщение размещается в буфере, адрес которого указан в msg. Размер буфера msg задается в bytes в байтах. Число принятых байтов не может превысить размера буфера (контролируется ядром).
Если сообщение уже было в канале, когда нить сервера вызывает MsgReceive(), то оно немедленно копируется ядром в адресное пространство сервера. Если сообщения в канале нет, то принимающая сообщение нить сервера переходит в RECEIVE-блокированное состояние, ожидая пока сообщение от клиента не поступит в канал. При получении сообщения нить переходит в состояние готовности к выполнению (READY).
Если значение info отлично от NULL, то в нем сохраняется дополнительная информация относительно сообщения и нити клиента, которая послала его. Если значение info равно NULL, то эта информация, при необходимости, может быть получена, с помощью функции MsgInfo() (описание этой функции содержит описание структуры _msg_info).
Если при выполнении функции возникает ошибка, то возвращается ‑1 и errno присваивается код ошибки. В случае успеха возвращается идентификатор rcvid, специфицирующий нить клиента, пославшую сообщение.
7.7.3. Посылка ответа
Получив сообщение от клиента сервер должен послать ему ответное сообщение с помощью функции:
#include <sys/neutrino.h>
Int MsgReply(int rcvid,int status,const void* msg, int size);
rcvid - ссылка на нить клиента (пославшую сообщение), возвращаемая функцией MsgReceive().
status - статус завершения, который возвращается нити клиента, пославшей сообщение, при успешном завершении функции MsgSend().
msg - указатель буфера, содержащего ответное сообщение.
size - размер сообщения в байтах.
Функция посылает ответ с сообщением нити клиента, идентифицированной rcvid. При этом нить должна находится в REPLY-блокированном состоянии. Ответ может послать любая нить сервера. Важно только, чтобы на каждое принятое сервером сообщение следовал бы ответ и только один. Выполнение функции MsgSend(), вызванной нитью клиента, которой соответствует rcvid, завершается разблокированием нити и возвратом значения статуса, заданного сервером при выполнении функции MsgReply().
Ядро контролирует, чтобы число байтов ответного сообщения, принимаемых клиентом, не превышало объема буфера клиента, предназначенного для приема ответа.
Функция MsgReply() не блокирует нить сервера, передача ответа выполняется немедленно. Нет никаких особых требований к порядку ответа, но, в конечном счете, серверу необходимо ответить на каждое принятое сообщение, чтобы разблокировать нить клиента, пославшую сообщение.
Заметим, что в функциях MsgSend() и MsgReceive() указывается количество посылаемых и принимаемых байт. Если они не совпадают, то выбирается минимальное из указанных значений с целью согласования размеров буферов передачи и приема. Аналогичная ситуация и с функцией MsgReply(). То есть, при необходимости сообщение будет "урезано" и лишние байты "отброшены".
Если возникает ошибка, то возвращается ‑1 и errno присваивается код ошибки.
Пример.
#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 = %X\n",rcvid);
printf("Сообщение такое: %s\n", message);
/*Подготовить отправить ответ - используем тот же буфер, что и для приема сообщения*/
strcpy(message,"Этоответ");
MsgReply(rcvid,EOK,message,sizeof(message));
}
}