65.9K
CodeProject 正在变化。 阅读更多。
Home

Netduino 的简单看门狗

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2014年7月14日

CPOL

5分钟阅读

viewsIcon

22803

以下是用于测试您的 Netduino 的“看门狗”的讨论和快速程序。

引言

如果您创建了自己的 Netduino 应用程序,但某个错误意外地导致其停止运行,会怎样?第一个答案:没问题,我正在调试器前,而且我会有完整的异常堆栈跟踪。
第二个答案:一场噩梦!我周末要度假,而我的基于 Netduino 的洒水系统看起来卡住了……我应该让我的邻居重置板卡,或者,更好的是,让他去浇草。

噩梦

显然,我们对第二个答案感兴趣,或者更好的是,如何避免这种情况。当硬件损坏或软件有 bug 时,并没有太多方法可以挽救板卡的控制。然而,在许多许多情况下,我们的板卡可以完美运行(可能数周)而没有任何问题。一旦它被“现场部署”,第一个问题就出现了。

由于我们没有人想在凌晨 3 点因为系统停止而醒来,或者因为洒水器没有正确浇水而被迫回家,那么我们可以通过添加所谓的“看门狗”来提高可靠性。

这是一种保护系统免受意外停止的非常简单的方法,但并不能解决所有潜在的头疼问题。相反,它更像是一种我们真正无法预见的“最后手段”。

良好的编程实践,以及良好的硬件,是任何系统大部分可靠性的必备冗余。

认真考虑一下。

简单的看门狗

我不知道是谁发明了这个名字……“看门狗”……但(至少对我来说)很清楚有两个不同的主体

  • ,即控制器
  • 房子,被狗看管着

现在,潜在的故障系统是房子,而狗住在房子的“外部”。这是显而易见的,因为如果系统挂了,它怎么能自我拯救呢?这是如此显而易见,以至于许多人都在要求纯软件解决方案,也许使用一个单独的线程作为控制器。

有太多情况会让 MCU 挂起,这会立即导致人们转向外部解决方案。例如

  • 温度过低或过高
  • 电压尖峰(高于供电和低于地)
  • 普遍存在的强烈噪声(尤其是在长导线直接连接到 MCU 引脚时)
  • 软件 bug
  • 硬件不稳定(例如,晶体停止振荡)
  • 还有许多其他

我本可以使用定制芯片作为看门狗。Netduino 的 Atmel 芯片内置了看门狗,但它没有被固件驱动。相反,我想展示一个非常简单的电路,它主要是为了学习如何解决这个问题。

我们将使用一个简单的计数器:74HC4060。它是一个 14 级二进制计数器,还内置了一个基本的 R-C 振荡器。所有这些都是为了获得一个可重新触发的、长周期的定时器。单词“定时器”立刻让人想到令人惊叹的“555”芯片:70 年代硬件设计的杰作。顺便说一句,我们需要相对较长的反应时间:至少几秒钟。这是因为 Netduino 完成完整的重置过程需要几秒钟,然后我们应该考虑程序的慢速。普通的看门狗在几毫秒内响应,而在这里我们考虑的是几十秒,甚至更长。对于如此长的定时,普通的 555 定时器并不可靠,因为它依赖于电容器充电。而且,我们需要一个相当大的电容器。对于长时序,74HC4060 要简单得多。我将振荡器调整为大约 60Hz 的频率,即使用

  • Rt = 68k
  • Ct = 100n

注意:请参考 74HC4060 规格。

然后,我选择第 10 级(即 Q9)的输出作为“超时信号”,它在大约 10 秒后触发 Netduino 重置。现在,十个二进制级产生 1024 (=2^10) 的频率分频,那么为什么 60 Hz 除以 1024 不是 10 秒,而是 20 秒呢?因为当 Q9 输出变为高电平时,重置立即发生,而这发生在整个时间的一半之后。

那么,Netduino 的作用是什么,害怕被 74HC4060 重置?是的……我们运行在 Netduino 上的程序必须不断地“刷新”计数器,这样它就不会达到 Q9 高电平。基本上,我们需要 Netduino 的任何输出生成一个短暂的正脉冲,它会重置计数器。只要 Netduino 应用程序正常运行,脉冲就会将计数器保持在相对较低的值,而 Q9 永远不会变为高电平。顺便说一句,当程序挂起时,就不再生成重置脉冲,计数器可以运行到 Q9 高电平。该信号将重置 Netduino。

简单的测试程序

下面的程序用作看门狗的测试。它使 LED 闪烁一段时间,然后生成一个异常。这是一个模拟的“bug”,实际上会挂起整个板卡。在这种情况下,您只有两种选择:按“reset”按钮,或拔掉电源再插上。由于这些操作都不适合远程环境,我们将引入一个小“助手”,它会“替我们按下重置按钮”。

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoWatchdog
{
    public class Program
    {
        public static void Main()
        {
            //define the led port
            var led = new OutputPort(Pins.ONBOARD_LED, false);

            //just a long loop to make the led blinking
            for (int i = 0; i < 1000; i++)
            {
                //call the critical section
                Freezer(i);

                //wait for a while, then toggle the led status
                Thread.Sleep(100);
                led.Write(
                    !led.Read()
                    );
            }
        }

        static void Freezer(int count)
        {
            //this is just to simulate an unexpected event
            if (count == 20)
                throw new Exception();

            //keep the dog awaken
            Watchdog();
        }

        //define the watchdog port
        static OutputPort wdt = new OutputPort(Pins.GPIO_PIN_A5, false);

        static void Watchdog()
        {
            //generate a positive pulse to reset the external counter
            wdt.Write(true);
            wdt.Write(false);
        }
    }
}

没有其他代码,因为项目主要侧重于使用 74HC4060 的外部电路。而且很清楚,类似这样的源代码每次都会挂起:在实际环境中没有意义。更现实的应用程序应该更加“防异常”,并且也许能够“自我纠正”某些故障。例如,考虑您的应用程序正在向 SD 卡写入文件,但用户却拔出了卡。编写一个没有异常的防弹过程来写入数据是很困难的。但是,一旦 Netduino 重置,您就可以检查 SD 卡是否存在,并避免任何相关操作。

演示

尽情享受吧!

© . All rights reserved.