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
 Rodriguez 3...2369 
 Linux Kernel 2.6...1762 
 Trees...1403 
 Стивенс 9...1403 
 William Gropp...1402 
 M.Pilgrim->Часть 2...1402 
 Clickhouse...1402 
 Rodriguez 7...1402 
 Part 3...1401 
 Httpd-> История Ap...1401 
 Mod_perl 2...1399 
 Stewens -> IPC 9...1398 
 Cluster 2...1398 
 Robert Love 2...1398 
 ground Up...1398 
 Rodriguez 6...1397 
 Ext4 FS...1396 
 FAQ...1396 
 Ethreal 4...1395 
 Rodriguez 8...1395 
 
  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