Watchdog使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 11/01/2022
    1.1
  • updated according to spec
  • 07/07/2023

    1. 概述

    Hardware watchdog 提供超时复位系统的功能,其功能由定时器和复位功能组成,用户可以设定一个超时时间,并在超时时间以内对它进行“喂狗”的操作,重置其内部计数,如果其内部计算达到了设定的超时时间,watchdog 就会对系统进行复位,重启系统。

    2. Uboot用法介绍

    2.1. CONFIG 配置

    Watchdog 驱动相关的 CONFIG 配置如下:

    [*] SigmaStar drivers  --->
    [*]   Sigmastar watchdog
    

    2.2. DTS 配置

    Watchdog 驱动相关的 DTS 配置如下:

    watchdog: watchdog {
        compatible = "sstar,wdt";
        reg = <0x1F006000 0x40>;
        status = "okay";
    };
    
    • compatible 属性:用于匹配驱动,需要与代码中保持一致,正常情况下不需要修改
    • reg 属性:用于指定Watchdog的寄存器范围,硬件设计决定的,不需要修改
    • status 属性:用于指定是否使能Watchdog驱动,用户可根据实际使用情况选择是否修改

    2.3. wdt 命令使用

    uboot 下使用 wdt 命令操作 watchdog,wdt 命令的使用说明如下:

    wdt - Watchdog sub-system
    
    Usage:
    wdt list - list watchdog devices
    wdt dev [<name>] - get/set current watchdog device
    wdt start <timeout ms> [flags] - start watchdog timer
    wdt stop - stop watchdog timer
    wdt reset - reset watchdog timer
    wdt expire [flags] - expire watchdog timer immediately
    

    2.3.1. wdt list

    wdt list 命令的作用为罗列所有的 watchdog 设备,wdt list 的使用方法为:

    SigmaStar # wdt list
    watchdog (sstar_wdt)
    

    2.3.2. wdt dev

    wdt dev 命令的作用为获取和切换当前操作的 watchdog 设备,wdt dev 命令的命令格式为:

    wdt dev [<name>]
    

    当 wdt dev 命令后不带参数时为获取当前操作的 watchdog 设备名称,当 wdt dev 命令后添加 watchdog 设备的名称时为设置操作切换当前操作的 watchdog 设备,watchdog 设备名称可以通过 wdt list 命令获取,例如:

    SigmaStar # wdt list            # 获取设备名称
    watchdog (sstar_wdt)
    SigmaStar # wdt dev watchdog    # 将当前设备切换为 watchdog (sstar_wdt)
    SigmaStar # wdt dev             # 查看当前设备
    dev: watchdog
    

    2.3.3. wdt start

    wdt start 命令的作用为启动 watchdog 计时,wdt start 命令的命令格式为:

    wdt start <timeout ms> [flags]
    
    • <timeout ms> : 指定 watchdog 的超时时间,单位为毫秒
    • [flags] : 传递给 watchdog 驱动的 flags 信息,当前驱动未使用该参数

    2.3.4. wdt stop

    wdt stop 命令的作用为停止 watchdog 计时,停止 watchdog 计时后 watchdog 不会超时使芯片复位,wdt stop 的使用方法为:

    SigmaStar # wdt dev watchdog
    SigmaStar # wdt start 100000
    SigmaStar # wdt stop
    

    2.3.5. wdt reset

    wdt reset 命令的作用为复位 watchdog 计时,复位 watchdog 的计时后,watchdog 将重新开始计时,在下一个超时时间前为复位或停止 watchdog 将导致芯片复位。wdt reset 的使用方法为:

    SigmaStar # wdt dev watchdog
    SigmaStar # wdt start 100000
    SigmaStar # wdt reset
    

    2.3.6. wdt expire

    wdt expire 命令的作用为立刻触发 watchdog 超时,uboot 原生的实现为将超时设置为 1ms,当前硬件不支持此命令。

    3. Linux 用法介绍

    3.1. CONFIG 配置

    Watchdog 驱动相关的 CONFIG 配置如下:

        Device Drivers  --->
        [*] SStar SoC platform drivers  --->
        <*>   watchdog driver
    

    3.2. DTS 配置

    Watchdog 驱动相关的 DTS 配置如下:

    watchdog0 {
        compatible = "sstar,wdt";
        reg = <0x1F006000 0x40>;
        interrupts=<GIC_SPI INT_FIQ_WDT IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&CLK_wdt>;
        status = "ok";
    };
    
    • compatible 属性:用于匹配驱动,需要与代码中保持一致,正常情况下不需要修改
    • reg 属性:用于指定Watchdog的寄存器范围,硬件设计决定的,不需要修改
    • interrupts 属性:用于指定 Watchdog 使用的硬件中断号,硬件设计决定的,不需要修改
    • clocks 属性:用于指定 Watchdog 使用的时钟,硬件设计决定的,不需要修改
    • status 属性:用于指定是否使能Watchdog驱动,用户可根据实际使用情况选择是否修改

    3.3. 驱动架构

    Watchdog 采用标准的 linux 框架,提供硬件的 watchdog,上层应用可以设定 timeout 时间,自己来 keep alive。

    Watchdog 默认是关闭的,用户可自行决定是否开启。开启建议在主线程中操作,如果在其他线程中操作,watchdog 会随着线程的关闭而关闭

    3.4. 打开 WATCHDOG

    打开 /dev/watchdog 设备,watchdog 将被启动。

    参考代码如下:

    int wdt_fd = -1;
    wdt_fd = open("/dev/watchdog", O_WRONLY);
    if (wdt_fd == -1)
    {
        // fail to open watchdog device
    }
    

    3.5. 关闭 WATCHDOG

    参考代码如下:

    int option = WDIOS_DISABLECARD;
    ioctl(wdt_fd, WDIOC_SETOPTIONS, &option);
    if (wdt_fd != -1)
    {
        close(wdt_fd);
        wdt_fd = -1;
    }
    

    3.6. 设定 TIMEOUT

    通过标准的 IOCTL 命令 WDIOC_SETTIMEOUT,来设定 timeout,单位是 second,timeout 的时间建议大于 5s,参考代码如下:

    #define WATCHDOG_IOCTL_BASE    'W'
    #define WDIOC_SETTIMEOUT       _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
    int timeout = 20;
    ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);
    

    3.7. KEEP ALIVE

    通过标准的 IOCTL 命令 WDIOC_KEEPALIVE 来喂狗,喂狗时间按照设定的 timeout 来决定,喂狗时间应该比 timeout 小,参考代码如下:

    #define WATCHDOG_IOCTL_BASE    'W'
    #define WDIOC_KEEPALIVE        _IOR(WATCHDOG_IOCTL_BASE, 5, int)
    ioctl(wdt_fd, WDIOC_KEEPALIVE, 0);