- •Министерство образования и науки Украины
- •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);
5.10.2. Обработка ошибок
Разница между системными вызовами и библиотечными функциями проявляется еще в способе передачи процессу информации об ошибке, произошедшей во время выполнения системного вызова или функции библиотеки.
Обычно в случае возникновения ошибки системные вызовы возвращают целое значение -1 и устанавливают значение глобальной системной переменной errno, указывающее причину возникновения ошибки. Системный заголовочный файл <errno.h> содержит коды ошибок, значения которых может принимать переменная errno, с краткими комментариями.
Библиотечные функции, как правило, не устанавливают значение переменной errno, а код возврата различен для разных функций. Для уточнения возвращаемого значения библиотечной функции необходимо обратиться к описанию этих функций в справочной системе QNX.
Рассмотрим более подробно обработку ошибок, возникающих при выполнении системных вызовов с использованием переменной errno. Заметим, что значение errno не обнуляется следующим нормально завершившимся системным вызовом. Следовательно, значение errno имеет смысл только после вызова, который завершился с ошибкой.
Стандарт ANSI C определяет две функции, помогающие сообщить причину ошибочной ситуации:
#include <string.h>
char *strerror(int errnum);
и
#include <errno.h>
#include <stdio.h>
void perror(const char *s).
Функция strerror() принимает в качестве аргумента errnum номер ошибки и возвращает указатель на строку, содержащую сообщение о причине ошибочной ситуации. Функция perror() выводит в стандартный поток сообщений об ошибках (обычно на экран) содержимое строкиs и вслед за ним – системную информацию об ошибочной ситуации, основываясь на значении переменной errno.
5.11. Формальные параметры функции main
Запуск программного файла на выполнение равносилен вызову функции main. Функция main также может иметь формальные параметры, но, в отличие от остальных функций, её параметры не могут задаваться произвольно. Количество, порядок следования и семантика формальных параметров функции main строго определены. Кроме того, аргументы передаются формальным параметрам функции main при запуске программы из командной строки и из переменных окружения (системные переменные ОС). Функция main с формальными параметрами имеет вид:
<спецификация_типа> main(int argc, char *argv[],char *env[])
{…}
Семантика формальных параметров функции main следующая:
argc – количество аргументов командной строки;
argv – массив указателей на аргументы командной строки;
env – массив указателей на переменные окружения.
Для передачи аргументов командной строки функции main они размещаются в командной строке вслед за именем исполняемого файла. Аргументы передаются в виде символьных строк (заключать в двойные кавычки не обязательно). Аргументы отделяются друг от друга пробелами или символами горизонтальной табуляции. Если требуется передать программе строку аргумента, содержащую внутри себя пробелы или символы горизонтальной табуляции, следует заключить её в двойные кавычки.
Массив argv имеет следующее содержание:
argv[0] – указатель строки с полным именем исполняемого файла в файловой системе;
argv[1] – указатель строки первого аргумента;
argv[2] – указатель строки второго аргумента;
…
argv[argc-1] – указатель строки последнего аргумента;
argv[argc] – нулевой указатель – NULL.
Значение формального параметра argc не может быть меньше 1. Если значение argc равно 1, это означает, что аргументы в командной строке отсутствуют.
Массив env, начиная с env[0], содержит указатели на строки переменных окружения вида:
<идентификатор>=<значение>
Идентификатор является именем переменной окружения, затем следует знак равенства и оставшаяся часть строки интерпретируется как значение переменной окружения. Последний элемент массива env содержит нулевой указатель – NULL.
Задавать все параметры функции main не обязательно. Они используются по необходимости. Допустимы следующие объявления формальных параметров:
main()
main(int argc)
main(int argc, char *argv[])
main(int argc, char *argv[],char *env[])
Ниже приводится пример программы ARGS.C, которая выводит на экран значения аргументов, заданных в командной строке при запуске программного файла, а также текущие значения переменных среды.
Пример:
/* Программа ARGS.C */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[], char *env[]){
int i;
printf("Значение argc = %d \n\n", argc);
printf("Функции main передано %d аргументов в командной \
строке: \n\n",argc);
for (i = 0; i < argc; i++)
printf("argv[%d]: %s\n", i, argv[i]);
printf("\nПереданы следующие значения переменных среды:\n\n");
for (i = 0; env[i] != NULL; i++)
printf(" env[%d]: %s\n", i, env[i]);
return 0;
}
Предположим, что полученный в результате компиляции программныймодуль имеет полное имя /root/home/args, находится в текущем каталоге и запущен на выполнение командой:
$ args first_arg "арг с пробелами" 3 4 "предпоследний арг" stop!
Заметим, что можно передавать аргументы, содержащие пробелы, заключив эти аргументы в двойные кавычки, как показано выше в примере командной строки: "арг с пробелами" и "предпоследний арг".
Результат выполнения программыargs (предполагая, что заданы переменные среды, имеющие представленные ниже значения) будет выглядеть на экране в виде:
Значение argc равно 7
Функции main передано 7 аргументов в командной строке:
argv[0]: /root/home/args
argv[1]: first_arg
argv[2]: aрг с пробелами
argv[3]: 3
argv[4]: 4
argv[5]: предпоследний арг
argv[6]: stop!
Переданы следующие значения переменных среды:
env[0]: PROMPT=$p $g
env[1]: PATH=/SPRINT; /GCC