7.1 KiB
串口关机控制器
通过串口接收指令触发 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
安装流程
- 选择串口 - 脚本自动扫描系统中的串口设备(
ttyUSB*、ttyACM*、ttyS*),列出设备并标明类型,交互选择或手动输入路径 - 配置参数 - 可自定义波特率(默认 115200)和关机指令(默认 SHUTDOWN)
- 确认安装 - 显示完整配置供确认
- 自动编译 - 检测到 Go 环境则交叉编译,否则使用预编译二进制
- 安装文件 - 二进制和配置文件安装到
/opt/ttyshutdown/ - 关机钩子 - 生成
/usr/lib/systemd/system-shutdown/send_signal.sh,系统关机时通过串口发送ok\r\n通知对端 - 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
更换流程
- 显示当前配置 - 展示当前串口设备、波特率、关机指令
- 选择新串口 - 自动扫描系统中可用串口,当前使用的串口会标注
<-- 当前,交互选择或手动输入新路径 - 可选修改参数 - 波特率和关机指令可直接回车保持不变,或输入新值修改
- 确认更改 - 显示新旧配置对比供确认
- 执行更改 - 同时更新
config.json和send_signal.sh,并自动重启ttyshutdown服务
脚本会同时更新
config.json和send_signal.sh中的串口配置,确保两者一致。
方式二:手动部署
1. 上传到目标系统
scp shutdown config.json user@<目标IP>:/home/user/shutdown/
2. 添加执行权限
chmod +x shutdown
3. 运行程序
sudo ./shutdown
注意事项
- 程序需要 root 权限才能执行系统关机命令
- 串口断开后会每 5 秒尝试重新连接
- 接收的数据以换行符(
\n或\r\n)为单位进行解析 - 关机指令必须与配置文件中的
shutdownWord完全匹配(区分大小写) - 串口重连后
start握手和blive心跳会自动重新启动 - 串口设备路径在设备重新插拔后可能变化(ttyUSB0 → ttyUSB1),建议使用 udev 规则绑定固定设备名
- 安装脚本会将选定的串口设备同时写入
config.json和send_signal.sh,确保两者一致
日志输出
程序运行时会输出以下日志信息:
- 配置加载状态
- 串口连接状态
start握手指令发送状态- 接收到的数据内容
- 关机指令触发和执行状态
- 串口错误和重连状态
关机钩子
系统关机时,/usr/lib/systemd/system-shutdown/send_signal.sh 会被 systemd 调用,在系统执行 poweroff 前通过串口向对端发送 ok\r\n,通知对端本机即将关机。
该脚本由安装脚本自动生成,其中 TTY_DEVICE 与 config.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 静态编译,无外部依赖