跳到主要内容

看门狗实验

前言

本章,我们将学习看门狗,基于定时器功能,教大家如何用定时器模拟看门狗功能。

看门狗简介

MCU可能工作在一些复杂环境,可能受到某些电磁干扰出现程序跑飞,导致死循环无法继续执行工作,看门狗的作用就是为了避免这种情况。看门狗的本质也是一个定时器,在程序启动后,需要在一定的时间内再给它一个信号,俗称“喂狗”。如果没有按时“喂狗”,说明系统或软件出现了不可预知的问题(比如软件卡在某个循环或逾期事件中),这时看门狗就向系统发送个复位信号,使整个系统重启,重新进入正常的工作状态。看门狗有助于检测、处理系统或软件的错误行为。

在RP2350上,看门狗从系统级滴答块中获取滴答输入。与RP2040一样,看门狗可以触发PSM(开机状态机)序列来重置系统组件,也可以用于重置选定的子系统组件。在RP2350上,看门狗还可以触发芯片电平重置。

硬件设计

例程功能

  1. 程序运行后,如果不断按下KEY1按键进行喂狗,那么就不会触发看门狗,LED也就保持常亮,一旦超过定时器的溢出时间(1000毫秒),没有按下KEY1按键进行喂狗,那么LED也就由亮变暗,且一直保持该状态,直到重新复位。

硬件资源

  1. LED: LED-GPIO3
  2. 按键: KEY1-GPIO2
  3. 看门狗

原理图

本章实验使用的定时器为RP2350A的片上资源,因此并没有相应的连接原理图。

程序设计

WATCH_DOG函数解析

使能看门狗函数

该函数用于启用看门狗(Watchdog)功能,并设置看门狗的计时器和调试模式下的行为。其函数原型如下所示:

void watchdog_enable(uint32_t delay_ms, bool pause_on_debug)

【参数】

delay_ms:看门狗的计时器时间,单位为毫秒。设置看门狗的倒计时时间,超时后会触发复位

  1. ture:调试模式下暂停看门狗计时器
  2. false:调试模式下继续运行看门狗计时器

【返回值】

“喂狗”函数

该函数用于更新看门狗(Watchdog)的计时器,通常称为“喂狗”操作。通过重新加载看门狗的计时器值,防止看门狗超时触发系统复位。其函数原型如下所示:

void watchdog_update(void)

【参数】

watchdog_hw->load = load_value;

将 load_value 写入看门狗硬件寄存器的 load 字段

load_value 是看门狗计时器的初始值,通常与看门狗的启用时间一致

【返回值】

WATCH_DOG驱动解析

在SDK版本的07_wdt例程中,作者在07_wdt\BSP路径下新增了一个WDT文件夹,用于存放wdt.c和wdt.h这两个文件。其中,wdt.h文件负责声明WDT相关的函数和变量,而wdt.c文件则实现了WDT的驱动代码。下面,我们将详细解析这两个文件的实现内容。

1,wdt.h文件

/* 函数声明 */
void wdt_init(uint32_t tps);/* 初始化独立看门狗 */

2,wdt.c文件

/**
* @brief 初始化任务看门狗计时器
* @param tps: 定时器周期
*/
void wdt_init(uint32_t tps)
{
watchdog_enable(tps, true);
}

这段代码是一个简单的看门狗(Watchdog)初始化函数,用于启用看门狗并设置其计时器。其代码逻辑为:调用 watchdog_enable()函数, 启用看门狗,并设置计时器时间为 tps。第二个参数 true 表示在调试模式下暂停看门狗计时器。

CMakeLists.txt文件

打开本章节的实验(07_wdt),在整个工程文件下包含了一个CMakeLists.txt文件。关于该实验的CMakeLists.txt文件的具体内容与上一章节并没有什么太大的不同,因此不再赘述。

实验应用代码

打开main.c文件,该文件定义了工程入口函数,名为main。该函数代码如下。

/**
* @brief 程序入口
* @param 无
* @retval 无
*/
int main()
{
uint8_t key;

stdio_init_all(); /* 初始化标准库 */
led_init(); /* 初始化LED */
key_init(); /* 初始化KEY */
wdt_init(1000); /* 初始化看门狗定时器 */
LED(0); /* LED灯常亮 */

while (1)
{
if (key_scan(0) == KEY1_PRES) /* 如果KEY1按下则喂狗 */
{
watchdog_update(); /* 喂狗 */
}

sleep_ms(10); /* 延时10ms */
}
}

可以看到应用代码中,LED初始化后,LED会处于常亮状态,随后初始化Watchdog定时器溢出过程,会看见LED在不停的闪烁。接着在while循环中重复判断KEY1按键是否被按下,若按下则进行“喂狗”操作,若在WDT溢出前都为按下KEY1按键,那么就不会产生复位,LED也就保持常亮。

下载验证

在完成编译和烧录操作后,可以看到板子上的LED在不停的闪烁,这是因为Watchdog对芯片进行复位。接下来若以时间间隔小于1秒(大约)的速度频繁地按下KEY1按键,则可以在芯片复位前及时“喂狗”,具体的现象为LED常亮。