一、说明:
看门狗,又叫 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 <watchdog.h>
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 <watchdog.h>
修改函数如下:
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!\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 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!\n",
__func__);
return TIMEOUT;
}
} while (mmc_stat == 0);
……………………….
}
看门狗,又叫 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 <watchdog.h>
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 <watchdog.h>
修改函数如下:
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!\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 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!\n",
__func__);
return TIMEOUT;
}
} while (mmc_stat == 0);
……………………….
}