前言:
在嵌入式系統使用中,看門狗(Watchdog)是保障系統穩定性的重要機制之一,守護著系統的穩定運行。常規實現是通過應用層參與喂狗操作,存在不穩定因素,也無法處理系統啟動過程中的異常。本文將分享一種在T113-I平臺上實現的uboot至kernel看門狗無縫銜接技術,且做到系統全自動喂狗,真正保障系統的高可靠性。
一、難點分析
實現從上電開始的系統全自動喂狗機制,可以確保系統在任何階段都不會因看門狗超時而重啟復位。然而,高可靠的嵌入式系統往往需要監管嚴苛且及時,能夠在異常的第一時間產生響應,因此又需要選用超時時間極短的看門狗芯片。
喂狗間隙短,從uboot至kernel的無縫切換便成了橫亙在高可靠性嵌入式系統設計中的一大難題。
二、環境說明
主控平臺:眺望電子AC113I-92M-SNLI工業級核心板,基于全志T113-I處理器;
看門狗芯片:思瑞浦(3PEAK)TPV6823S-TR,其復位時間為 1.12 秒;

SDK版本:talowe-T113-I-Tina-sdk.tar.gz,
虛擬機環境:ubuntu20.04
硬件原理圖:PE1為喂狗引腳

三、方案設計
針對 1.12 秒的復位時間限制,制定了如下分階段的實現方案,確保從 uboot 到 kernel 的全過程都能及時喂狗:
階段 1:uboot 電平翻轉,驗證喂狗引腳的控制能力。
階段 2:uboot 喂狗,確保在 uboot 命令行停留時不會超時重啟。
階段 3:kernel 喂狗,保證系統進入內核后能持續喂狗。
階段 4:uboot 到 kernel 的無縫銜接,確保系統從上電到完全啟動的整個過程中,看門狗不會超時重啟。
四、實現步驟
4.1uboot 電平翻轉測試驗證
喂狗引腳為 PE1,我們需要先驗證對該引腳的電平控制能力。通過查閱《T113-i_User_Manual_V1.5.pdf》,找到 PE 相關寄存器的地址。

在brandy/brandy-2.0/u-boot-2018/cmd/ 目錄下新建 gpio_toggle.c 文件,編寫碼實現 PE1 引腳的輸出模式設置和電平翻轉功能
brandy/brandy-2.0/u-boot-2018/cmd/gpio_toggle.c
#include#include
#defineT113_I_GPIOE_CFG00x020000C0#defineT113_I_GPIOE_CFG10x020000C4#defineT113_I_GPIOE_DAT0x020000D0#defineT113_I_GPIOE_DRV00x020000D4#defineT113_I_GPIOE_DRV10x020000D8#defineT113_I_GPIOE_PULL00x020000E4
intgpio_toggle(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[]){ printf("## test gpio Toggle...\n");
// 設置PE1為輸出模式 unsignedint*PE1_CFG0 = (unsignedint*)(T113_I_GPIOE_CFG0); unsignedintPE1_CFG0_val =readl(PE1_CFG0); PE1_CFG0_val &= ~(0xf<4*1);? ? PE1_CFG0_val |= (0x1?<4*1);? ? writel(PE1_CFG0_val, PE1_CFG0);
// 電平翻轉 unsignedint*PE1_DAT = (unsignedint*)(T113_I_GPIOE_DAT); unsignedintPE1_DAT_val =readl(PE1_DAT); PE1_DAT_val ^= (0x1<1);? ? writel(PE1_DAT_val, PE1_DAT);
return0;}
U_BOOT_CMD( gpio_toggle,1,0,gpio_toggle, "talowe test gpio Toggle", "no parameters\n");
修改Makefile 和 Kconfig 文件,添加相關配置
brandy/brandy-2.0/u-boot-2018/cmd/Makefile
obj-$(CONFIG_CMD_GPIO_TOGGLE) += gpio_toggle.o
brandy/brandy-2.0/u-boot-2018/cmd/Kconfig
configCMD_GPIO_TOGGLEbool"GPIO toggle"help Activatethisoption to test GPIO toggle.
配置 sun8iw20p1_auto_t113_i_defconfig選項
上電后按住鍵盤的 s 進入 uboot 命令行,執行 gpio_toggle 指令,用萬用表測試 PE1 引腳的電平,可發現執行一次指令,電平狀態翻轉一次,驗證成功。
brandy/brandy-2.0/u-boot-2018/configs/sun8iw20p1_auto_t113_i_defconfig
CONFIG_CMD_GPIO_TOGGLE=y
編譯后燒寫uboot固件進行測試
在uboot命令行進行測試,上電一直按住鍵盤的s進入uboot命令行,執行以下指令
=> gpio_toggle
會有以下信息輸出,用萬用表測試PE1引腳的電平,發現執行一次翻轉一次電平狀態

