跳转至

watchdog开发指南

本文档以 watchdog_demo 为例,带你在 HiDiTing 开发板上快速跑通第一个 watchdog(看门狗)监控应用,并了解如何基于它构建自己的应用。


watchdog 驱动背景知识

watchdog 工作原理

watchdog 是一种监控机制,用于检测系统是否出现死锁或异常状态。其工作原理:

  1. 系统定期"喂狗"(kick)
  2. 如果超时未喂狗,watchdog 会触发复位或回调函数
  3. 通过回调函数可以记录错误信息或执行恢复操作

工作模式

watchdog 支持以下工作模式:

模式 特点 适用场景
复位模式 超时触发系统复位 关键系统监控
中断模式 超时触发中断回调,未在中断回调中"喂狗"才会复位 需要记录错误信息的场景

配置参数

基本配置参数包括:

  • 超时时间(timeout)
  • 工作模式(reset/interrupt)
  • 喂狗周期(kick interval)

API 接口列表

本文档示例代码中使用的接口:

接口函数 说明
uapi_watchdog_init 初始化看门狗
uapi_watchdog_deinit 去初始化看门狗
uapi_watchdog_enable 使能看门狗
uapi_watchdog_kick 喂狗

完整 API 列表

更多 Watchdog 接口请参考:Watchdog API 参考


快速跑通 watchdog_demo

功能说明

WatchDog Demo 通过 AT 命令方式提供交互式控制,可以通过执行下面的 AT 指令实现看门狗的功能。

AT+WDINIT=1(参数`0`不喂狗 `1`喂狗) // 注意:传0表示不喂狗,8s后开发板会重启

编译

完成一站式 CLI 环境配置后执行:

# 编译固件,编译生成的固件从 output/3322/fwpkgt 中获取 diting-community.fwpkg
fbb set-target pack_diting_community
fbb build

构建成功后,使用一站式 CLI 烧写固件并打开 UART2 串口监视器。以下为 Windows USB DFU 示例;将 COM3 替换为实际日志串口,其他平台和串口烧写参数参见一站式 CLI 开发环境使用指南

fbb flash -f "$env:FBB_SDK_DIR\output\3322\fwpkg\diting-community.fwpkg" --chip 3322 -d --timeout 180
fbb monitor --port COM3 --baud 750000

使用方式

  1. 烧录固件并启动设备
  2. 通过串口发送 AT 命令,格式如下:

    # 启动看门狗功能(初始化、使能看门狗,以及注册相应回调函数)
    AT+WDINIT=1
    

通过串口发送 AT 命令,格式如下

预期结果

定期喂狗

**定期喂狗**

选择不喂狗

**选择不喂狗**


文件结构与代码走读

文件职责

文件 作用
samples/native_samples/watchdog/CMakeLists.txt 定义 watchdog_sample 组件及依赖。
samples/native_samples/watchdog/watchdog_demo.h 定义串口测试参数和命令表。
samples/native_samples/watchdog/watchdog_demo.c 实现看门狗任务、超时回调、周期喂狗和异常路径。
samples/native_samples/watchdog/README.md 给出完整命令和预期日志。

核心参数与常量

名称 作用 开发注意事项
TIME_OUT 看门狗超时时间,当前 Sample 为 8 秒。 必须大于正常业务最坏执行时间并留出调度余量。
WDT_TASK_DURATION_MS 正常场景的喂狗周期,当前为 5 秒。 喂狗周期必须稳定小于超时时间。
WDT_MODE 选择复位或中断模式。 产品容错策略应明确最终是否允许自动复位。
wd_init_args_t.kick_flag 选择持续喂狗或故意等待超时。 该结构是 AT 测试参数,自定义应用不应让外部输入任意切换量产策略。
WDT_TASK_PRIO / WDT_TASK_STACK_SIZE 配置 Sample 任务资源。 按产品任务模型评估优先级和栈余量。

核心业务流程

  1. 在独立业务任务中调用 uapi_watchdog_init(),随后调用 uapi_watchdog_enable() 并注册超时回调。
  2. 正常场景按固定周期调用 uapi_watchdog_kick();周期必须覆盖系统最坏调度延迟且小于超时时间。
  3. 故障验证场景停止喂狗,观察中断回调或系统复位是否符合 WDT_MODE 配置。
  4. 可退出的测试路径应调用 uapi_watchdog_deinit();量产常驻看门狗需在系统架构中明确启动时机和异常恢复策略。

AT 命令只用于选择测试分支和创建 Sample 任务。完整线程、日志和超时实现见源文件;下一节保留面向应用的 app_run 组织方式,不重复 AT 代码。

