C语言 在计划的裸机嵌入式应用中使用内部硬件监视器的最安全方法是什么(以及为什么)?



我已经在几个无操作系统的嵌入式应用程序中使用了内部硬件看门狗(带有静态调度程序)。

我所做的是:

  • 我查找最慢的周期性和最低优先级的任务
  • 我将看门狗超时设置为超过最慢任务的时间段
  • 然后我在最慢的任务开始时踢狗

我认为这是一种极简但安全的方法。

有什么最佳实践吗?(个人经验或经过验证的来源)

我听说/看到人们做不同的事情,比如在不同的任务中不止一次踢狗,或者只有在超时内调用所有任务时才踢狗,...

您的方法存在一个问题,您无法通过运行所有其他任务运行的最慢任务来保证。

作为多任务环境中的扩展,您通常最终会得到一些高优先级任务,这些任务是确保功能和其他任务(IO,硬件监控等)所必需的,而您并不真正关心这些任务。

所以你的看门狗只在重要的事情上需要,但你必须观察它们。 为了确保您需要非常简单的解决方案,运行状态结构如下:

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

周围有互斥锁。每个任务都设置自己的hasRunFlag,并检查是否也设置了所有其他任务。如果设置了所有其他设置,它将重置所有并触发看门狗。如果您不让每个任务自行检查,您可能会错过被阻止的任务。

对于这个问题,有更优雅的方法,但这种方法是便携式的,可以让你知道该怎么做。

你的问题有点主观,但实时应用程序有一个行业事实上的标准,它是这样的:

  • 指定系统允许的最大响应时间。例如,允许某些任务占用的最长时间。考虑 ISR 等。例如 1 毫秒。
  • 将狗设置为略长于指定响应时间的时间。
  • 从整个程序中的一个位置踢狗,最好是从main()循环或类似的合适位置踢狗(RTOS没有标准来做这件事,AFAIK)。

这是最严格的要求 - 理想情况下,狗对你的各种任务一无所知,但远离应用程序逻辑。

实际上,对于某些系统来说,这可能很难做到 - 假设您有闪存引导加载程序和类似的引导加载程序,就其性质而言,它们必须花费很长时间。然后,您可能不得不做一些肮脏的事情,例如在特定驱动程序中放置看门狗踢。但这是要争取的最佳实践。

因此,理想情况下,您将它放在应用程序的顶层:

void main (void)
{
/* init stuff */
for(;;)
{
kick_dog();
result = execute();
error_handler(result);
}
}

作为这项政策的副作用,它消除了"有才华"的人最终从 ISR 内踢狗的风险。

最新更新