一、说明
刚开始想的方案是利用uboot中的看门狗定时器,在中断里面进行喂狗。但是经过几天的折腾,内部看门狗打开后达到溢出条件就会直接复位,没办法进入中断,而且复位动作没找到屏蔽的方法,所以只能放弃这个方案。
之后在网上搜到了一篇关于am335x uboot 看门狗喂狗的文章,写的很详细,根据这篇文章解决了这个问题。
参考:335x uboot 看门狗喂狗
链接:https://blog.csdn.net/zjy900507/article/details/78797833
二、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
其实,在uboot已经在源码中比较耗时、需要喂狗的地方穿插了喂狗函数。
所以,我们只需要打开CONFIG_HW_WATCHDOG开关以及实现hw_watchdog_reset喂狗函数。
2、打开硬件看门狗,在板级头文件中include/configs/am437x_evm.h文件中加上宏定义
#define CONFIG_HW_WATCHDOG 1
#define GPIO_WATCHDOG (3<<5 | 23)
GPIO_WATCHDOG这个值的设置是通过分析uboot源码中gpio_set_value()函数才知道如何设置。
根据原理图找到引脚,然后在数据手册中搜索,查到看门狗复用GPIO引脚为gpio3_23
3、然后在板级文件board/ti/am437x/board.c中加入看门狗初始化函数以及喂狗函数hw_watchdog_reset
#ifdef CONFIG_HW_WATCHDOG
void hw_watchdog_reset(void)
{
if (gpio_get_value(GPIO_WATCHDOG))
{
gpio_set_value(GPIO_WATCHDOG, 0);
}
else
{
gpio_set_value(GPIO_WATCHDOG, 1);
}
}
void hw_watchdog_init(void)
{
enable_wdt_pin_mux();
gpio_request(GPIO_WATCHDOG, "gpio_watchdog");
gpio_direction_output(GPIO_WATCHDOG, 0);
}
#endif
4、在board/ti/am437x/mux.c添加引脚初始化代码,并在board/ti/am437x/board.h中加上函数声明。
static struct module_pin_mux wdt_pin_mux[] = {
{OFFSET(spi2_d1), (MODE(7) | PULLUDEN)}, /* SPI2_D1 */
{-1},
};
void enable_wdt_pin_mux(void)
{
configure_module_pin_mux(wdt_pin_mux);
}
5、在common/board_f.c里面已经调用了看门狗初始化函数并喂狗。最后编译,uboot烧写后即可使用。
三、问题
用SD卡烧写文件系统即大文件的时候系统会重启,原因应该是读写SD卡文件的函数没有进行喂狗,
解决办法:
SD卡烧写文件系统时喂狗
在drivers/mmc/omap_hsmmc.c文件中加上头文件
#include <watchdog.h>
修改函数如下:
static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size)
{
……………………………………..
while (size) {
/*add gpio3_23 for watchdog*/
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!\n",
__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 gpio3_23 for watchdog*/
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!\n",
__func__);
return TIMEOUT;
}
} while (mmc_stat == 0);
……………………….
}