uboot - 驱动开发 - dw watchdog

说明

  • 公司SOC使用的watchdog模块是新思(Synopsys)的IP。

需求

  • 用户有时会在uboot/kernel中做些开发,新增一些功能(OTA升级等),可能会出现uboot/kernel启动崩溃甚至设备死机等问题,需要在uboot启动阶段开启watchdog监控设备运行实现异常后复位。

实现

  • 前提:dts watchdog节点配置ok。
  • 由于历史原因,根据是否支持DM(Driver model),uboot原生支持两种wdt驱动和使用的配置/实现方式。
  1. 不支持DM,常见于较早版本(uboot,wdt驱动)实现

    核心配置项:CONFIG_HW_WATCHDOG

  2. 支持DM

    核心配置项:CONFIG_WDT

    // file: drivers/watchdog/Kconfig
    config WDT
    bool "Enable driver model for watchdog timer drivers"
    depends on DM
    ....

不支持DM

配置项

  1. 核心配置

    CONFIG_HW_WATCHDOG

  2. wdt timeout时间

    CONFIG_WATCHDOG_TIMEOUT_MSECS

  3. 具体型号的wdt,例如:dw wdt。

    CONFIG_DESIGNWARE_WATCHDOG

  • 如果未配置支持DM(CONFIG_WDT),但是配置了硬件wdt,CONFIG_HW_WATCHDOG会自动选上,例如:

    config DESIGNWARE_WATCHDOG
    bool "Designware watchdog timer support"
    select HW_WATCHDOG if !WDT
    ...

驱动代码

  1. 定义并实现驱动相关功能接口

    //file: drivers/watchdog/designware_wdt.c
    static int designware_wdt_settimeout(unsigned int timeout)
    {
    ....
    }

    static void designware_wdt_enable(void)
    {
    ....
    }

    static void designware_wdt_disable(void)
    {
    ....
    }

    static unsigned int designware_wdt_is_enabled(void)
    {
    ....
    }

  2. 定义实现对外接口

    //file: drivers/watchdog/designware_wdt.c
    #if defined(CONFIG_HW_WATCHDOG)
    void hw_watchdog_reset(void)
    {
    ...
    }

    void hw_watchdog_init(void)
    {
    // 初始化wdt,并enable
    ...
    }

    void hw_watchdog_disable(void)
    {
    ...
    }
    #endif

uboot中使用

  1. 头文件(watchdog.h)中会定义统一的宏(WATCHDOG_RESET、WATCHDOG_DISABLE)指向驱动文件中实现的hw对外接口,具体使用后面统一说明。

    // file: include/watchdog.h
    #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
    #define INIT_FUNC_WATCHDOG_INIT init_func_watchdog_init,
    #define INIT_FUNC_WATCHDOG_RESET init_func_watchdog_reset,
    #else
    #define INIT_FUNC_WATCHDOG_INIT
    #define INIT_FUNC_WATCHDOG_RESET
    #endif

    #ifdef CONFIG_HW_WATCHDOG
    #if defined(ASSEMBLY)
    #define WATCHDOG_RESET bl hw_watchdog_reset
    #else
    extern void hw_watchdog_reset(void);
    extern void hw_watchdog_disable(void);

         #define WATCHDOG_RESET hw_watchdog_reset
         #define WATCHDOG_DISABLE hw_watchdog_disable
     #endif /* __ASSEMBLY__ */
    

    #else
    ....
    #endif

  2. 由于不支持DM,wdt-uclass.c(DM接口)未使用。

验证

  • 这种方式,整体上执行流程比较固定,uboot启动wdt就会自动运行,支持配置项较少,验证方法只能代码调试。
  • 由于不支持DM,这种模式,不支持wdt cmd。

支持DM

配置项

  1. 核心配置

    CONFIG_WDT
    CONFIG_WATCHDOG // enable uboot内部使用的喂狗接口,该方式下必需enable

  • 配置CONFIG_WDT后会自动开启CONFIG_WATCHDOG, 如下:

    // file: drivers/watchdog/Kconfig
    config WDT
    bool "Enable driver model for watchdog timer drivers"
    depends on DM
    imply WATCHDOG
    ...

  1. 自动启动配置(可选配置)

    CONFIG_WATCHDOG_AUTOSTART=y // 自动启动
    CONFIG_WATCHDOG_TIMEOUT_MSECS //wdt timeout时间, 默认60s

  2. 具体型号的wdt,例如:dw wdt。

    CONFIG_DESIGNWARE_WATCHDOG

驱动代码

  1. 按照DM模型,实现probe等相关接口

  2. 实现DM定义的 wdt 操作接口

    //file: include/wdt.h
    struct wdt_ops {
    int (*start)(struct udevice *dev, u64 timeout_ms, ulong flags);
    int (*stop)(struct udevice *dev);
    int (*reset)(struct udevice *dev);
    int (*expire_now)(struct udevice *dev, ulong flags);
    }

