AI嵌入式K210项目(10)-看门狗

发布时间:2024年01月17日


前言

本章我们来学习下看门狗(watchdog),看门狗是一种形象的说法,他是一种用于监测单片机程序运行状态的芯片,由于单片机的工作常常会受到来自外界电磁场的干扰,造成各种寄存器和内存的数据混乱,导致程序指针错误、取出错误的程序指令等,都有可能会陷入死循环,程序的正常运行被打断,导致整个系统的陷入停滞状态,发生不可预料的后果。有了看门狗之后就会对系统进行复位;


一、看门狗是什么?

看门狗其实就是一个需要在设定一定时间内被复位的计数器,如果没有按时复位,则会强制系统复位。在看门狗启动前需要配置超时时间,当看门狗启动后,计数器开始自动计数,经过一定时间,如果没有被复位,计数器溢出就会对CPU产生一个复位信号使系统重启(俗称“被狗咬”)。要保证系统正常运行时,需要在看门狗超时时间内重置看门狗计数器(俗称“喂狗”)。
之前讲STM32时候也有过介绍,详细了解的话可以参考:STM32开发(11)----CubeMX配置独立看门狗(IWDG) STM32开发(12)----CubeMX配置WWDG

二、K210的看门狗

WDT是外围总线(APB)的一种从外设,并且也是“同步化硬件组件设计”的组成部分,具有两个WDT,分别为WDT0和WDT1看门狗定时器,主要包含的模块有一个APB从接口,一个当前计数器同步的寄存器模块,一个随着计数器递减的中断/系统重置模块和逻辑控制电路,一个同步时钟域来为异步时钟同步做支持。

看门狗定时器支持如下设置:

? APB 总线宽度可配置为8、16 和32 位

? 时钟计数器从某一个设定的值递减到0 来指示时间的计时终止

? 可选择的外部时钟使能信号,用于控制计数器的计数速率

? 一个时钟超时WDT 可以执行以下任务:

– 产生一个系统复位信号

– 首先产生一个中断,即使该位是否已经被中断服务清除,其次它会产生一个系统复位信号

? 占空比可编程调节

? 可编程和硬件设定计数器起始值

? 计数器重新计时保护

? 暂停模式,仅当使能外部暂停信号时

? WDT 偶然禁用保护

? 测试模式,用来进行计数器功能测试(递减操作)

? 外部异步时钟支持。当该项功能启用时,将会产生时钟中断和系统重置信号,即使APB 总线时钟关闭的情况下。

4.SDK中对应API功能

板级对应的头文件wdt.h

WDT看门狗在开发单片机中作用巨大,可以在程序出现死机的情况自动重启系统,而不需要手动操作。

为用户提供以下接口:

? wdt_init:配置看门狗参数,启动看门狗,不使用中断的话,将on_irq设置为NULL。返回值为看门狗实际超时时间,一般比设置的时间稍微大一些。

? wdt_start(0.6.0 后不再支持,请使用wdt_init)

? wdt_stop:关闭看门狗。

? wdt_feed:重置看门狗计时器,俗称喂狗。

? wdt_clear_interrupt:清除中断,如果在中断函数中清除中断,看门狗不会重启。

三、实验过程

本实验实现一个喂狗的过程,前面我们先在超时时间内进行喂狗,这样不会触发看门狗的中断处理函数,后面我们停止喂狗,触发我们定义的看门狗中断处理函数。

新建wdt文件夹,在文件夹下新建main.c文件
代码如下(示例):

#include <stdio.h>
#include <unistd.h>
#include "wdt.h"
#include "sysctl.h"

#define WDT_TIMEOUT_REBOOT    1
/**
* Function       wdt0_irq_cb
* @brief         看门狗中断回调
* @param[in]     void
* @param[out]    void
* @retval        0
* @par History   无
*/
int wdt0_irq_cb(void *ctx)
{
    #if WDT_TIMEOUT_REBOOT     //这种情况下系统会重启
    printf("%s:The system will reboot soon!\n", __func__);
    while(1);
    #else         //这种情况下系统不重启,重置WDT状态
    printf("%s:The system is busy but not reboot!\n", __func__);
    wdt_clear_interrupt(WDT_DEVICE_0);
    #endif
    return 0;
}

/**
* Function       main
* @brief         主函数,程序的入口
* @param[in]     void
* @param[out]    void
* @retval        0
* @par History   无
*/
int main(void)
{
    /* 打印系统启动信息 */
    printf("system start!\n");
    /* 记录feed的次数 */
    int times = 0;

    /* 系统中断初始化 */
    plic_init();
    sysctl_enable_irq();

    /* 启动看门狗,设置超时时间为2秒后调用中断函数wdt0_irq_cb */
    int timeout = wdt_init(WDT_DEVICE_0, 2000, wdt0_irq_cb, NULL);

    /* 打印看门狗实际超时的时间 */
    printf("wdt timeout is %d ms!\n", timeout);
    
    while(1)
    {
        sleep(1);
        if(times++ < 10)
        {
            /* 打印feed的次数 */
            printf("wdt_feed %d times!\n", times);

            /* 重置看门狗的计时器,重新开始计时 */
            wdt_feed(WDT_DEVICE_0);
        }
    }
}

代码写好后,我们开始编译,注意:如果你编译过程中出现错误,可以先make clean掉之前生成的过程文件,重新生成

cd build
//注意这里的目标文件目录改成gpio,和刚才新建的文件夹名称一致
cmake .. -DPROJ=wdt  -G "MinGW Makefiles"
make

编译完成后,在build文件夹下会生成wdt.bin文件。

使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。
在这里插入图片描述
然后我们一起来看下实验现象,在停止喂狗之后,系统重启
在这里插入图片描述


总结

看门狗的作用是当没有在设定的时间内喂狗,则系统会发送中断使系统强制重启,看门狗必须在系统正常运行的情况下喂狗,这样系统异常时就能够及时重启系统,看门狗的定时中断是实际超时时间的一半,需要在这个时间内喂狗。

文章来源:https://blog.csdn.net/bin_zhang1/article/details/135649974
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。