Что (и почему) является наиболее безопасным способом использования внутреннего аппаратного сторожевого таймера в запланированном встроенном приложении на «голом железе»?

Я уже использовал внутренние аппаратные сторожевые таймеры в нескольких встроенных приложениях без ОС (со статическими планировщиками).

Что я делаю:

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

Я думаю, что это минималистский, но безопасный подход.

Есть ли лучшая практика? (личный опыт или проверенные источники)

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
242
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

И в качестве расширения в многозадачной среде вы обычно получаете какую-то задачу с высоким приоритетом, которая необходима для обеспечения функциональности и других задач (IO, аппаратный мониторинг и т. д.), о которых вы действительно не заботитесь.

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

struct{
  bool task1HaRun;
  bool task2HasRun;
  bool task3HasRun;
};

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

Есть более элегантные способы решения этой проблемы, но этот портативный и дает вам представление о том, что делать.

"не могу гарантировать"?

Guillaume D 15.04.2019 12:24

@Guillaume D извините, исправил.

user6556709 15.04.2019 13:10

«запустив самую медленную задачу, которую выполняли все остальные задачи». Фактически, при запуске самой медленной задачи в совместном планировщике все задачи вызываются последовательно, поэтому, если выполняется самая медленная задача, выполняется любая задача ... Это можно сделать, как сказал @Lundin, в основном цикле.

Guillaume D 23.04.2019 09:35

@Guillaume D Я предполагал, что вы используете какую-то RTOS, и большинство из них являются упреждающими. Или, чтобы быть более правильным, чтобы обеспечить возможность работы в реальном времени, они должны.

user6556709 23.04.2019 10:04

Я сказал "без ОС" и "голое железо"

Guillaume D 23.04.2019 10:43

@Guillaume D Вы сказали планировщик и задачи. Во встраиваемых системах RTOS больше ничего не делала, и кстати. если у вас чистая кооперативная система, вам не нужны задачи. Они не покупают ничего, кроме большей сложности.

user6556709 23.04.2019 18:32
Ответ принят как подходящий

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

  • Укажите максимально допустимое время отклика системы. Например, самый длинный период времени, который может занять какая-либо задача. Примите во внимание ISR и т. д. Например 1мс.
  • Настройте собаку на время, немного превышающее указанное время отклика.
  • Ударьте собаку из одного места во всей программе, предпочтительно из цикла main() или аналогичного подходящего места (в RTOS нет стандарта, где это делать, насколько я знаю).

Это самое жесткое требование — в идеале собака ничего не знает о ваших различных задачах, но держится подальше от логики приложения.

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

Так что в идеале у вас есть это на самом верхнем уровне вашего приложения:

void main (void)
{
  /* init stuff */

  for(;;)
  {
    kick_dog();
    result = execute();
    error_handler(result);
  }
}

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

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

Guillaume D 23.04.2019 09:50

@GuillaumeD Зависит от того, позволяете ли вы системе пропускать сроки или нет. Для системы реального времени пропущенный крайний срок является ошибкой. Но во время отладки может быть целесообразно отключить wdog и вместо этого использовать таймер.

Lundin 23.04.2019 10:04

но отключение wdg во время отладки — это одно. Удар wdg до или после выполнения основного цикла - это другое. Что вы думаете о вызове удара после выполнения основного цикла, а не перед выполнением основного цикла?

Guillaume D 23.04.2019 11:19

@GuillaumeD «Ударьте wdg до или после выполнения основного цикла». Это цикл ... он повторяется. Но если у вас есть требования в реальном времени, которые значительно сложнее, чем тайм-аут wdog, в любом случае может иметь смысл использовать таймер, чтобы производить диагностику и изящно обрабатывать ошибки - зависит от характера приложения. Некоторые приложения должны сбрасываться при ошибках, другим этого делать нельзя. Для критичных к безопасности систем тайм-аут wdog является последним средством — в идеале они должны вместо этого вернуться в безопасное состояние, прежде чем это произойдет.

Lundin 23.04.2019 12:34

Другие вопросы по теме