Знакомство со сторожевыми таймерами

20/09/2012 - 19:28

Майкл Барр

   Сторожевые таймеры могут быть подходящим решением для встраиваемых систем, которые не могут постоянно находиться под присмотром человека.

   Большинство встраиваемых систем должны полагаться на свои силы. Во-первых, если программное обеспечение зависло, не всегда существует возможность дождаться того, кто бы его перезапустил. Во-вторых, некоторые из устройств, например такие, как космические зонды, попросту не достижимы для людей-операторов. И, в-третьих, скорость, с которой оператор может перезагрузить систему, может быть слишком низкой, чтобы удовлетворить временным требованиям по приведению изделия в рабочее состояние.

   Сторожевой таймер – это элемент оборудования, который может использоваться для автоматического обнаружения аномалий программного обеспечения и сброса процессора, если что-то произойдет. В общем случае, сторожевой таймер основан на счетчике, который ведет обратный отсчет от какого-либо начального значения до нуля. Встроенное программное обеспечение выбирает исходное значение счетчика и периодически перезапускает его. Если счетчик достигает нуля до того, как его перезапустят, то предполагается, что программное обеспечение неисправно и процессор перезапускается. Процессор и программа, которую он выполняет, перезапустятся точно так же, как если бы это сделал человек-оператор. 


   На рисунке 1 показана типичная схема. Из рисунка видно, что сторожевой таймер – это чип, находящийся вне процессора, однако он может быть и в составе процессора. Так, например, устроены многие микроконтроллеры. В обоих случаях, выходной пин сторожевого таймера связан непосредственно с выводом сброса процессора.


Рисунок 1. Типичная компоновка сторожевого таймера.

ПИНАЯ СОБАКУ

  Процесс перезапуска счетчика сторожевого таймера иногда называют «пинанием собаки». Подходящая метафора – это когда на человека бросается злобный пес. Если человек будет пинать собаку, она никогда не сможет его укусить. Но чтобы избежать укуса, он должен продолжать пинать собаку через определенные интервалы времени. Проще говоря, программа должна перезапускать сторожевой таймер с регулярной частотой, иначе возникнет риск перезагрузки.

   В листинге 1 показан простой пример. Тут у нас есть один бесконечный цикл, который управляет всей работой системы. Это так называемая main()+ISR архитектура, популярная во многих встраиваемых системах с недорогими микроконтроллерами. Аппаратная реализация этого сторожевого таймера позволяет устанавливать значение счетчика через отображаемые в памяти регистры.

Листинг 1. Пинаем сторожевой таймера из C кода.


uint16_t volatile * pWatchdog = (uint16_t volatile *) 0xFF0000;

main(void)
{
   hwinit();

   for (;;) {
      *pWatchdog = 10000;
       read_sensors();
       control_motor();
      display_status();
  }
}

   Предположим, что цикл for выполняется как минимум раз в 5 мс. Если счетчик сторожевого таймера инициализирован значением соответствующем 5 мс прошедшего времени, например 10 000, и программа не имеет ошибок, то сторожевой таймер никогда не будет истекать. Поскольку программное обеспечение будет всегда перезапускать счетчик до того, как он достигнет нуля.

