Как стать автором
Обновить

Почти ОС реального времени — 2

Время на прочтение 2 мин
Количество просмотров 9.2K
Теперь, когда инструмент готов, его уже можно и нужно использовать.

Предварительно пара слов про Главный Таймер.

На плате предусмотрен внешний генератор импульсов (часы DS1307). Генератор настроен на частоту 4 кГц и импульсы заведены на ногу INT0 — внешнее прерывание.

Это прерывание и используется как главный таймер в системе. Как? Да очень просто:

unsigned int calc_delay; // Счетчик Главного Таймера

ISR(INT0_vect) {
  if (calc_delay > 41) { // каждые 10 мсек
    calc_delay = 0;
    dispatchTimer(); // а вот и диспетчер
  } else
    calc_delay++;
}

* This source code was highlighted with Source Code Highlighter.


Макросом ISR в avr-gcc описывается обработчик прерывания. Эта функция вызывается 4096 раз в секунду. А наш диспетчер таймеров вызывается один раз в 10 мсек (с небольшой погрешностью).
Желающие могут использовать встроенный таймер или другой период таймера, суть от этого не меняется.

Еще у меня используются прерывания ADC (опрос клавиатуры) и UART (общение с компом). Там тоже минимализм — положить значение в буфер и продолжить. Основная работа выполняется в главном цикле программы:

int main() {
  init();
  
  for(;;) {
    dispatchMessage();
  }
}

* This source code was highlighted with Source Code Highlighter.


Надеюсь, даже комментировать не нужно. Да, есть небольшой, но очень важный кусочек кода в процедуре инициализации:

  // регистрация обработчиков событий
  
  setHandler(MSG_LCD_REFRESH, &refreshLCD);
  setTimer(MSG_LCD_REFRESH, 0, 20);

  setHandler(MSG_ADC_CYCLE, &readKey);
  setHandler(MSG_KEY_REPEAT, &repeatKey);

  setHandler(MSG_KEY_PRESS, &analyseKey);
  
  setHandler(MSG_1W_TEMP, &owTemp);
  setTimer(MSG_1W_TEMP, 1, 10);

* This source code was highlighted with Source Code Highlighter.


В двух словах — выставляем обработчик и взводим таймер. Дальше уже работает система — отслеживает таймер и создает событие. События обрабатываются в порядке поступления. Функция-обработчик выполняет действия и опять взводит таймер (если надо).

Например, так выглядит самая простая функция перерисовки экрана:

unsigned char Disp[2][20]; // буфер экрана

unsigned char refreshLCD(msg_par par) {
  lcd_gotoxy(0,0);
  lcd_puts(Disp[0]); // выводим первую строку
  lcd_gotoxy(0,1);
  lcd_puts(Disp[1]); // выводим вторую строку

  setTimer(MSG_LCD_REFRESH, 0, 20);
  return(0);
}


* This source code was highlighted with Source Code Highlighter.


Экранчик обновляется, клавиатура анализируется, датчики опрашиваются.

Следующий раздел — интерфейс пользователя.

Теги:
Хабы:
+16
Комментарии 18
Комментарии Комментарии 18

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн