244 lines
7.1 KiB
Markdown
244 lines
7.1 KiB
Markdown
# 串口关机控制器
|
||
|
||
通过串口接收指令触发 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 转串口:
|
||
```json
|
||
{
|
||
"port": "/dev/ttyUSB0",
|
||
"baudRate": 115200,
|
||
"shutdownWord": "SHUTDOWN"
|
||
}
|
||
```
|
||
|
||
使用 USB CDC:
|
||
|
||
```json
|
||
{
|
||
"port": "/dev/ttyACM0",
|
||
"baudRate": 115200,
|
||
"shutdownWord": "SHUTDOWN"
|
||
}
|
||
```
|
||
|
||
使用主板原生串口:
|
||
|
||
```json
|
||
{
|
||
"port": "/dev/ttyS0",
|
||
"baudRate": 115200,
|
||
"shutdownWord": "SHUTDOWN"
|
||
}
|
||
```
|
||
|
||
## 交叉编译
|
||
|
||
本程序在 Windows 上开发,需要交叉编译为 x86 Linux 可执行文件:
|
||
|
||
```bash
|
||
set GOOS=linux
|
||
set GOARCH=amd64
|
||
set CGO_ENABLED=0
|
||
go build -o shutdown shutdown.go
|
||
```
|
||
|
||
PowerShell 环境:
|
||
|
||
```powershell
|
||
$env:GOOS = "linux"
|
||
$env:GOARCH = "amd64"
|
||
$env:CGO_ENABLED = "0"
|
||
go build -o shutdown shutdown.go
|
||
```
|
||
|
||
编译产物 `shutdown` 为 Linux x86_64 可执行文件,需上传至目标 Ubuntu 系统运行。
|
||
|
||
## 部署与运行
|
||
|
||
### 方式一:使用安装脚本(推荐)
|
||
|
||
项目提供 `install.sh` 安装脚本,可自动完成串口选择、配置生成、服务安装等全部流程。
|
||
|
||
#### 上传项目到目标系统
|
||
|
||
```bash
|
||
scp -r ./ user@<目标IP>:/home/user/shutdown/
|
||
```
|
||
|
||
#### 运行安装脚本
|
||
|
||
```bash
|
||
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`
|
||
|
||
#### 安装后管理
|
||
|
||
```bash
|
||
# 查看服务状态
|
||
systemctl status ttyshutdown
|
||
|
||
# 查看实时日志
|
||
journalctl -u ttyshutdown -f
|
||
|
||
# 停止服务
|
||
systemctl stop ttyshutdown
|
||
|
||
# 更换串口
|
||
sudo bash change_port.sh
|
||
|
||
# 卸载
|
||
sudo bash uninstall.sh
|
||
```
|
||
|
||
### 更换串口
|
||
|
||
当需要更换串口设备时(如更换 USB 端口、更换转接器等),使用 `change_port.sh` 脚本可自动完成配置更新和服务重启。
|
||
|
||
```bash
|
||
sudo bash change_port.sh
|
||
```
|
||
|
||
#### 更换流程
|
||
|
||
1. **显示当前配置** - 展示当前串口设备、波特率、关机指令
|
||
2. **选择新串口** - 自动扫描系统中可用串口,当前使用的串口会标注 `<-- 当前`,交互选择或手动输入新路径
|
||
3. **可选修改参数** - 波特率和关机指令可直接回车保持不变,或输入新值修改
|
||
4. **确认更改** - 显示新旧配置对比供确认
|
||
5. **执行更改** - 同时更新 `config.json` 和 `send_signal.sh`,并自动重启 `ttyshutdown` 服务
|
||
|
||
> 脚本会同时更新 `config.json` 和 `send_signal.sh` 中的串口配置,确保两者一致。
|
||
|
||
### 方式二:手动部署
|
||
|
||
#### 1. 上传到目标系统
|
||
|
||
```bash
|
||
scp shutdown config.json user@<目标IP>:/home/user/shutdown/
|
||
```
|
||
|
||
#### 2. 添加执行权限
|
||
|
||
```bash
|
||
chmod +x shutdown
|
||
```
|
||
|
||
#### 3. 运行程序
|
||
|
||
```bash
|
||
sudo ./shutdown
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
1. 程序需要 root 权限才能执行系统关机命令
|
||
2. 串口断开后会每 5 秒尝试重新连接
|
||
3. 接收的数据以换行符(`\n` 或 `\r\n`)为单位进行解析
|
||
4. 关机指令必须与配置文件中的 `shutdownWord` 完全匹配(区分大小写)
|
||
5. 串口重连后 `start` 握手和 `blive` 心跳会自动重新启动
|
||
6. 串口设备路径在设备重新插拔后可能变化(ttyUSB0 → ttyUSB1),建议使用 udev 规则绑定固定设备名
|
||
7. 安装脚本会将选定的串口设备同时写入 `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 静态编译,无外部依赖
|