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

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

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

在brandy/brandy-2.0/u-boot-2018/cmd/ 目錄下新建 gpio_toggle.c 文件,編寫碼實(shí)現(xiàn) PE1 引腳的輸出模式設(shè)置和電平翻轉(zhuǎn)功能
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");
// 設(shè)置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);
// 電平翻轉(zhuǎn) 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 文件,添加相關(guān)配置
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選項(xiàng)
上電后按住鍵盤的 s 進(jìn)入 uboot 命令行,執(zhí)行 gpio_toggle 指令,用萬用表測試 PE1 引腳的電平,可發(fā)現(xiàn)執(zhí)行一次指令,電平狀態(tài)翻轉(zhuǎn)一次,驗(yàn)證成功。
brandy/brandy-2.0/u-boot-2018/configs/sun8iw20p1_auto_t113_i_defconfig
CONFIG_CMD_GPIO_TOGGLE=y
編譯后燒寫uboot固件進(jìn)行測試
在uboot命令行進(jìn)行測試,上電一直按住鍵盤的s進(jìn)入uboot命令行,執(zhí)行以下指令
=> gpio_toggle
會有以下信息輸出,用萬用表測試PE1引腳的電平,發(fā)現(xiàn)執(zhí)行一次翻轉(zhuǎn)一次電平狀態(tài)

至此完成驗(yàn)證寄存器翻轉(zhuǎn)電平方案成功,接下來進(jìn)入下一步。
4.2uboot PE1引腳自動喂狗實(shí)現(xiàn)
實(shí)現(xiàn) uboot 自帶的 hw_watchdog 接口,編寫代碼完成 PE1 引腳的初始化(設(shè)置為輸出模式)和喂狗操作(電平翻轉(zhuǎn))。
#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){ // 設(shè)置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);
// 設(shè)置PE1驅(qū)動等級(默認(rèn)為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);
// 設(shè)置PE1電平,由于硬件電路該引腳為高阻,所以一開始先翻轉(zhuǎn)下 // 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);
// // 默認(rèn)為無上下拉,符合需求不用管
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.
在相關(guān)配置文件中添加該看門狗驅(qū)動的配置選項(xiàng),然后修改全志板級文件 board.c,在板級初始化過程中調(diào)用 hw_watchdog_init () 函數(shù),新增PE1的初始化調(diào)用,開啟 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();
驗(yàn)證:開啟看門狗電路設(shè)計(jì)預(yù)留的硬件撥碼開關(guān),上電后進(jìn)入 uboot 命令行,系統(tǒng)不會因超時(shí)重啟,說明 uboot 喂狗實(shí)現(xiàn)成功。
4.3kernel PE1 引腳自動喂狗實(shí)現(xiàn)
在內(nèi)核中開啟 CONFIG_GPIO_WATCHDOG 選項(xiàng)
CONFIG_GPIO_WATCHDOG=y
設(shè)備樹中新增看門狗配置
watchdog: watchdog {compatible ="linux,wdt-gpio";gpios = <&pio PE 1 GPIO_ACTIVE_HIGH>;hw_algo ="toggle";hw_margin_ms = <1000>; #always-running ="true"; };
驗(yàn)證:進(jìn)入系統(tǒng)后,開啟看門狗電路設(shè)計(jì)預(yù)留的硬件撥碼開關(guān),系統(tǒng)不會重啟,表明 kernel 喂狗功能正常。
4.4uboot 到 kernel 的銜接
關(guān)鍵一步,經(jīng)測試在kernel啟動的0.2秒左右看門狗會出現(xiàn)超時(shí),為避免 kernel 啟動初期因打印信息過多導(dǎo)致喂狗不及時(shí),需要修改打印等級。減少啟動過程中的打印輸出,確保kernel能及時(shí)接管喂狗任務(wù),實(shí)現(xiàn)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=
五、總結(jié)
通過以上步驟,我們成功在T113-I平臺上實(shí)現(xiàn)了從 uboot 到 kernel 的看門狗無縫銜接,系統(tǒng)能夠全自動喂狗,無需應(yīng)用層干預(yù),極大地提高了系統(tǒng)的穩(wěn)定性和可靠性。相信這一方案對于需要高穩(wěn)定性的嵌入式項(xiàng)目具有重要的應(yīng)用價(jià)值,十分適用于對系統(tǒng)穩(wěn)定性要求極高的工業(yè)控制、物聯(lián)網(wǎng)設(shè)備。
-
看門狗
+關(guān)注
關(guān)注
10文章
602瀏覽量
72466 -
嵌入式系統(tǒng)
+關(guān)注
關(guān)注
41文章
3703瀏覽量
132892 -
核心板
+關(guān)注
關(guān)注
6文章
1323瀏覽量
31644
發(fā)布評論請先 登錄
看門狗多任務(wù)系統(tǒng)及喂狗方法詳解
新手如何開發(fā)高可靠性的嵌入式系統(tǒng)
開發(fā)高可靠性嵌入式系統(tǒng)的技巧有哪些?
嵌入式系統(tǒng)看門狗計(jì)數(shù)器怎么清零?
什么是stm32看門狗?獨(dú)立看門狗和窗口看門狗工作原理解析
uC/OS-II 系統(tǒng)的多任務(wù)看門狗設(shè)計(jì)
對于MCU看門狗IIWDG WWDG喂狗時(shí)間的配置參考
【嵌入式系統(tǒng)】獨(dú)立看門狗原理+看門狗實(shí)驗(yàn)分析

T113-I打造高可靠性嵌入式系統(tǒng),1.12秒極限下的看門狗喂狗之法
評論