Пока ОС предоставляет только услугу переключения процессов. Однако в любой человеческой ОС нужны две важных вещи: программная задержка и ожидание события. Пока не истекло время или не наступило ожидаемое событие, процесс не получает управления. Таким образом можно ожидать, например, прихода символа по UART сколь угодно долго, никак не напрягая ядро.
читать дальшеДля таких случаев у меня выделен регистр флагов. И понадобится ещё один служебный 32-битный регистр, например Event.
1. Один флаг (F_DELAY) будет обозначать, что сейчас выполняется программная задержка. На каждый вызов прерывания таймера число, сохранённое в регистре Event будет уменьшаться на единицу. По достижении нуля флаг F_DELAY снимается, процесс продолжает выполнение в обычном режиме.
2. Другой флаг (F_EVENT) будет означать, что выполняется ожидание событие. Событие представлено сохранённой в регистре Event ссылкой на переменную. Как только в переменной читается ненулевое значение, оно заносится в R0 процесса (код результата) и флаг F_EVENT снимается. Процесс продолжает выполнение.
Чем это здорово, что легко генерировать программные события. Заводи переменную, меняй её значение...
В принципе, можно немного модифицировать систему событий и ввести третий параметр: маска, которая применяется к переменной перед проверкой. Тогда можно будет ссылаться напрямую на регистры периферии с флагами прерываний.
Но тут не так. ОС проверяет значение переменной и, если оно ненулевое, записывает значение в R0 процесса (стек) и ноль в переменную как знак того, что событие обработано.
И добавить следует несколько API-функций:
1. Задержка.
2. Ожидание события.
3. Добавление события.
4. Активация события
Все API идут через программные прерывания. Кстати, в Си их определение объявляют c помощью ключевого слова __svc(номер):
Реализация функций написана тоже на Си. Только обработчик прерывания на ассемблере. Начало в нём точно такое же, как и раньше, только в конец добавлено переключение процессов, если надо.
Надобность определяется тоже просто: имеется константа SWI_ChCount, с которой сравнивается номер программного прерывания. Если больше или равно - переключения нет, если меньше, то переключение форсируется.
То есть в данном проекте будет форсироваться переключение после вызова функций Delay и WaitForEvent.
Можно поморгать светодиодами с помощью них... Этим занимается третий процесс.
А первые два работают с кнопкой по следующей логике:
Первый регистрирует событие и потом в цикле опрашивает кнопку с периодичностью порядка 10 мс и по детектированию фронта на линии кнопки генерирует событие. Ну и светодиодом 0 показывает состояние линии кнопки. В зависимости от фронта он генерирует событие с кодом 1 (нажали) или 3 (отпустили).
Второй ждёт события и моргает светодиодом (номер берёт из кода события) длительностью примерно 100 мс.
Третий просто моргает светодиодом, номер которого передаётся через аргумент (2).
Таким образом, по нажатию кнопки моргнёт светодиод 1 (оранжевый), а по отпускнию - светодиод 3 (синий).
Ну и я добавил в проект файл system_stm32f4xx.c из CMSIS, который имеет реализацию функции SystemInit, где тактовая частота настраивается равной 168 МГц.
Файлы только самые интересные, остальные в проекте:
main.c
nyaos.c
nyaos.h
nyaos_api.c
nyaos.core.s
swi_table.s
<< Предыдущее Следующее >>
STM32F4. Задержки и события в ОС.
Пока ОС предоставляет только услугу переключения процессов. Однако в любой человеческой ОС нужны две важных вещи: программная задержка и ожидание события. Пока не истекло время или не наступило ожидаемое событие, процесс не получает управления. Таким образом можно ожидать, например, прихода символа по UART сколь угодно долго, никак не напрягая ядро.
читать дальше
<< Предыдущее Следующее >>
читать дальше
<< Предыдущее Следующее >>