3. 网关启动流程优化与看门狗配置
任务目标
本案例面向基于Linux的工业IoT网关,完成两项核心工作:一是通过启动脚本串行化改造与关键服务延迟加载,将网关从上电到应用就绪的时间压缩至可接受范围;二是配置硬件看门狗(以i.MX6ULL+外部看门狗芯片SP7060为例),在应用主循环中周期性喂狗,防止系统死机后无法自恢复。
环境与依赖
- 硬件:i.MX6ULL核心板 + SP7060看门狗芯片(连接到GPIO1_IO09,低电平触发喂狗)
- 系统:Linux 4.1.15 + Buildroot交叉编译环境
- 关键工具:
busybox(含watchdog命令)、systemd(或SysVinit,本案例使用systemd) - 交叉编译器:
arm-linux-gnueabihf-gcc
实现方案
启动优化采用“依赖分级”策略:将启动脚本拆分为base-init(挂载文件系统、启动核心驱动)和app-init(启动业务应用)两个服务,利用systemd的After=和Type=oneshot控制顺序,避免所有服务并行争抢CPU导致启动峰值过高。看门狗部分通过设备树使能GPIO,应用层使用ioctl定时喂狗,并在异常退出时由内核驱动自动复位系统。
关键完整代码
// 文件1: /etc/systemd/system/gateway-base.service
[Unit]
Description=Gateway Base Init
DefaultDependencies=no
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/usr/bin/base-init.sh
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
// 文件2: /etc/systemd/system/gateway-app.service
[Unit]
Description=Gateway Application
After=gateway-base.service network.target
[Service]
Type=simple
ExecStart=/usr/bin/gateway-app
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
// 文件3: /usr/bin/base-init.sh
#!/bin/sh
# 挂载必要文件系统
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
# 加载核心驱动(按依赖顺序)
modprobe spi-imx
modprobe spidev
# 初始化看门狗GPIO
echo 9 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio9/direction
echo 1 > /sys/class/gpio/gpio9/value # 初始拉高,禁止复位
// 文件4: /usr/bin/gateway-app.c(喂狗核心逻辑)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>
#define WDT_DEV "/dev/watchdog"
#define GPIO_FEED "/sys/class/gpio/gpio9/value"
#define FEED_INTERVAL 2 // 喂狗周期(秒)
int main() {
int wdt_fd = open(WDT_DEV, O_WRONLY);
if (wdt_fd < 0) {
perror("open watchdog");
return -1;
}
// 设置超时时间为5秒(硬件看门狗芯片设定)
int timeout = 5;
ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);
int gpio_fd = open(GPIO_FEED, O_WRONLY);
if (gpio_fd < 0) {
perror("open gpio");
return -1;
}
// 主业务循环
while (1) {
// 业务处理逻辑(此处简化为空转)
usleep(100000); // 100ms
// 喂狗:GPIO拉低再拉高,产生下降沿触发
write(gpio_fd, "0", 1);
usleep(1000);
write(gpio_fd, "1", 1);
}
close(wdt_fd);
close(gpio_fd);
return 0;
}
编译与部署
# 交叉编译应用
arm-linux-gnueabihf-gcc -o gateway-app gateway-app.c
# 部署到网关(假设通过NFS或scp)
scp gateway-app root@192.168.1.100:/usr/bin/
scp base-init.sh root@192.168.1.100:/usr/bin/
scp gateway-base.service gateway-app.service root@192.168.1.100:/etc/systemd/system/
# 在网关上执行
chmod +x /usr/bin/gateway-app /usr/bin/base-init.sh
systemctl daemon-reload
systemctl enable gateway-base.service
systemctl enable gateway-app.service
reboot
验证方法与判定标准
- 启动时间验证:在
base-init.sh首行和gateway-app首行分别添加echo $(date +%s%N) >> /tmp/boot_time.log,重启后对比两个时间戳差值,应小于3秒(不含内核启动时间)。 - 看门狗功能验证:正常运行后执行
kill -9 $(pidof gateway-app),观察系统应在5秒内自动重启(看门狗超时触发硬件复位)。若系统未重启,说明喂狗逻辑或GPIO配置有误。 - 喂狗信号检查:使用示波器测量GPIO1_IO09引脚,正常工作时应有周期约2秒的低脉冲(脉宽约1ms)。
常见问题
- 看门狗设备不存在:确认内核已配置
CONFIG_WATCHDOG和CONFIG_GPIO_WATCHDOG,且设备树中正确声明了看门狗节点。 - 启动时间未优化:检查是否有其他服务仍在并行启动,使用
systemd-analyze blame查看各服务耗时。 - 喂狗失败导致反复重启:确认GPIO编号与硬件连接一致,且应用启动前GPIO已正确初始化为高电平。