Advertisement
teplofizik

nyaos_api.c (11)

Aug 14th, 2012
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.17 KB | None | 0 0
  1. // ***********************************************************
  2. // **                    NyaOS Sample                       **
  3. // ***********************************************************
  4. // http://teplofizik.diary.ru/p179655647.htm
  5.  
  6. // API
  7.  
  8. #include "nyaos.h"
  9.  
  10. // Максимальное количество процессов
  11. extern const uint32_t           ProcessMaxCount;
  12.  
  13. // Максимальное количество зарегистрированных событий
  14. extern const uint32_t           EventMaxCount;
  15.  
  16. // Текущий процесс
  17. extern volatile uint32_t        CurrentProcess;
  18.  
  19. // Таблица процессов
  20. extern volatile TProcess        ProcessTable[PROCESS_MAX_COUNT];
  21.  
  22. // Таблица контекстов
  23. extern volatile TProcessContext ContextTable[PROCESS_MAX_COUNT];
  24.  
  25. // Таблица зарегистрированных событий
  26. extern volatile TEvent          EventTable[EVENT_MAX_COUNT];
  27.  
  28. void swi_Delay(uint32_t Milliseconds);
  29. uint32_t swi_WaitForEvent(EVENT Event);
  30. uint32_t swi_ExitProcess(uint32_t ExitCode);
  31. uint32_t swi_RegisterEvent(EVENT Event, volatile uint32_t * Value, uint32_t Mask);
  32. uint32_t swi_FireEvent(EVENT Event, uint32_t Value);
  33.  
  34. // Инициализация задержки
  35. void swi_Delay(uint32_t Milliseconds)
  36. {
  37.     volatile TProcess * Process = &ProcessTable[CurrentProcess];
  38.    
  39.     Process->Event = Milliseconds * 8;
  40.     Process->Flags |= F_DELAY;
  41. }
  42.  
  43. // Инициализация ожидания события
  44. uint32_t swi_WaitForEvent(EVENT Event)
  45. {
  46.     volatile TProcess * Process = &ProcessTable[CurrentProcess];
  47.    
  48.     // Найти в таблице событие...
  49.     volatile TEvent * E = nyaos_GetEvent(Event);
  50.    
  51.     if(E)
  52.     {
  53.         volatile uint32_t * Value = (uint32_t *)E->Event;
  54.    
  55.         // Если событие не обработано пока никем, ждать нечего
  56.         if (*Value)
  57.         {
  58.             uint32_t Val = *Value;
  59.            
  60.             // Событие обработано
  61.             *Value = 0;
  62.            
  63.             // Результат запишется в R0 по выходу автоматически
  64.             return Val;
  65.         }
  66.     }
  67.    
  68.     // Скопипастим параметры, ждём наступление события
  69.     Process->Event      = Event;
  70.     Process->Flags     |= F_EVENT;
  71.  
  72.     // Этот результат перезапишется
  73.     return 0;
  74. }
  75.  
  76. // Завершить процесс
  77. // Аргументы: 1
  78. //  ExitCode: код завершения (не используется)
  79. // Результаты: нет
  80. uint32_t swi_ExitProcess(uint32_t ExitCode)
  81. {
  82.     volatile TProcess * Process = &ProcessTable[CurrentProcess];
  83.    
  84.     // Сигнализируем систему о завершении процесса с заданным кодом!
  85.     swi_FireEvent(CurrentProcess, ExitCode);
  86.    
  87.     // Очистим PID как знак неактивности процесса.
  88.     // Вообще, стоит тут удалять всю занятую процессом память,
  89.     // если та выделялась динамически. Но тут всё жёстко пока.
  90.     Process->PID = 0;
  91.    
  92.     // Все его состояния перезапишутся потом при создании другого
  93.     // процесса в этом слоте.
  94.    
  95.     return 0;
  96. }
  97.  
  98. // Зарегистрировать событие
  99. // Аргументы: 3
  100. //  Event: идентификатор события
  101. //  Value: адрес переменной, за которой наблюдаем.
  102. //  Mask:  маска для проверки
  103. // Результат: код ошибки (0 - добавилось, иначе ошибка).
  104. uint32_t swi_RegisterEvent(EVENT Event, volatile uint32_t * Value, uint32_t Mask)
  105. {
  106.     volatile TEvent * E = 0;
  107.     int i;
  108.    
  109.     // Найдём свободный слот
  110.     for(i = 0; i < EventMaxCount; i++)
  111.     {
  112.         E = &EventTable[i];
  113.        
  114.         if(E->EventID == 0) break;
  115.     }
  116.    
  117.     // Нет свободных слотов
  118.     if(i == EventMaxCount) return 1;
  119.    
  120.     E->EventID = Event;
  121.     E->Event   = (uint32_t)Value;
  122.    
  123.     return 0;
  124. }
  125.  
  126. // Сигнализировать событие
  127. // Аргументы: 2
  128. //  Event: код события
  129. //  Value: значение для передачи
  130. // Результаты: код ошибки
  131. uint32_t swi_FireEvent(EVENT Event, uint32_t Value)
  132. {
  133.     volatile TEvent * E = 0;
  134.     int i;
  135.     int count = 0; // Счётчик обработанных событий
  136.    
  137.     // Проверка процессов, и установка флагов, если событие слушается
  138.     for(i = 0; i < ProcessMaxCount; i++)
  139.     {
  140.         volatile TProcess * Process = &ProcessTable[i];
  141.        
  142.         // Процесс слушает наше событие
  143.         if(Process->Flags & F_EVENT)
  144.         {
  145.             if (Process->Event == Event)
  146.             {
  147.                 // Смотрим контекст
  148.                 volatile TProcessContext * Context = Process->Context;
  149.                 // Смотрим адрес стека, сохранённые регистры
  150.                 volatile TInterruptStackFrame * StackFrame = (volatile TInterruptStackFrame *)Context->SP;
  151.                
  152.                 // Записываем код события в R0
  153.                 StackFrame->R0 = Value;
  154.                
  155.                 // Сбрасываем флаг ожидания события
  156.                 Process->Flags &= ~F_EVENT;
  157.                
  158.                 count++;
  159.             }
  160.         }
  161.     }
  162.    
  163.     if(!count)
  164.     {
  165.         // Если обработчиков не было, поглядим в таблице, зарегистрировано ли?
  166.         for(i = 0; i < EventMaxCount; i++)
  167.         {
  168.             E = &EventTable[i];
  169.            
  170.             if(E->EventID == Event)
  171.             {
  172.                 if(E->Event) *(uint32_t *)E->Event = Value;
  173.             }
  174.         }
  175.     }
  176.    
  177.     return 0;
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement