11

我的微控制器中有一个看门狗,如果它没有被踢,将重置处理器。我的应用程序在一段时间内运行良好,但最终会重置,因为看门狗没有被踢。如果我逐步执行该程序,它可以正常工作。

有什么方法可以调试这个?

编辑:结论:我发现我的错误的方式是看门狗面包屑。

我正在使用具有高 ISR 向量和低 ISR 向量的 PIC。高向量用于处理 LED 矩阵,而低向量用于处理计时器滴答声。但是我将两个 ISR 处理程序都放在了高向量中。因此,当我禁用 LED 矩阵 ISR 并且计时器滴答 ISR 需要服务时,处理器将卡在低 ISR 以处理计时器滴答,但计时器滴答处理程序不存在。

面包屑将我的搜索限制在处理 LED 矩阵并专门禁用 LED 矩阵中断的函数上。

4

8 回答 8

10

添加一个未初始化的全局变量,该变量在整个代码中设置为不同的值。具体来说,在主要函数调用之前和之后设置它。

在 main 的开头放置一个断点。

当处理器重置时,全局变量仍将具有上次设置的值。继续添加这些“面包屑”以缩小问题功能。

于 2009-03-19T11:46:42.807 回答
4

当您附加调试器时,许多软件看门狗会自动禁用(以防止在调试器暂停应用程序时重新启动)。

也就是说,这里有一些基础知识:

这是一个多线程应用程序吗?您使用的是 RT 调度程序吗?如果是这样,你的看门狗任务饿死了吗?

确保您的看门狗任务不会卡在任何事情上(挂起的信号量、等待消息等)。有时,函数会以您意想不到的方式阻塞;例如,我现在正在开发一个 Linux 平台,可以很容易地阻止 printf。

如果它是单线程的,分析器可以帮助您识别时序问题。

如果这是一个新系统,请确保看门狗工作正常;测试刚刚碰到 WD 然后进入无限循环的简单代码。

于 2009-03-19T11:50:16.230 回答
2

我使用基于状态的编程,而我一直想使用的一个技巧是为二进制的当前状态保留一个输出端口。然后连接逻辑分析仪并查看状态变化的时间。你可以在这里做类似的事情:按照罗伯特所说的做,创建一个全局变量并在关键点更改它的值 - 最好使用一个立即将端口值设置为当前状态的函数(即 changeState(nextState); )进入踢狗的函数时的状态,然后在离开函数之前将其更改回之前的状态。您应该能够从哪些功能中看到它没有被踢,然后您可以处理这些功能。

祝你好运,这听起来像是一个时间问题,而且很难解决。

于 2009-03-19T13:22:41.797 回答
2

通常看门狗任务/线程以低优先级运行。所以如果看门狗没有被踢,这应该是因为处理器正忙于做其他事情——可能是它不应该做的事情。

在处理器重置之前为每个任务/线程转储执行上下文(本地堆栈、调度状态等)非常有用。如果有一点运气和工作,您将能够确定是什么阻止了看门狗任务启动计时器。

于 2009-03-19T13:40:14.717 回答
2

我会使用一个额外的输出引脚,在代码中的适当点设置高然后低,以限制我正在寻找的范围。然后我会在数字示波器或逻辑分析仪上对其进行跟踪。这相当于另一张海报提到的面包屑方法,但您将能够更好地与复位脉冲进行时间相关。

于 2009-03-23T01:17:17.600 回答
1

您可以在代码中插入一个 while 循环,并在 while 循环内切换一个 LED。这是检查板子是否正在复位的有效方法。

于 2016-09-06T12:35:29.530 回答
0

质疑你所做的每一个假设,两次:

  • 确保看门狗踢(我不知道处理器上的日志记录工具)。
  • 确保看门狗在被踢时不会重置处理器。

并想知道“步入”和独自跑步之间有什么区别;时间限制肯定很重要。

于 2009-03-19T11:41:16.033 回答
0

您可以将strace(option -p) 附加到正在运行的进程,观察它何时停止写入打开的文件描述符/dev/watchdog。您可以使用选项过滤strace输出-e。有关详细信息,请参阅手册页。

于 2021-04-13T13:14:16.000 回答