Advertisement
teplofizik

nyaos.c (9)

Aug 11th, 2012
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.06 KB | None | 0 0
  1. // ***********************************************************
  2. // **                    NyaOS Sample                       **
  3. // ***********************************************************
  4. // http://teplofizik.diary.ru/p179560849.htm
  5.  
  6. // Объявление таблиц, запуск ОС и добавление процессов.
  7.  
  8. #include "nyaos.h"
  9.  
  10. #include <string.h>
  11.  
  12. // Заглушка на всякий случай, если вдруг какому-либо процессу захочется выйти с помощью записи LR в PC.
  13. void nyaos_Stub(void);
  14.  
  15. // Настройка системного таймера
  16. void SysTickInit(void);
  17.  
  18. // Максимальное количество процессов
  19. const uint32_t ProcessMaxCount = PROCESS_MAX_COUNT;
  20. // Размер стека
  21. const uint32_t StackSize       = STACK_SIZE;
  22.  
  23. // Запущено?
  24. volatile uint32_t        Started;
  25.  
  26. // Текущий процесс
  27. volatile uint32_t        CurrentProcess;
  28.  
  29. // Номер процесса (для назначения новых)
  30. volatile uint32_t        PIDCounter;
  31.  
  32. // Таблица процессов
  33. volatile TProcess        ProcessTable[PROCESS_MAX_COUNT];
  34.  
  35. // Таблица контекстов
  36. volatile TProcessContext ContextTable[PROCESS_MAX_COUNT];
  37.  
  38. // Куча для стеков
  39. volatile uint8_t         StackHeap[PROCESS_MAX_COUNT][STACK_SIZE];
  40.  
  41. // Процесс для простоя.
  42. static int nyaos_Idle(uint32_t Argument)
  43. {
  44.     while (1)
  45.     {
  46.        
  47.     }
  48. }
  49.  
  50. // Получить адрес стека по умолчанию для слота.
  51. // Не проверяется допустимость номера!
  52. // Аргументы: 1
  53. //  Slot: номер слота
  54. // Результат: указатель стека.
  55. static uint32_t nyaos_GetDefaultSP(uint32_t Slot)
  56. {
  57.     return (uint32_t)&(StackHeap[Slot][StackSize - 4]);
  58. }
  59.  
  60. // Сформировать стек прерывания и вернуть на него указатель
  61. // Аргументы: 1
  62. //  Context: указатель на структуру контекста процесса
  63. static TInterruptStackFrame * nyaos_AddStackFrame(volatile TProcessContext * Context)
  64. {
  65.     TInterruptStackFrame * StackFrame;
  66.    
  67.     if(Context->SP == 0) return 0;
  68.    
  69.     Context->SP -= sizeof(TInterruptStackFrame);
  70.     StackFrame = (TInterruptStackFrame *)Context->SP;
  71.    
  72.     // Настроить регистры по умолчанию
  73.     StackFrame->R0 = 0;
  74.     StackFrame->R1 = 0;
  75.     StackFrame->R2 = 0;
  76.     StackFrame->R3 = 0;
  77.     StackFrame->R12 = 0;
  78.    
  79.     // Адрес возврата: заглушка, чтоб ничего не поломалось. Туда можно добавить функцию завершния процесса
  80.     StackFrame->LR = (uint32_t)&nyaos_Stub;
  81.     StackFrame->PC = (uint32_t)&nyaos_Stub;
  82.    
  83.     // Состояние статуса по-умолчанию
  84.     StackFrame->CPSR = DEFAULT_CPSR;
  85.    
  86.     return StackFrame;
  87. }
  88.  
  89. // Инициализация таблиц, выделение процессам адресов вершин стека
  90. // Аргументы: нет
  91. // Результат: нет
  92. static void nyaos_InitTables(void)
  93. {
  94.     volatile TProcess        * Process;
  95.     volatile TProcessContext * Context;
  96.     int                        i;
  97.    
  98.     for(i = 0; i < ProcessMaxCount; i++)
  99.     {
  100.         Process = &ProcessTable[i];
  101.         Context = &ContextTable[i];
  102.        
  103.         Process->Context = Context;
  104.        
  105.         // Задать начальный SP
  106.         Context->SP = nyaos_GetDefaultSP(i);
  107.     }
  108. }
  109.  
  110. // Добавить процесс
  111. // Аргументы:
  112. //  EntryPoint: точка входа;
  113. //  Argument: аргумент, которй будет передан в функцию;
  114. //  Flags: параметры создания процесса.
  115. // Результат: код ошибки
  116. int nyaos_AddProcess(char * Name, void * EntryPoint, uint32_t Argument, uint32_t Flags)
  117. {
  118.     volatile TProcess             * Process = 0;
  119.     volatile TProcessContext      * Context;
  120.     volatile TInterruptStackFrame * StackFrame;
  121.     int                        i = 0;
  122.    
  123.     // Чтобы добавить процесс, нужно заполнить таблицу его контекста.
  124.     // Но сначала найдём свободную запись о процессе
  125.     for(i = 0; i < ProcessMaxCount; i++)
  126.     {
  127.         // Очередную запись проверим
  128.         Process = &ProcessTable[i];
  129.        
  130.         if(Process->PID == 0)
  131.         {
  132.             // Нашёлся свободный слот
  133.             break;
  134.         }
  135.            
  136.         // Уберём адрес как свидетельство занятости
  137.         Process = 0;
  138.     }
  139.    
  140.     // Если не нашлось, сообщим об этом
  141.     if(Process == 0) return E_PROCESS_MAX_COUNT;
  142.    
  143.     // Новый номер процесса
  144.     PIDCounter++;
  145.    
  146.     Process->PID = PIDCounter;
  147.     Process->Flags = 0;
  148.     Process->Name = Name;
  149.    
  150.     // Настроим контекст
  151.     Context = &ContextTable[i];
  152.    
  153.     // Указатель стека - в начальное положение
  154.     Context->SP = nyaos_GetDefaultSP(i);
  155.    
  156.     // Указатель на стек прерывания
  157.     StackFrame = nyaos_AddStackFrame(Context);
  158.    
  159.     // Установим PC на точку входа
  160.     StackFrame->PC = (uint32_t)EntryPoint;
  161.    
  162.     // Аргумент в R0
  163.     StackFrame->R0 = Argument;
  164.    
  165.     // R8-R11 выставим в 0
  166.     memset((void *)&Context->Rother[0], 0, sizeof(Context->Rother));
  167.    
  168.     return E_PROCESS_CREATED;
  169. }
  170.  
  171. // Инициализация ОС
  172. // Аргументы: нет
  173. // Результат: нет
  174. void nyaos_Init(void)
  175. {
  176.     SysTickInit();
  177.    
  178.     nyaos_InitTables();
  179.    
  180.     // Добавим пустой процесс
  181.     nyaos_AddProcess("Idle", &nyaos_Idle, 0, 0);
  182.    
  183.     CurrentProcess = 0;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement