Как предотвратить зависание системы перед выполнением задачи сторожевого таймера

Мы используем встроенную систему ARM AM1808 с rtos и файловой системой. Мы используем язык C. У нас есть сторожевой таймер, реализованный внутри кода приложения. Итак, всякий раз, когда что-то происходит в коде приложения, сторожевой таймер заботится о системе.

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

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

Профессиональные встроенные системы разработаны следующим образом:

  • Выберите MCU с прерыванием включения питания и встроенным сторожевым таймером. Это стандарт для всех современных микроcontrollerов.
  • Выполните следующие шаги изнутри вектора прерывания сброса.
  • Если память MCU прост в настройке, например, просто установив указатель стека, сделайте это, прежде всего, из сброса. Это позволяет программировать на С.
  • Если настройка памяти сложная – есть установка MMU или аналогичная – ей придется подождать, и вам придется придерживаться ассемблера, чтобы предотвратить случайную укладку, вызванную кодом C.
  • Установите наиболее фундаментальные регистры, такие как регистры режимов, сторожевой таймер и системные часы.
  • При необходимости установите аппаратуру обнаружения низкого напряжения. Надеемся, что состояние отказа от сброса для LVD на MCU является звуковым.
  • Здесь должны быть установлены специфические для приложения критические регистры, такие как направление GPIO и внутренние резисторные резисторные регистры. Многие MCU имеют контакты по умолчанию, что делает их уязвимыми. Если они не предназначены для ввода в приложение, время их хранения как таковое вне сброса должно быть сведено к минимуму, чтобы избежать проблем с шумом, переходными процессами и ОУР.
  • Установите MMU, если это применимо.
  • Все остальное «CRT», например инициализация .data и .bss .
  • Вызовите main() .

Обратите внимание, что готовый код запуска для вашего MCU не обязательно сделан профессионалами! Довольно распространено, что на вашем инструментальном цехе есть «CRT» на любительском уровне, который не может установить сторожевой таймер и часы на ранней стадии. Это, конечно, неприемлемо, поскольку:

  1. Это делает любую программу, запущенную на этой платформе заметной опасностью безопасности / низкого качества, в случае сбоя или зависания «ЭЛТ» по любой причине.
  2. Это делает инициализацию .data и .bss ненужным, мучительно медленным, так как тогда он обычно выполняется с часами, работающими на встроенном по умолчанию RC-генераторе или аналогичном.

Имейте в виду, что даже код де-факто для де-факто, такой как ARM CMSIS, не выполняет некоторые из указанных выше аппаратных настроек MCU. Это может быть или не быть проблемой.

Существует аппаратный сторожевой таймер, который может быть запущен до запуска приложения. ARM AM1808 имеет таймер, который может быть реализован в качестве сторожевого пса, согласно документации: http://www.ti.com/lit/ds/symlink/am1808.pdf. Таким образом, вы можете установить его таким образом, по крайней мере, во время части программы, которая проходит через критический и длинный раздел. Вы хотите иметь кусок кода загрузки, который сначала устанавливает этот сторожевой таймер, и после правильной инициализации переходит к приложению. На самом деле это очень распространенный подход.