Watch Dog Timer
该示例通过 GPIO 中断触发喂狗操作重启看门狗定时器 WDT 。
当 GPIO 检测到下降沿输入时,会触发 GPIO 中断,在中断函数内进行喂狗操作,重启看门狗定时器。
若在 WDT 设定时间内未进行喂狗操作,WDT 将进行 Reset 操作。
用户可以通过不同的宏配置改变示例中 WDT 的配置,GPIO 引脚配置等信息,具体宏配置详见 配置选项。
环境需求
该示例的环境需求,可参考 环境需求。
硬件连线
连接 P4_0 和外部输入信号。
配置选项
可配置如下宏选择使用 CORE WDT 或 AON WDT。
#define USE_WDT 1 #define USE_AON_WDT 0 #define USE_WDT_SELECT USE_WDT /*< Set this macro to select CORE WDT or AON WDT. */
可配置如下宏修改引脚定义。
#define INPUT_PIN P4_0 /*< Set this macro to modify GPIO Pin. */ #define GPIO_PIN_IRQN GPIOB5_IRQn #define GPIO_Pin_Handler GPIOB5_Handler
编译和下载
该示例的编译和下载流程,可参考 编译和下载。
测试验证
当 EVB 启动后,在 Debug Analyzer 工具内观察如下 log。
Start wdt test!
看门狗定时时间为 10 秒。若在 10 秒内控制外部输入信号从高电平变为低电平,则触发 GPIO 中断并进行喂狗操作,打印 log。
[APP] !**[app] app_handle_io_msg: feeding dog, restart wdg timer.
若在 10 秒内没有进行喂狗操作,则 IC 会自动 Reset。
代码介绍
该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明。
源码路径
工程文件和源码路径如下:
工程路径:
sdk\samples\peripheral\wdt\wdt\proj
源码路径:
sdk\samples\peripheral\wdt\wdt\src
初始化
外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。
主函数中调用
os_sched_start
,开启任务调度。在app_main_task
中,创建消息队列,调用driver_init
,对 GPIO 和 WDT 外设进行初始化。void app_main_task(void *p_param) { ... os_msg_queue_create(&io_queue_handle, "io queue", MAX_NUMBER_OF_IO_MESSAGE, sizeof(uint32_t)); os_msg_queue_create(&evt_queue_handle, "evt queue", MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint32_t)); driver_init(); while (true) ... } void driver_init(void) { driver_gpio_init(); driver_wdt_init(); }
GPIO 外设的初始化具体详见 GPIO Input Interrupt 中的 GPIO 初始化 。
对 WDT 外设进行初始化:
若配置宏
USE_WDT_SELECT
为USE_WDT
,调用WDT_Start()
函数,开启 WDT 功能,设置定时时间为 10 秒,超时未喂狗时 EVBRESET_ALL
。若配置宏
USE_WDT_SELECT
为USE_AON_WDT
,调用AON_WDT_Start()
函数,开启 AON WDT 功能,设置定时时间为 10 秒,超时未喂狗时 EVBRESET_ALL
。
void driver_wdt_init(void) { /* WDT timing 10s. */ #if USE_WDT_SELECT WDT_Start(10000, RESET_ALL); #else AON_WDT_Start(AON_WDT, 10000, RESET_ALL); #endif }
功能实现
在开启 WDT 功能后,系统会进行 10 秒定时。
在定时时间内,当 P4_0 检测到外部有下降沿信号输入时,会触发 GPIO 中断,在中断处理函数内,会发送
IO_MSG_TYPE_GPIO
类型的消息,在消息处理函数内调用WDT_Kick()
或AON_WDT_Kick()
进行喂狗操作以重启看门狗定时器。void GPIO_Pin_Handler(void) { /* Mask and disable interrupt */ ... uint32_t send_val = IO_MSG_TYPE_GPIO; if (false == app_send_msg_to_apptask(&send_val)) { APP_PRINT_ERROR0("[io_gpio] GPIO_Input_Handler: Send int_gpio_msg failed!"); //Add user code here! GPIO_ClearINTPendingBit(GPIO_PORT, GPIO_PIN); return; } /* Clear int flag, unmask and enable interrupt */ ... } void app_handle_io_msg(uint32_t io_msg) { switch (io_msg) { case IO_MSG_TYPE_GPIO: { APP_PRINT_INFO0("[app] app_handle_io_msg: feeding dog, restart wdg timer."); wdt_feed(); } break; default: break; } } void wdt_feed(void) { #if USE_WDT_SELECT WDT_Kick(); #else AON_WDT_Kick(AON_WDT); #endif }
若在定时时间内 P4_0 没有检测到外部下降沿信号输入,即没有进行喂狗操作时,系统会进行复位操作。