Files
poweroff-protection/poweroff_linux/串口关机文档.md
2026-05-14 17:53:52 +08:00

7.1 KiB
Raw Permalink Blame History

串口关机控制器

通过串口接收指令触发 x86 Ubuntu 系统关机的程序。

功能概述

本程序持续监听指定的串口,当接收到特定的关机指令时,自动执行系统关机操作。适用于嵌入式 x86 Ubuntu 系统中需要通过外部设备(如 MCU/Arduino控制关机的场景。

程序启动后会主动发送 start 握手指令,并每秒定时发送 blive 心跳包,用于告知对端设备本机处于在线状态。

主要特性

  • 持续监听串口数据
  • 支持配置文件自定义串口参数
  • 自动重连机制(串口断开后每 5 秒重新连接)
  • 按行解析接收到的数据
  • 串口连接后发送 start 握手指令
  • 每秒定时发送 blive 心跳包
  • 执行系统关机命令

通信协议

本机发送(→ 对端)

指令 触发时机 说明
start\r\n 串口连接成功后立即发送 握手指令,通知对端本机已就绪
blive\r\n 每秒定时发送 心跳包,通知对端本机仍在运行
ok\r\n 系统关机poweroff时发送 关机钩子脚本发送,通知对端本机即将关机

本机接收(← 对端)

指令 说明
shutdownWord(配置项) 收到后立即触发系统关机,默认为 SHUTDOWN

配置说明

配置文件为 config.json,与可执行文件放在同一目录下,包含以下参数:

参数 类型 说明 默认值
port string 串口设备路径 /dev/ttyUSB0
baudRate int 串口波特率 115200
shutdownWord string 触发关机的指令文本 SHUTDOWN

串口设备路径

x86 Ubuntu 下常见的串口设备路径格式:

设备类型 路径格式 说明
USB 转串口 /dev/ttyUSBx USB-RS232/USB-TTL 转接器(如 CH340、CP2102、FT232
USB CDC ACM /dev/ttyACMx USB 虚拟串口设备(使用USB时)
原生串口 /dev/ttySx 主板自带 RS232 串口COM 口)

x 为设备编号,从 0 开始。可通过 ls /dev/tty*dmesg | grep tty 查看系统中可用的串口设备。

配置示例

使用 USB 转串口:

{
  "port": "/dev/ttyUSB0",
  "baudRate": 115200,
  "shutdownWord": "SHUTDOWN"
}

使用 USB CDC

{
  "port": "/dev/ttyACM0",
  "baudRate": 115200,
  "shutdownWord": "SHUTDOWN"
}

使用主板原生串口:

{
  "port": "/dev/ttyS0",
  "baudRate": 115200,
  "shutdownWord": "SHUTDOWN"
}

交叉编译

本程序在 Windows 上开发,需要交叉编译为 x86 Linux 可执行文件:

set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0
go build -o shutdown shutdown.go

PowerShell 环境:

$env:GOOS = "linux"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"
go build -o shutdown shutdown.go

编译产物 shutdown 为 Linux x86_64 可执行文件,需上传至目标 Ubuntu 系统运行。

部署与运行

方式一:使用安装脚本(推荐)

项目提供 install.sh 安装脚本,可自动完成串口选择、配置生成、服务安装等全部流程。

上传项目到目标系统

scp -r ./ user@<目标IP>:/home/user/shutdown/

运行安装脚本

cd /home/user/shutdown
sudo bash install.sh

安装流程

  1. 选择串口 - 脚本自动扫描系统中的串口设备(ttyUSB*ttyACM*ttyS*),列出设备并标明类型,交互选择或手动输入路径
  2. 配置参数 - 可自定义波特率(默认 115200和关机指令默认 SHUTDOWN
  3. 确认安装 - 显示完整配置供确认
  4. 自动编译 - 检测到 Go 环境则交叉编译,否则使用预编译二进制
  5. 安装文件 - 二进制和配置文件安装到 /opt/ttyshutdown/
  6. 关机钩子 - 生成 /usr/lib/systemd/system-shutdown/send_signal.sh,系统关机时通过串口发送 ok\r\n 通知对端
  7. systemd 服务 - 生成并启用 ttyshutdown.service

安装后管理

# 查看服务状态
systemctl status ttyshutdown

# 查看实时日志
journalctl -u ttyshutdown -f

# 停止服务
systemctl stop ttyshutdown

# 更换串口
sudo bash change_port.sh

# 卸载
sudo bash uninstall.sh

更换串口

当需要更换串口设备时(如更换 USB 端口、更换转接器等),使用 change_port.sh 脚本可自动完成配置更新和服务重启。

sudo bash change_port.sh

更换流程

  1. 显示当前配置 - 展示当前串口设备、波特率、关机指令
  2. 选择新串口 - 自动扫描系统中可用串口,当前使用的串口会标注 <-- 当前,交互选择或手动输入新路径
  3. 可选修改参数 - 波特率和关机指令可直接回车保持不变,或输入新值修改
  4. 确认更改 - 显示新旧配置对比供确认
  5. 执行更改 - 同时更新 config.jsonsend_signal.sh,并自动重启 ttyshutdown 服务

脚本会同时更新 config.jsonsend_signal.sh 中的串口配置,确保两者一致。

方式二:手动部署

1. 上传到目标系统

scp shutdown config.json user@<目标IP>:/home/user/shutdown/

2. 添加执行权限

chmod +x shutdown

3. 运行程序

sudo ./shutdown

注意事项

  1. 程序需要 root 权限才能执行系统关机命令
  2. 串口断开后会每 5 秒尝试重新连接
  3. 接收的数据以换行符(\n\r\n)为单位进行解析
  4. 关机指令必须与配置文件中的 shutdownWord 完全匹配(区分大小写)
  5. 串口重连后 start 握手和 blive 心跳会自动重新启动
  6. 串口设备路径在设备重新插拔后可能变化ttyUSB0 → ttyUSB1建议使用 udev 规则绑定固定设备名
  7. 安装脚本会将选定的串口设备同时写入 config.jsonsend_signal.sh,确保两者一致

日志输出

程序运行时会输出以下日志信息:

  • 配置加载状态
  • 串口连接状态
  • start 握手指令发送状态
  • 接收到的数据内容
  • 关机指令触发和执行状态
  • 串口错误和重连状态

关机钩子

系统关机时,/usr/lib/systemd/system-shutdown/send_signal.sh 会被 systemd 调用,在系统执行 poweroff 前通过串口向对端发送 ok\r\n,通知对端本机即将关机。

该脚本由安装脚本自动生成,其中 TTY_DEVICEconfig.json 中的 port 保持一致。

文件说明

文件 说明
shutdown.go 主程序源码
config.json 串口配置文件(与二进制同目录)
send_signal.sh systemd 关机钩子脚本,安装到 /usr/lib/systemd/system-shutdown/
ttyshutdown.service systemd 服务单元文件
install.sh 安装脚本
uninstall.sh 卸载脚本
change_port.sh 更换串口脚本

技术实现

  • 编程语言Go
  • 目标平台x86 Ubuntu (linux/amd64)
  • 依赖库:go.bug.st/serial(串口通信)
  • 关机命令:shutdown -h now
  • 交叉编译CGO_ENABLED=0 静态编译,无外部依赖