Мои правила написания программ:
Весь набор правил подчиняется главному условию - псевдопараллельность процессов. Каждый процесс при каждой итерации выполняет часть кода.
Модульность. Стараемся делать все модули самостоятельными.
Никаких долгих циклов.
Разбиение функций на подзадачи. Стремимся к тому, чтобы все модули быстро выполняли свой код. Вход в функцию, выполнение кода, выход. Проверка условий, выполнение кода, выход. Разбиение на подзадачи осуществляется флагами, условиями, состояниями конечных автоматов.
Автоматное программирование. У конечных автоматов помимо всего прочего есть отличная фича. Нулевое состояние можно сделать состоянием самоинициализации модуля. Инициализация ввода-вывода, переменных.
Программные таймеры. Я перелопатил таймерную службу взятую у ди хальта. И перенес ее в основной цикл. Настриваем аппаратный таймер на 1 мс, если кварц на 8 или 16 МГц. Или 10 мс, если кварц для uart. В прерывании выставляется флаг. В службе проверяется флаг. если флаг установлен, сброс и перебор очереди программный таймеров. Структура таймера - статус, 16-битный счетчик.
Итерация основного цикла должна с запасом впаковаться в тик системного таймера. То есть, 1 мс или 10 мс.
Проекты при таком подходе создаются как конструктор из кирпичиков модулей.
Нет затрат на перебор диспетчером задач. Установку задач в очередь, удаление задач из очереди.
В итоге основной цикл представляет из себя список необходимых функций. Пример я показал выше. У меня нет диспетчеров. Нужно поправить проект? Вписываем нужные функции. Удаляем ненужные функции.
Видео одного из последних проектов.
Основной цикл этого проекта:
CODE
//========================================================================
void main (void)
{
// wait_500_ms (); // После включения питания задержка 500 мс.
wdt_enable (WDTO_15_MS);
init_sys_timer ();
__enable_interrupt ();
// logo (); // Что-то вроде заставки.
Init_Events ();
while (1)
{
__watchdog_reset ();
service_timers (); // Программные таймеры.
proc_eds (); // Управление циклом работы станка.
tui_service (); // Модуль вывода информации на дисплей.
drv_char_dsp (); // Модуль дисплея VFD. Аппаратная часть.
Process_Events (); // Служба сообщений. Взаимодействие модулей.
}
}
//========================================================================