一、说明: 看门狗,又叫watchdog
timer,主要用来监控、管理CPU的运行状态,并对处于异常状态中的CPU进行复位操作,使其能重新工作。 看门狗可分为硬件看门狗和软件看门狗两种。 这里使用硬件看门狗:电路图如下:
这个硬件设计,在开机后,系统需要全程喂狗, 喂狗操作:WDI(Watchdog Input)的电平信号超过1.6S不发生跳变时,就会让系统重启,所以只需让WDI在每个1.6s内遇到一个上升沿或者下降沿即可。 其他更详细的内容请自己在网上查找。
二、uboot代码修改
1、
在include/watchdog.h文件中有宏定义
#ifdef CONFIG_HW_WATCHDOG
#if defined(__ASSEMBLY__)
#define WATCHDOG_RESET bl hw_watchdog_reset
#else
extern void hw_watchdog_reset(void);
#define WATCHDOG_RESET hw_watchdog_reset
#endif
所以,需要打开CONFIG_HW_WATCHDOG开关以及实现hw_watchdog_reset喂狗函数。
2、
在板级头文件中include/configs/am335x_evm.h文件中加上宏定义
#define CONFIG_HW_WATCHDOG 1
#define GPIO_WATCHDOG 23
然后在板级文件board/ti/am335x/evm.c中加入喂狗函数hw_watchdog_reset #ifdef CONFIG_HW_WATCHDOG #include void gpio0_23_watchdog(void) { enable_gpio0_23_pin_mux(); gpio_request(GPIO_WATCHDOG, "gpio_watchdog"); gpio_direction_output(GPIO_WATCHDOG,0); } void hw_watchdog_reset(void) { gpio_set_value(GPIO_WATCHDOG, 1); gpio_set_value(GPIO_WATCHDOG, 0); } #endif 说明:喂狗使用的是GPIO0_23(根据自己的引脚配置修改) (1)、在board/ti/am335x/mux.c中加上引脚初始化代码 static struct module_pin_mux gpio0_23_pin_mux[] = { {OFFSET(gpmc_ad9), (MODE(7) | PULLUDEN)}, /* GPIO0_23 */ {-1}, }; void enable_gpio0_23_pin_mux(void) { configure_module_pin_mux(gpio0_23_pin_mux); } (2)在board/ti/am335x/common_def.h中加上函数声明 extern void enable_gpio0_23_pin_mux(void); 3、 在uboot启动过程中要执行gpio0_23_watchdog();函数 我加在common/main.c中,也可以加在其他地方
我加在arch/arm/lib/board.c中,也可以加在其他地方
void board_init_f(ulong bootflag)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
gd_t *id;
ulong addr, addr_sp;
/*add gpio0_23 for watchdog by liuc of 2013-1-30*/
#ifdef CONFIG_HW_WATCHDOG
gpio0_23_watchdog();
#endif
.......................
}
4、然后编译,uboot烧写成功后,即可使用,用tftp烧写内核和文件系统是正常的。 问题: 用SD卡烧写文件系统即大文件的时候系统会重启,原因应该是读写SD卡文件的函数没有进行喂狗, 解决办法: SD卡烧写文件系统时喂狗 在drivers/mmc/omap_hsmmc.c文件中加上头文件 #include 修改函数如下: static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size) { …………………………………….. while (size) { /*add gpio0_23 for watchdog by liuc of 2013-2-4*/ WATCHDOG_RESET(); ulong start = get_timer(0); do { mmc_stat = readl(&mmc_base->stat); if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for status!
", __func__); return TIMEOUT; } } while (mmc_stat == 0); ………………………………. } static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int size) { ……………………… while (size) { /*add gpio0_23 for watchdog by liuc of 2013-2-4*/ WATCHDOG_RESET(); ulong start = get_timer(0); do { mmc_stat = readl(&mmc_base->stat); if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for status!
", __func__); return TIMEOUT; } } while (mmc_stat == 0); ………………………. }