Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 OS
 osjournal 
 Protected Mode 
 Hardware 
 Kernels
  Dark Fiber
  BOS
  QNX
  OS Dev
  Lecture notes
  MINIX
  OS
  Solaris
  История UNIX
  История FreeBSD
  Сетунь
  Эльбрус
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...3284 
 Trees...455 
 Clickhouse...437 
 Go Web ...430 
 Ethreal 4...424 
 Максвелл 3...386 
 Ext4 FS...384 
 C++ Patterns 3...375 
 William Gropp...364 
 Rodriguez 6...360 
 Ethreal 1...356 
 Secure Programming for Li...356 
 Gary V.Vaughan-> Libtool...354 
 Steve Pate 1...349 
 Ethreal 3...341 
 Assembler...337 
 DevFS...335 
 Стивенс 9...333 
 Ulrich Drepper...322 
 Стивенс 10...301 
 
  01.01.2024 : 3621733 посещений 

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