uboot-驱动开发-dwwatchdog
- 互联网
- 2025-08-13 08:33:01

说明 公司SOC使用的watchdog模块是新思(Synopsys)的IP。 需求 用户有时会在uboot/kernel中做些开发,新增一些功能(OTA升级等),可能会出现uboot/kernel启动崩溃甚至设备死机等问题,需要在uboot启动阶段开启watchdog监控设备运行实现异常后复位。 实现 前提:dts watchdog节点配置ok。由于历史原因,根据是否支持DM(Driver model),uboot原生支持两种wdt驱动和使用的配置/实现方式。 不支持DM,常见于较早版本(uboot,wdt驱动)实现 核心配置项:CONFIG_HW_WATCHDOG 支持DM 核心配置项:CONFIG_WDT // file: drivers/watchdog/Kconfig config WDT bool "Enable driver model for watchdog timer drivers" depends on DM .... 不支持DM 配置项 核心配置 CONFIG_HW_WATCHDOG wdt timeout时间 CONFIG_WATCHDOG_TIMEOUT_MSECS 具体型号的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 ... 驱动代码 定义并实现驱动相关功能接口 //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) { .... } 定义实现对外接口 //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中使用 头文件(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 由于不支持DM,wdt-uclass.c(DM接口)未使用。 验证 这种方式,整体上执行流程比较固定,uboot启动wdt就会自动运行,支持配置项较少,验证方法只能代码调试。由于不支持DM,这种模式,不支持wdt cmd。 支持DM 配置项 核心配置 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 ... 自动启动配置(可选配置) CONFIG_WATCHDOG_AUTOSTART=y // 自动启动 CONFIG_WATCHDOG_TIMEOUT_MSECS //wdt timeout时间, 默认60s 具体型号的wdt,例如:dw wdt。 CONFIG_DESIGNWARE_WATCHDOG 驱动代码 按照DM模型,实现probe等相关接口实现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中使用 wdt cmd使用的是wdt-uclass.c中的统一接口,wdt-uclass.c中的函数再调用具体驱动的接口。头文件(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 */ 验证 使用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,不同的是宏指向的函数。 不支持DM,WATCHDOG_RESET指向的是wdt驱动中hw_watchdog_reset函数。支持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喂狗。
uboot-驱动开发-dwwatchdog由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“uboot-驱动开发-dwwatchdog”