基于 watchdog_demo 开发自己的应用

上面的demo是使用AT指令触发运行,HiDiTing还支持app_run方式触发应用在系统启动时自动运行,以下示例将以app_run的方式开发一个开发者自己的应用

  • app_run(func) 是HiDiTing中应用层注册应用函数的宏,基于 GCC 编译器属性和自定义段区(section)自动注册来实现集中调用应用函数,系统启动时会自动遍历所有用 app_run 注册过的函数并执行,无需在 系统 main 函数里逐个调用函数。

代码清单

新建一个 watchdog 应用(以 my_watchdog_demo 为例)通常只需要以下改动:

  • 新建 my_watchdog_demo.c 源文件
  • 新建 my_watchdog_demo.h 头文件
  • 新建 CMakeLists.txt 源文件
  • my_watchdog_demo.c 中实现看门狗的初始化,使能和回调函数的注册,以及循环喂狗操作
  • my_watchdog_demo.h 中实现看门配置的声明
  • CMakeLists.txt 中添加源文件编译规则

my_watchdog_demo文件结构:

/samples/native_samples/my_watchdog_demo/
├── my_watchdog_demo.c
├── my_watchdog_demo.h
└── CMakeLists.txt

CMakeLists.txt 修改示例

# 在新建的 CMakeLists.txt 中添加应用的源文件
set(SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/my_watchdog_demo.c
)

set(PUBLIC_HEADER
    ${CMAKE_CURRENT_SOURCE_DIR}
)

set(PRIVATE_HEADER

)

set(PUBLIC_DEFINES
    MY_WATCHDOG_DEMO_ENABLE
)

build_component()

关键代码片段

my_watchdog_app.c —— watchdog 监控

#include "watchdog.h"
#include "app_init.h"
#include "common_def.h"

#define MY_WATCHDOG_TIMEOUT     2
#define KICK_INTERVAL_MS        500

static errcode_t my_watchdog_callback(uintptr_t param)
{
    UNUSED(param);
    osal_printk("watchdog timeout detected!\r\n");
    return ERRCODE_SUCC;
}

void my_watchdog_entry(void)
{
    osal_printk("my_watchdog_app start\n");

    // step1:初始化 watchdog
    errcode_t ret = uapi_watchdog_init(MY_WATCHDOG_TIMEOUT);
    if (ret != ERRCODE_SUCC) {
        osal_printk("watchdog init failed\n");
        return;
    }

    // step2:启用 watchdog 并注册回调
    uapi_watchdog_enable(WDT_MODE_INTERRUPT);
    uapi_register_watchdog_callback(my_watchdog_callback);

    // step3:主循环
    while (1) {
        osal_msleep(KICK_INTERVAL_MS);
        uapi_watchdog_kick();
        osal_printk("Kick watchdog\n");
    }
}

app_run(my_watchdog_entry);

app_run运行配置

app_run应用默认是关闭的,如需启用此应用,需用户手动在acore.prelds文件中添加 KEEP (*(SORT(.zinitcall.app_run*.init))) 具体参考示意图如下:

apprun运行配置

acore.prelds


测试验证

新demo完成后,逐项验收:

  • 设备启动后串口输出 my_watchdog_app start
  • 每隔 500ms 输出一次喂狗成功的日志
  • 若停止喂狗,会触发回调输出超时信息

注意事项

超时时间注意事项:

  • 超时时间不宜过短,否则可能误触发
  • 超时时间不宜过长,否则故障检测不及时

工作模式注意事项:

  • 复位模式适合关键系统,中断模式适合需要记录错误信息的场景
  • 中断模式需要正确实现回调函数

资源说明:

  • watchdog 通常为硬件模块,无需额外资源分配

常见错误

错误现象 原因 解决方法
undefined reference to 'uapi_watchdog_init' 未链接 watchdog 驱动库 检查 CMakeLists.txt 中是否正确添加了源文件
undefined reference to 'uapi_at_cmd_table_register' 未链接 AT 命令库 检查 CMakeLists.txt 中是否正确添加了 AT 相关头文件路径
编译报 at_ret_t 未定义 未包含 at.h 头文件 添加 #include "at.h"
串口无输出 AT 命令未注册 确认调用了 at_diting_watchdog_example_cmd_register()
watchdog 不触发 超时时间设置过长或未正确初始化 检查超时时间设置和初始化代码
中断回调不触发 未正确注册回调函数 检查 uapi_register_watchdog_callback 调用
watchdog 复位频繁 喂狗周期过长或未喂狗 调整喂狗周期或确保及时喂狗