Этот вопрос касается программирования небольших микроконтроллеров без ОС. В частности, на данный момент меня интересуют PIC, но этот вопрос носит общий характер.
Я несколько раз видел следующую схему хранения времени:
Код прерывания таймера (скажем, таймер срабатывает каждую секунду):
...
if (sec_counter > 0)
sec_counter--;
...
Основной код (без прерывания):
sec_counter = 500; // 500 seconds
while (sec_counter)
{
// .. do stuff
}
Код основной линии может повторяться, устанавливать счетчик на различные значения (не только секунды) и т. Д.
Мне кажется, здесь есть условие гонки, когда присвоение sec_counter
в основном коде не является атомарным. Например, в PIC18 назначение переводится в 4 оператора ASM (загрузка каждого байта за раз и выбор правильного байта из банка памяти перед этим). Если код прерывания находится в середине этого, окончательное значение может быть повреждено.
Любопытно, что если присвоенное значение меньше 256, присваивание является атомарным, поэтому проблем нет.
Прав ли я об этой проблеме?
Какие шаблоны вы используете для правильной реализации такого поведения? Я вижу несколько вариантов:
- Отключать прерывания перед каждым назначением sec_counter и включать после - это не красиво
- Не используйте прерывание, а используйте отдельный таймер, который запускается и затем опрашивается. Это чисто, но использует весь таймер (в предыдущем случае 1-секундный таймер срабатывания можно было использовать и для других целей).
Есть еще идеи?