Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ***********************************************************
- // ** NyaOS Sample **
- // ***********************************************************
- // http://teplofizik.diary.ru/p179655647.htm
- // API
- #include "nyaos.h"
- // Максимальное количество процессов
- extern const uint32_t ProcessMaxCount;
- // Максимальное количество зарегистрированных событий
- extern const uint32_t EventMaxCount;
- // Текущий процесс
- extern volatile uint32_t CurrentProcess;
- // Таблица процессов
- extern volatile TProcess ProcessTable[PROCESS_MAX_COUNT];
- // Таблица контекстов
- extern volatile TProcessContext ContextTable[PROCESS_MAX_COUNT];
- // Таблица зарегистрированных событий
- extern volatile TEvent EventTable[EVENT_MAX_COUNT];
- void swi_Delay(uint32_t Milliseconds);
- uint32_t swi_WaitForEvent(EVENT Event);
- uint32_t swi_ExitProcess(uint32_t ExitCode);
- uint32_t swi_RegisterEvent(EVENT Event, volatile uint32_t * Value, uint32_t Mask);
- uint32_t swi_FireEvent(EVENT Event, uint32_t Value);
- // Инициализация задержки
- void swi_Delay(uint32_t Milliseconds)
- {
- volatile TProcess * Process = &ProcessTable[CurrentProcess];
- Process->Event = Milliseconds * 8;
- Process->Flags |= F_DELAY;
- }
- // Инициализация ожидания события
- uint32_t swi_WaitForEvent(EVENT Event)
- {
- volatile TProcess * Process = &ProcessTable[CurrentProcess];
- // Найти в таблице событие...
- volatile TEvent * E = nyaos_GetEvent(Event);
- if(E)
- {
- volatile uint32_t * Value = (uint32_t *)E->Event;
- // Если событие не обработано пока никем, ждать нечего
- if (*Value)
- {
- uint32_t Val = *Value;
- // Событие обработано
- *Value = 0;
- // Результат запишется в R0 по выходу автоматически
- return Val;
- }
- }
- // Скопипастим параметры, ждём наступление события
- Process->Event = Event;
- Process->Flags |= F_EVENT;
- // Этот результат перезапишется
- return 0;
- }
- // Завершить процесс
- // Аргументы: 1
- // ExitCode: код завершения (не используется)
- // Результаты: нет
- uint32_t swi_ExitProcess(uint32_t ExitCode)
- {
- volatile TProcess * Process = &ProcessTable[CurrentProcess];
- // Сигнализируем систему о завершении процесса с заданным кодом!
- swi_FireEvent(CurrentProcess, ExitCode);
- // Очистим PID как знак неактивности процесса.
- // Вообще, стоит тут удалять всю занятую процессом память,
- // если та выделялась динамически. Но тут всё жёстко пока.
- Process->PID = 0;
- // Все его состояния перезапишутся потом при создании другого
- // процесса в этом слоте.
- return 0;
- }
- // Зарегистрировать событие
- // Аргументы: 3
- // Event: идентификатор события
- // Value: адрес переменной, за которой наблюдаем.
- // Mask: маска для проверки
- // Результат: код ошибки (0 - добавилось, иначе ошибка).
- uint32_t swi_RegisterEvent(EVENT Event, volatile uint32_t * Value, uint32_t Mask)
- {
- volatile TEvent * E = 0;
- int i;
- // Найдём свободный слот
- for(i = 0; i < EventMaxCount; i++)
- {
- E = &EventTable[i];
- if(E->EventID == 0) break;
- }
- // Нет свободных слотов
- if(i == EventMaxCount) return 1;
- E->EventID = Event;
- E->Event = (uint32_t)Value;
- return 0;
- }
- // Сигнализировать событие
- // Аргументы: 2
- // Event: код события
- // Value: значение для передачи
- // Результаты: код ошибки
- uint32_t swi_FireEvent(EVENT Event, uint32_t Value)
- {
- volatile TEvent * E = 0;
- int i;
- int count = 0; // Счётчик обработанных событий
- // Проверка процессов, и установка флагов, если событие слушается
- for(i = 0; i < ProcessMaxCount; i++)
- {
- volatile TProcess * Process = &ProcessTable[i];
- // Процесс слушает наше событие
- if(Process->Flags & F_EVENT)
- {
- if (Process->Event == Event)
- {
- // Смотрим контекст
- volatile TProcessContext * Context = Process->Context;
- // Смотрим адрес стека, сохранённые регистры
- volatile TInterruptStackFrame * StackFrame = (volatile TInterruptStackFrame *)Context->SP;
- // Записываем код события в R0
- StackFrame->R0 = Value;
- // Сбрасываем флаг ожидания события
- Process->Flags &= ~F_EVENT;
- count++;
- }
- }
- }
- if(!count)
- {
- // Если обработчиков не было, поглядим в таблице, зарегистрировано ли?
- for(i = 0; i < EventMaxCount; i++)
- {
- E = &EventTable[i];
- if(E->EventID == Event)
- {
- if(E->Event) *(uint32_t *)E->Event = Value;
- }
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement