Evgeny_CDАрхитектор (10.06.2008 00:42, просмотров: 263) ответил AlexandrY на Очередь на real-time. В этом что-то есть...
Такие сложности уже продуманы :) У нас есть некая
struct HW_TIME{
unsigned volitile int HW_TIME_lsint; // регистр таймера
int HW_TIME_msint;
};
У таймера есть два важных для нас регистра:
* compare 1 - генерит прерывание
* compare 2 - генерит прерывание для обнуления таймера.
Важно! compare 2 всегда меньше максимального числа, которой может насчитать таймер.
Надо нам сделать засечку времени. С шагом квантования = тику таймера. Но разрядность слова времени - long long.
Читаем HW_TIME_lsint. Если значение > максимально допустимого значения -> значит была достигнута граница таймера, но прерывание не отработало. И пока системное время не корректно.
Снова читаем. If < максимально допустимого значения читаем и HW_TIME_msint. Эта пара и даст корректное значение "длинного системного времени".
Ну а дальше от него и танцуем.
Таймер останавливать нелья! - Время должно быть монотонным и равномерным.
В хороших контроллерах прерываний, у которых можно прочитать бит необработанного прерывания без сброса, все это можно автоматизировать - т.е. время на таймере будет монотонным и непрерывным, и мы будем знать - было ли переполнение, и корректна ли HW_TIME_msint.
Далее бинарное дерево "как в книжке Кнута" очереди ожидающих событий. Обработали событие - удалили этот узел. И так от самого старого, заодно фиксируем максимальный "пролет" по времени (разница между заданным временем и временем, когда активировали семафор).
При выборе события еще нужно учесть приоритеты, для чего надо правильно настроить формулу весов - какова максимальная длительность ожидания для того, чтобы ++ приоритет семафора.
Далее начинается махровая математика из теории очередей, тут я не силен.
Соственно, вот ради таких "тонкостей" 32 бита и надо. На ATxmega все это проделывать будет непросто.