Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

uOS

uOS - операционная система реального времени.
 Автор - Сергей Вакуленко
 Авторский сайт - www.vak.ru
 Архив исходников также можно взять тут (500 KB)
 Для компиляции нужно сделать следующее :
  1 Войдите в каталог /targets/i386-dbg
  	Запустите команду make 
 	Будет сгенерированы 2 обьектных файла :
 	рантайм-библиотека libuos.a и startup.o.
  2 Войдите в каталог /tests/i386
  	Запустите команду make
 	Будут сгенерированы несколько бинарных файлов с расширением .out
 	Фактически это загрузчики , которые запускаются из-под grub .
 Например , при запуске t_tcl.out открывается терминал .
 В нем можно набрать команду help , которая распечатает список команд .
 Запуская эти команды , можно получить информацию о железе и т.д.
 
  А вот тут лежит обрезанная версия.
 Она короче на 5 модулей , и все собирается с помощью одного Makefile.
 
  Библиотека libuos.a состоит из набора модулей :
 	runtime 
 	kernel
 	stream
 	random
 	regexp
 	mem
 	tcl
 	timer
 	buf 
 	net 
         crc 
 	snmp 
 	vesa 
 	i8042 
 	input 
 	pci 
  	
  Модуль runtime : работа с памятью - поиск и копирование , набор символьных функций ,
  Модуль kernel  : управление задачами , прерываниями , сигналами , наконец главная 
 задача - main() :
  	int	main (void)
 	{
 		/* Create the idle task.
 		* Align stack on long word boundary. */
 		task_idle = (task_t*) (((int) task_idle_data + sizeof (long) - 1) &
 			~(sizeof (long) - 1));
 		task_idle->stack[0] = STACK_MAGIC;
 		task_idle->name = CONST("idle");
 		task_current = task_idle;
 		task_enqueue (&task_active, task_idle);
 	
 		/* тут можно создавать пользовательские процессы */
 		uos_init ();
 		/* установка приоритета */
 		MACHDEP_TASK_SWITCH ();
 	
 	}
  
  Модуль mem  : выделение - освобождение памяти
  Модуль tcl  : интерпретатор языка
  
 

uOS представляет собой переносимую масштабируемую операционную систему реального времени с вытесняющей многозадачностью.

Система uOS построена по модульному принципу . Базовый модуль ядра занимает около 2 килобайт ПЗУ и 200 байт ОЗУ . Набор модулей может наращиваться . В перечень модулей входят драйверы устройств , диспетчер памяти , сетевые протоколы .

Ядро системы оперирует обьектами 2-х типов - "задача" и "ресурс". Задача представляет собой поток управления (thread) . Каждая задача имеет отдельный стек . В процессе выполнения задача может захватывать необходимые ресурсы . При попытке захватить ресурс , занятый другой задачей , задача блокируется до момента освобождения ресурса . Т.о каждая задача может находиться в одном из 2-х состояний - выполнения или блокировки .

Каждая задача имеет приоритет , при этом будет выполняться задача с наибольшим приоритетом. Приоритет создается при создании задачи и по ходу может меняться . Для отладки каждая задача имеет имя - текстовую строку .

Задачи могут обмениваться сообщениями . Если задача ожидает сообщения от ресурса , она блокируется .

При захвате ресурса задача може присвоить ему номер аппаратного прерывания , и ожидать сообщения . Для каждого аппаратного прерывания следует создать отдельную задачу, которая в цикле будет ожидать от прерывания сообщения .

При старте системы вызывается функция пользователя uos_init() , которая посредством task_create() создает необходимое количество задач . После завершения функции uos_init() запускается планировщик задач , открываются прерывания и самая приоритетная задача получает управление . Ниже показана стартовая точка работы загрузчика t_tcl.out :


 ...
 void task_tcl (void *arg)
 {
         char *cmd;
         unsigned char result, got_partial, quit_flag;
         Tcl_Interp *interp;
         Tcl_CmdBuf buffer;
 
         mem_init (&pool, (mem_size_t) 0x200000, (mem_size_t) 0x400000);
 again:
         printf ("\nEmbedded TCL\n\n");
         printf ("Enter \"help\" for a list of commands\n\n");
 
         interp = Tcl_CreateInterp (&pool);
         Tcl_CreateCommand (interp, "loop", loop_cmd, 0, 0);
 	...
        buffer = Tcl_CreateCmdBuf (&pool);
         got_partial = 0;
         quit_flag = 0;
         while (! quit_flag) {
 /*              clearerr (stdin);*/
                 if (! got_partial) {
                         debug_puts ("% ");
                 }
                 if (! debug_gets (line, sizeof (line))) {
                         if (! got_partial)
                                 break;
 
                         line[0] = 0;
                 }
                 cmd = Tcl_AssembleCmd (buffer, line);
                 if (! cmd) {
                         got_partial = 1;
                         continue;
                 }
 
                 got_partial = 0;
                 result = Tcl_Eval (interp, cmd, 0, 0);
 
                 if (result != TCL_OK) {
                         debug_puts ("Error");
 
                         if (result != TCL_ERROR)
                                 printf (" %d", result);
 
                         if (*interp->result != 0)
                                 printf (": %s", interp->result);
 
                         debug_putchar (0, '\n');
                         continue;
                }
 
                 if (*interp->result != 0)
                         printf ("%s\n", interp->result);
         }
 
         Tcl_DeleteInterp (interp);
         Tcl_DeleteCmdBuf (buffer);
         goto again;
 }
 	
 void uos_init (void)
 {
         task_create (task_tcl, 0, "tcl", 1, task, sizeof (task));
 }
 
Функция uos_halt() - завершает работу системы , используется при отладке .

Задача - представляет собой поток управления (thread) . У каждой задачи свой стек .

Тип task_t :


 #include < kernel/uos.h>
 typedef struct task_t {
 ...
 }task_t;
 task_t *task_create(void (*func)(void*),
 		void *arg,
 		char *name,
 		int priority,
 		char *stack,
 		int stacksz);
 
Это структура , описывающая задачу . ОС производит переключение между задачами . Для работы с задачами применяются следующие функции :

 'task_create'
 'task_exit'
 'task_delete'
 'task_wait'
 'task_stack_avail'
 'task_name'
 'task_priority'
 'task_set_priority'
 

Тип lock_t применяется для работы с ресурсами :


 #include < kernel/uos.h>
 typedef struct _lock_t {
 ...
 }lock_t;
 
Применяются следующие функции :

 'lock_take' - захват ресурса
 'lock_release' - освобождение ресурса
 'lock_try' - попытка захвата ресурса
 'lock_signal' - посылка сообщения
 'lock_wait' - ожидание сообщения
 
Ниже показана схема работы функции lock_release :

Для обработки аппаратных прерываний применяется механизм сообщений . При захвате ресурса задача может присвоить ему номер аппаратного прерывания , и ожидать сообщения .

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

У этого метода обработки прерываний есть недостаток - требуется переключение задач на каждое прерывание . Если нужна более быстрая реакция на прерывания , применяется механизм быстрой обработки .

Быстрый обработчик - это функция , которая регистрируется рои захвате ресурса прерывания , и вызывается ядром при наступлении прерывания . Обслужив прерывание , такой обработчик принимает решение - стоит ли основной задаче посылать сообщение о прерывании .

Если ресурс захвачен с помощью lock_take , он может быть освобожден после lock_release или lock_wait .

Следующая диаграмма показывает работу функции lock_take_irq() , которая захватывает ресурс и привязывает его к аппаратному прерывани/ю с указанным номером :

Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье
Roman
  Как создать процесс. можно пример простейший, например моргание светодиодом через определенное время. и как скомпилировать под AVR?
2009-09-05 16:20:31