至此完成驗證寄存器翻轉電平方案成功,接下來進入下一步。
4.2uboot PE1引腳自動喂狗實現
實現 uboot 自帶的 hw_watchdog 接口,編寫代碼完成 PE1 引腳的初始化(設置為輸出模式)和喂狗操作(電平翻轉)。
#include#include#include
#defineT113_I_GPIOE_CFG0 0x020000C0#defineT113_I_GPIOE_CFG1 0x020000C4#defineT113_I_GPIOE_DAT 0x020000D0#defineT113_I_GPIOE_DRV0 0x020000D4#defineT113_I_GPIOE_DRV1 0x020000D8#defineT113_I_GPIOE_PULL0 0x020000E4
voidhw_watchdog_reset(void){ if(get_boot_work_mode()) return;
unsignedint*PE1_DAT = (unsignedint*)(T113_I_GPIOE_DAT); unsignedintPE1_DAT_val =readl(PE1_DAT); PE1_DAT_val ^= (0x1<1);? ? writel(PE1_DAT_val, PE1_DAT);}
voidhw_watchdog_init(void){ // 設置PE1為輸出模式 unsignedint*PE1_CFG0 = (unsignedint*)(T113_I_GPIOE_CFG0); unsignedintPE1_CFG0_val =readl(PE1_CFG0); PE1_CFG0_val &= ~(0xf<4*1);? ? PE1_CFG0_val |= (0x1?<4*1);? ? writel(PE1_CFG0_val, PE1_CFG0);
// 設置PE1驅動等級(默認為1,可以不用) // unsigned int *PE1_DRV0 = (unsigned int *)(T113_I_GPIOE_DRV0); // unsigned int PE1_DRV0_val = readl(PE1_DRV0); // PE1_DRV0_val &= ~(0x3 << 4*1);? ? // PE1_DRV0_val |= (0x10 << 4*1);? ? // writel(PE1_DRV0_val, PE1_DRV0);
// 設置PE1電平,由于硬件電路該引腳為高阻,所以一開始先翻轉下 // unsigned int *PE1_DAT = (unsigned int *)(T113_I_GPIOE_DAT); // unsigned int PE1_DAT_val = readl(PE1_DAT); // PE1_DAT_val ^= (0x1 << 1);? ? // writel(PE1_DAT_val, PE1_DAT);? ? // PE1_DAT_val ^= (0x1 << 1);? ? // writel(PE1_DAT_val, PE1_DAT);
// // 默認為無上下拉,符合需求不用管
hw_watchdog_reset();}
在以下文件新增
1obj-$(CONFIG_T113_I_WATCHDOG_REG) += t113_I_watchdog_reg.o
config T113_I_WATCHDOG_REGbool"T113_I hw watchdog"depends on ARCH_SUNXIselectHW_WATCHDOGhelp Say Y here toenablethe T113_I hw watchdog driver.
在相關配置文件中添加該看門狗驅動的配置選項,然后修改全志板級文件 board.c,在板級初始化過程中調用 hw_watchdog_init () 函數,新增PE1的初始化調用,開啟 uboot 階段的喂狗功能。
diff --git a/brandy/brandy-2.0/u-boot-2018/board/sunxi/board.c b/brandy/brandy-2.0/u-boot-2018/board/sunxi/board.cindex 0019f45..4233b22 100644--- a/brandy/brandy-2.0/u-boot-2018/board/sunxi/board.c+++ b/brandy/brandy-2.0/u-boot-2018/board/sunxi/board.c@@ -54,6 +54,9 @@#endif#include #include +#ifdef CONFIG_T113_I_WATCHDOG_REG+#include +#endif
int __attribute__((weak)) sunxi_set_sramc_mode(void)@@ -219,6 +222,9 @@int board_init(void)
sunxi_plat_init();
+#ifdef CONFIG_T113_I_WATCHDOG_REG+hw_watchdog_init();+#endifint work_mode = get_boot_work_mode();
ret = axp_gpio_init();
驗證:開啟看門狗電路設計預留的硬件撥碼開關,上電后進入 uboot 命令行,系統不會因超時重啟,說明 uboot 喂狗實現成功。
4.3kernel PE1 引腳自動喂狗實現
在內核中開啟 CONFIG_GPIO_WATCHDOG 選項
CONFIG_GPIO_WATCHDOG=y
設備樹中新增看門狗配置
watchdog: watchdog {compatible ="linux,wdt-gpio";gpios = <&pio PE 1 GPIO_ACTIVE_HIGH>;hw_algo ="toggle";hw_margin_ms = <1000>; #always-running ="true"; };
驗證:進入系統后,開啟看門狗電路設計預留的硬件撥碼開關,系統不會重啟,表明 kernel 喂狗功能正常。
4.4uboot 到 kernel 的銜接
關鍵一步,經測試在kernel啟動的0.2秒左右看門狗會出現超時,為避免 kernel 啟動初期因打印信息過多導致喂狗不及時,需要修改打印等級。減少啟動過程中的打印輸出,確保kernel能及時接管喂狗任務,實現uboot到kernel的無縫銜接。
在 device/config/chips/t113_i/configs/evb1_auto/buildroot/env.cfg 文件中,將 loglevel 從8修改為5或6。
diff--git a/device/config/chips/t113_i/configs/evb1_auto/buildroot/env.cfg b/device/config/chips/t113_i/configs/evb1_auto/buildroot/env.cfgindex bc1d41d..52d32d2100755---a/device/config/chips/t113_i/configs/evb1_auto/buildroot/env.cfg+++b/device/config/chips/t113_i/configs/evb1_auto/buildroot/env.cfg@@-8,7+8,7@@ mmc_root=/dev/mmcblk0p5mtd_name=sysrootfstype=ubifs,rwinit=/init-loglevel=8+loglevel=5cma=16Mmac=wifi_mac=
五、總結
通過以上步驟,我們成功在T113-I平臺上實現了從 uboot 到 kernel 的看門狗無縫銜接,系統能夠全自動喂狗,無需應用層干預,極大地提高了系統的穩定性和可靠性。相信這一方案對于需要高穩定性的嵌入式項目具有重要的應用價值,十分適用于對系統穩定性要求極高的工業控制、物聯網設備。
-
看門狗
+關注
關注
10文章
610瀏覽量
72946 -
嵌入式系統
+關注
關注
41文章
3747瀏覽量
133635 -
核心板
+關注
關注
6文章
1399瀏覽量
32010
發布評論請先 登錄
新手如何開發高可靠性的嵌入式系統
開發高可靠性嵌入式系統的技巧有哪些?
對于MCU看門狗IIWDG WWDG喂狗時間的配置參考
STM32中的獨立看門狗和窗口看門狗
基于全志T113-i多核異構處理器的全國產嵌入式核心板簡介
“喂狗”的藝術:看門狗不叫,才是系統好
T113-I打造高可靠性嵌入式系統,1.12秒極限下的看門狗喂狗之法
評論