看門狗,又叫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);
……………………….
}