• 正文
  • 相关推荐
申请入驻 产业图谱

T113-I打造高可靠性嵌入式系统,1.12秒极限下的看门狗喂狗之法

08/25 14:57
1511
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

前言:

嵌入式系统使用中,看门狗(Watchdog)是保障系统稳定性的重要机制之一,守护着系统的稳定运行。常规实现是通过应用层参与喂狗操作,存在不稳定因素,也无法处理系统启动过程中的异常。本文将分享一种在T113-I平台上实现的uboot至kernel看门狗无缝衔接技术,且做到系统全自动喂狗,真正保障系统的高可靠性。

一、难点分析

实现从上电开始的系统全自动喂狗机制,可以确保系统在任何阶段都不会因看门狗超时而重启复位。然而,高可靠的嵌入式系统往往需要监管严苛且及时,能够在异常的第一时间产生响应,因此又需要选用超时时间极短的看门狗芯片

喂狗间隙短,从uboot至kernel的无缝切换便成了横亘在高可靠性嵌入式系统设计中的一大难题。

二、环境说明

→主控平台:眺望电子AC113I-92M-SNLI工业级核心板,基于全志T113-I处理器

→看门狗芯片:思瑞浦(3PEAK)TPV6823S-TR,其复位时间为 1.12 秒;

SDK版本:talowe-T113-I-Tina-sdk_2025_04_16.tar.gz,

→虚拟机环境:ubuntu20.04

→硬件原理图:PE1为喂狗引脚

三、方案设计

针对 1.12 秒的复位时间限制,制定了如下分阶段的实现方案,确保从 uboot 到 kernel 的全过程都能及时喂狗:

•阶段 1:实现 uboot 电平翻转,验证喂狗引脚的控制能力。

•阶段 2:实现 uboot 喂狗,确保在 uboot 命令行停留时不会超时重启。

•阶段 3:实现 kernel 喂狗,保证系统进入内核后能持续喂狗。

•阶段 4:完成 uboot 到 kernel 的无缝衔接,确保系统从上电到完全启动的整个过程中,看门狗不会超时重启。

四、实现步骤

4.1 uboot 电平翻转测试验证

喂狗引脚为 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 <common.h>
#include <sunxi_board.h>

#define T113_I_GPIOE_CFG0		0x020000C0
#define T113_I_GPIOE_CFG1		0x020000C4
#define T113_I_GPIOE_DAT		0x020000D0
#define T113_I_GPIOE_DRV0		0x020000D4
#define T113_I_GPIOE_DRV1		0x020000D8
#define T113_I_GPIOE_PULL0		0x020000E4

int gpio_toggle (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
    printf ("## test gpio Toggle...n");

    // 设置PE1为输出模式
    unsigned int *PE1_CFG0    = (unsigned int *)(T113_I_GPIOE_CFG0);
    unsigned int PE1_CFG0_val = readl(PE1_CFG0);
    PE1_CFG0_val &= ~(0xf << 4*1);
    PE1_CFG0_val |= (0x1 << 4*1);
    writel(PE1_CFG0_val, PE1_CFG0);

    // 电平翻转
    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);

    return 0;
}

U_BOOT_CMD(
    gpio_toggle,	1,	0,	gpio_toggle,
    "talowe test gpio Toggle",
    "no parametersn"
);

♦修改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

config CMD_GPIO_TOGGLE
	bool "GPIO toggle"
	help
	  Activate this option 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.2 uboot PE1引脚自动喂狗实现

实现 uboot 自带的 hw_watchdog 接口,编写代码完成 PE1 引脚的初始化(设置为输出模式)和喂狗操作(电平翻转)。

#include <common.h>
#include <asm/io.h>
#include <sunxi_board.h>

#define T113_I_GPIOE_CFG0		  0x020000C0
#define T113_I_GPIOE_CFG1		  0x020000C4
#define T113_I_GPIOE_DAT		  0x020000D0
#define T113_I_GPIOE_DRV0		  0x020000D4
#define T113_I_GPIOE_DRV1		  0x020000D8
#define T113_I_GPIOE_PULL0		  0x020000E4

void hw_watchdog_reset(void)
{
    if (get_boot_work_mode())
        return;

    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);
}

void hw_watchdog_init(void)
{
    // 设置PE1为输出模式
    unsigned int *PE1_CFG0 		= (unsigned int *)(T113_I_GPIOE_CFG0);
    unsigned int PE1_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();
}

在以下文件新增

obj-$(CONFIG_T113_I_WATCHDOG_REG) += t113_I_watchdog_reg.o
config T113_I_WATCHDOG_REG
	bool "T113_I hw watchdog"
	depends on ARCH_SUNXI
	select HW_WATCHDOG
	help
	  Say Y here to enable the 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.c
index 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 <mapmem.h>
 #include <smc.h>
+#ifdef CONFIG_T113_I_WATCHDOG_REG
+#include <watchdog.h>
+#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();
+#endif
 	int work_mode = get_boot_work_mode();
 
 	ret = axp_gpio_init();

验证:开启看门狗电路设计预留的硬件拨码开关,上电后进入 uboot 命令行,系统不会因超时重启,说明 uboot 喂狗实现成功。

4.3 kernel 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.4 uboot 到 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.cfg
index bc1d41d..52d32d2 100755
--- 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/mmcblk0p5
 mtd_name=sys
 rootfstype=ubifs,rw
 init=/init
-loglevel=8
+loglevel=5
 cma=16M
 mac=
 wifi_mac=

五、总结

通过以上步骤,我们成功在T113-I平台上实现了从 uboot 到 kernel 的看门狗无缝衔接,系统能够全自动喂狗,无需应用层干预,极大地提高了系统的稳定性和可靠性。相信这一方案对于需要高稳定性的嵌入式项目具有重要的应用价值,十分适用于对系统稳定性要求极高的工业控制物联网设备
如果您希望获取完整上述代码补丁或者T113-I核心板开发资料,欢迎关注我们的公众号,联系我们获取!

思瑞浦

思瑞浦

思瑞浦(3PEAK)始终坚持研发高性能、高质量和高可靠性的集成电路产品,包括信号链模拟芯片、电源管理模拟芯片和数模混合模拟前端,并逐渐融合嵌入式处理器,为客户提供全方面的解决方案。其应用范围涵盖通讯、工业、汽车、新能源和医疗健康等众多领域。2020 年 9 月 21 日在上海证券交易所科创板上市。更多详情访问:https://www.3peak.com/

思瑞浦(3PEAK)始终坚持研发高性能、高质量和高可靠性的集成电路产品,包括信号链模拟芯片、电源管理模拟芯片和数模混合模拟前端,并逐渐融合嵌入式处理器,为客户提供全方面的解决方案。其应用范围涵盖通讯、工业、汽车、新能源和医疗健康等众多领域。2020 年 9 月 21 日在上海证券交易所科创板上市。更多详情访问:https://www.3peak.com/收起

查看更多

相关推荐