АНОМАЛИИ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ

   Сторожевой таймер может избавить систему от опасных ситуаций. Однако если мы хотим, чтобы она была эффективной, перезапуск сторожевого таймера должен рассматриваться в рамках всего проекта. Разработчики должны знать, что может разладиться в их программном обеспечении и быть уверенными, что сторожевой таймер обнаружит неполадки, если что-нибудь случится.

   Системы зависают по многим причинам. Логическая ошибка, приводящая к выполнению бесконечного цикла – самая простая из них. Предположим, такое обстоятельство произошло при выполнении функции read_sensors(), как в листинге 1. Ни одна другая часть программы (кроме обработчика прерываний, если прерывания будут разрешены) не сможет запуститься снова.

   Другая вероятность может состоять в том, что за один проход цикла придется непривычное количество прерываний. Любое время, потраченное в обработчике прерываний – это время, не потраченное на выполнение основного цикла. А значит, может произойти опасная задержка в подаче управляющих команд двигателю.

   Когда используются многозадачные ядра, может произойти взаимоблокировка. Например, группа задач может застрять, ожидая друг друга и какой-нибудь внешний сигнал, который нужен одной из них, подвесив остальной набор задач на неопределенное время.

   Если такие ошибки случаются редко, система может отлично работать определенный промежуток времени после каждого перезапуска, вызванного сторожевым таймером. Однако неисправное оборудование может привести к тому, что ваша система будет постоянно перезапускаться. По этой причине будет не лишним считать число перезагрузок, приведенных в действие сторожевым таймером, и в случае определенного числа неудач, отказаться от дальнейших попыток перезагрузить систему.

УРОКИ КАРАТЕ

   Фактическая реализация сторожевого таймера обычно имеет более сложную взаимосвязь с программой, чем та, что изображена на рисунке 1. Когда набор инструкций, требуемый для перезапуска сторожевого таймера очень прост, есть вероятность того, что содержащая ошибки программа, может совершить это действие случайно. Рассмотрим ошибку, которая приводит к тому, что значение 10 000 записывается в каждый адрес ячейки памяти беспрестанно. Этот код будет регулярно перезапускать счетчик сторожевого таймера, и сторожевой таймер никогда не сможет «укусить». Чтобы предотвратить эту ситуацию, многие варианты сторожевого таймера для рестарта и перезагрузки используют сложную последовательность из двух или более последовательных операций записи.

   Если в ваш микроконтроллер встроен сторожевой таймер, он может не активироваться автоматически при перезагрузке устройства. Вы должны обязательно активировать его во время инициализации аппаратных средств. Для обеспечения защиты от ошибки, случайно выводящей сторожевой таймер из строя, конструкция устройства обычно предусматривает, что вывести из строя сторожевой таймер, однажды приведенный в действие, невозможно.

   Если ваша программа совершает полный цикл быстрее, чем рабочий период сторожевого таймера, структура в листинге 1 будет работать превосходно. Но если какая-то часть программного обеспечения требует для завершения цикла много времени, ситуация усложняется. К примеру, это может быть цикл, ожидающий нагрева элемента до определенной температуры. Многие сторожевые таймеры имеют максимальный период около двух секунд. Если вам нужна отсрочка на время, большее, чем 2 секунды, вы можете «пнуть собаку» внутри цикла ожидания. Если таких мест в вашей программе много, управление сторожевым таймером может стать весьма проблематичным.

   Инициализация системы является частью кода, которому часто требуется время превышающее максимальный цикл сторожевого таймера. По этой причине некоторые сторожевые таймеры могут ждать первого «пинка» дольше, чем последующих. Вообще выбор надлежащего интервала между «пинками»таймера, также является важным вопросом.

   Когда в программу добавляются потоки управления, в виде прерываний и программных задач, «пинать» сторожевой таймер всего в одном месте кода становится неэффективным.

СОБАЧЬЯ ЖИЗНЬ

   Сторожевой таймер – полезное средство, которое может помочь вашей системе восстановиться после непредвиденных отказов. С тех пор, как стало общепринятым встраивать сторожевые таймеры в современные микроконтроллеры, техника стала фактически самостоятельной. Если вы работаете с системой, созданной для решения критически важных задач, то на использовании сторожевого таймера будет настаивать либо ваш здравый смысл, либо контролирующие органы. В любом случае будет хорошо, если вы сделаете ваши системы более самостоятельными.

Murphy, Niall and Michael Barr. "Watchdog Timers" Embedded Systems Programming, October 2001, pp. 79-80.

У вас недостаточно прав для комментирования.