uboot中使用

  1. wdt cmd使用的是wdt-uclass.c中的统一接口,wdt-uclass.c中的函数再调用具体驱动的接口。

  2. 头文件(watchdog.h)中会定义统一的宏(WATCHDOG_RESET)指向wdt-uclass.c中实现的对外喂狗接口,具体使用后面统一说明。

    // file: include/watchdog.h
    #ifdef CONFIG_HW_WATCHDOG
    ...
    #else
    /*
    * Maybe a software watchdog?
    /
    #if defined(CONFIG_WATCHDOG)
    #if defined(ASSEMBLY)
    #define WATCHDOG_RESET bl watchdog_reset
    #else
    /
    Don't require the watchdog to be enabled in SPL */
    #if defined(CONFIG_SPL_BUILD) &&
    !defined(CONFIG_SPL_WATCHDOG)
    #define WATCHDOG_RESET() {}
    #else
    extern void watchdog_reset(void);

                             #define WATCHDOG_RESET watchdog_reset
                     #endif
             #endif
     #else
             /*
              * No hardware or software watchdog.
              */
             #if defined(__ASSEMBLY__)
                     #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/
             #else
                     #define WATCHDOG_RESET() {}
             #endif /* __ASSEMBLY__ */
     #endif /* CONFIG_WATCHDOG && !__ASSEMBLY__ */
    

    #endif /* CONFIG_HW_WATCHDOG */

验证

  1. 使用cli命令验证
  • enable wdt命令(cmdline)

    CONFIG_CMD_WDT=y // wdt cmd

  • 运行效果

    uboot# 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

    uboot# wdt list
    dw-wd@0x27000000 (designware_wdt) // dts配置
    uboot# wdt dev dw-wd@0x27000000
    uboot# wdt start 30000

uboot中使用

  • 两种配置(是否支持DM)方式,uboot中都是使用统一的宏(WATCHDOG_RESET等)去操作wdt,不同的是宏指向的函数。
  1. 不支持DM,WATCHDOG_RESET指向的是wdt驱动中hw_watchdog_reset函数。
  2. 支持DM,WATCHDOG_RESET指向的是wdt-uclass.c中watchdog_reset函数。
  • uboot初始化时会主动调用INIT_FUNC_WATCHDOG_INIT初始化wdt,不支持DM配置(CONFIG_HW_WATCHDOG),wdt初始化时会直接enable wdt。

    //file: common/board_f.c
    #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
    static int init_func_watchdog_init(void)
    {

    if defined(CONFIG_HW_WATCHDOG) && \

      (defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \
      defined(CONFIG_SH) || \
      defined(CONFIG_DESIGNWARE_WATCHDOG) || \
      defined(CONFIG_IMX_WATCHDOG))
      hw_watchdog_init(); //该函数,默认实现会配置好wdt,并enable
      puts("       Watchdog enabled\n");
    

    endif

      WATCHDOG_RESET();
    
      return 0;
    

    }

    int init_func_watchdog_reset(void)
    {
    WATCHDOG_RESET();

          return 0;
    

    }
    #endif /* CONFIG_WATCHDOG */

  • uboot是裸机程序,所有操作都是顺序执行,开启wdt后,如有耗时操作需要自己调用WATCHDOG_RESET进行喂狗,进到cli时,uboot cli会间隔调用WATCHDOG_RESET喂狗。

相关推荐
gopher951116 小时前
linux驱动开发-中断子系统
linux·运维·驱动开发
gopher95112 天前
linux驱动开发-设备树
linux·驱动开发
三菱-Liu2 天前
三菱变频器以模拟量电流进行频率设定(电流输入)
驱动开发·单片机·嵌入式硬件·硬件工程·制造
三菱-Liu3 天前
三菱FX5U CPU 内置以太网功能
网络·驱动开发·硬件工程·制造·mr
让开,我要吃人了3 天前
OpenHarmony鸿蒙( Beta5.0)摄像头实践开发详解
驱动开发·华为·移动开发·harmonyos·鸿蒙·鸿蒙系统·openharmony
OH五星上将3 天前
如何更换OpenHarmony SDK API 10
驱动开发·嵌入式硬件·sdk·harmonyos·openharmony·鸿蒙开发
OH五星上将5 天前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(二)Linux内核
linux·驱动开发·嵌入式硬件·移动开发·harmonyos·鸿蒙开发·鸿蒙内核
芊言芊语5 天前
蓝牙驱动开发详解
驱动开发
让开,我要吃人了5 天前
OpenHarmony鸿蒙( Beta5.0)RTSPServer实现播放视频详解
驱动开发·嵌入式硬件·华为·移动开发·harmonyos·鸿蒙·openharmony
OH五星上将6 天前
OpenHarmony(鸿蒙南向开发)——轻量和小型系统三方库移植指南(二)
驱动开发·移动开发·harmonyos·内存管理·openharmony·鸿蒙内核·鸿蒙移植