2026-05-19 14:58:08 +08:00
2026-05-14 17:53:52 +08:00
2026-05-14 17:53:52 +08:00
2026-05-19 14:58:08 +08:00

Poweroff Protection

基于 STM32 + Linux 的安全断电保护系统。当主电源断开时STM32 通知 Linux 主机执行关机,等待关机完成后再切断继电器电源,避免数据损坏。

目前5块板子仅id:0的板子可以正常使用USB与RS232口进行通信其余板子由于硬件问题目前仅支持USB进行通信。

系统架构

主 12V 电源 ──┬──> [Main12V_In]  STM32F103C8  [Relay_out] ──> 继电器 ──> Linux 主机电源
              │                      │
              │                  UART / USB CDC
              │                      │
              └──────────────── Linux 主机 (poweroff_linux)

通信协议

方向 指令 说明
Linux → STM32 start 启动监控循环
STM32 → Linux Alive 心跳请求
Linux → STM32 blive 心跳应答
STM32 → Linux SHUTDOWN 通知主机立即关机
Linux → STM32 ok 关机完成确认

工作流程

  1. Linux 端连接串口,发送 start
  2. STM32 进入监控循环,持续发送 Alive 并等待 blive 应答5 秒超时)
  3. 当检测到主 12V 电源断开(连续 10 次读取为高或心跳超时STM32 发送 SHUTDOWN
  4. 等待 Linux 回复 ok(最长 60 秒)
  5. 收到 ok 后延迟 10 秒,拉高继电器引脚切断主机电源

目录结构

poweroff/
├── poweroff_stm32/        # STM32 固件 (Keil MDK 工程)
│   ├── Core/              # 用户代码 (main.c, gpio.c, usart.c)
│   ├── Drivers/           # HAL 驱动 + CMSIS
│   ├── Middlewares/        # USB CDC 中间件
│   ├── USB_DEVICE/        # USB 设备配置
│   └── MDK-ARM/           # Keil 工程文件
│
└── poweroff_linux/        # Linux 端 Go 程序
    ├── shutdown.go        # 主程序
    ├── shutdown           # 预编译二进制
    ├── config.json        # 配置文件
    ├── install.sh         # 安装脚本
    ├── uninstall.sh       # 卸载脚本
    ├── change_port.sh     # 更换串口脚本
    ├── send_signal.sh     # 关机信号钩子
    ├── ttyshutdown.service
    ├── go.mod
    └── go.sum

硬件引脚 (STM32F103C8)

引脚 端口 功能
SHUT PB4 关机指示(低电平有效)
RUN PB5 运行指示灯
Relay_out PB6 继电器控制(高电平切断电源)
Main12V_In PB7 主 12V 电源检测
USART1_TX PA9 串口发送
USART1_RX PA10 串口接收
USB PA11/PA12 USB CDC 通信

安装

硬件准备

  • STM32F103C8 最小系统板Blue Pill
  • 继电器模块(低电平触发),用于控制 Linux 主机电源
  • USB 转 TTL 串口模块(如 CH340/CP2102或 USB 数据线
  • J-Link / ST-Link 下载器
  • 12V 主电源

接线

STM32                外设
─────                ────
PB6  (Relay_out) ──> 继电器信号端
PB7  (Main12V_In)──> 主 12V 电源检测(需分压至 3.3V
PB5  (RUN)        ──> LED 指示灯
PB4  (SHUT)       ──> 关机状态指示灯

PA9  (USART1_TX)  ──> 串口模块 RX
PA10 (USART1_RX)  ──> 串口模块 TX

USB (PA11/PA12)   ──> Linux 主机 USB 口(使用 USB CDC 时)

注意12V 电源检测引脚需通过电阻分压将电压降至 3.3V 以下,避免损坏 STM32。推荐使用 10k + 3.3k 电阻分压。

STM32 固件编译与烧录

前置要求

  • Keil MDK-ARM v5.38+
  • STM32F1xx DFP (Device Family Pack),通过 Pack Installer 安装
  • J-Link 驱动或 ST-Link 驱动

编译

  1. 打开 Keil选择 Project → Open Project
  2. 加载 poweroff_stm32/MDK-ARM/poweroff_protection.uvprojx
  3. 点击 Build (F7) 编译

烧录

  1. 连接 J-Link / ST-Link 到 STM32 的 SWDIO、SWCLK、GND
  2. 在 Keil 中选择 Flash → Download (F8) 烧录
  3. 也可以使用 poweroff_stm32/MDK-ARM/poweroff_protection/poweroff_protection.hex 配合 ST-Link Utility 独立烧录

Linux 端安装

前置要求

  • Linux 主机(需要 shutdown 命令权限)
  • 串口设备已接入USB 转串口模块或 USB CDC
  • shutdown 预编译二进制文件已放在 poweroff_linux/ 目录下

编译(可选)

如需从源码编译:

cd poweroff_linux
go build -o shutdown .

install.sh — 一键安装

安装脚本会交互式引导你完成配置,自动部署为 systemd 服务。

cd poweroff_linux
sudo bash install.sh

运行后脚本会:

  1. 扫描串口 — 自动检测已接入的串口设备ttyUSB / ttyACM / ttyS以列表形式供你选择也可手动输入路径
  2. 配置参数 — 按提示设置波特率(默认 115200和关机指令默认 SHUTDOWN),回车保持默认
  3. 确认安装 — 显示完整配置,确认后执行安装
  4. 自动部署 — 将二进制和配置文件安装到 /opt/ttyshutdown/,生成 systemd 服务,安装关机钩子,启用并启动服务

安装完成后:

# 查看服务状态
systemctl status ttyshutdown

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

uninstall.sh — 卸载

cd poweroff_linux
sudo bash uninstall.sh

卸载脚本会依次执行:

  1. 停止并禁用 ttyshutdown 服务
  2. 删除 systemd 服务文件 /etc/systemd/system/ttyshutdown.service
  3. 删除关机钩子 /usr/lib/systemd/system-shutdown/send_signal.sh
  4. 删除安装目录 /opt/ttyshutdown/

执行前会要求确认(输入 y)。

change_port.sh — 更换串口

当串口设备变化(如更换 USB 口、换用不同串口模块)时使用:

cd poweroff_linux
sudo bash change_port.sh

运行后脚本会:

  1. 显示当前配置 — 读取 /opt/ttyshutdown/config.json,展示当前串口、波特率、关机指令
  2. 扫描新串口 — 列出可用设备,当前使用的串口会标记 <-- 当前
  3. 修改参数 — 选择新串口后,可一并修改波特率和关机指令(回车保持原值)
  4. 确认更改 — 显示变更对比(如 串口设备: /dev/ttyUSB0 -> /dev/ttyACM0
  5. 生效 — 自动更新 config.json 和关机钩子 send_signal.sh,并重启服务

常用命令

# 查看服务状态
systemctl status ttyshutdown

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

# 手动重启服务
sudo systemctl restart ttyshutdown

# 手动停止服务
sudo systemctl stop ttyshutdown

通信说明

STM32 支持 UART 和 USB CDC 双通道,收到 start 指令时自动切换到对应通道:

  • 通过串口模块发送 start → 使用 UART 通道
  • 通过 USB CDC 发送 start → 使用 USB CDC 通道

程序会自动重连串口,每秒发送 blive 心跳,收到 SHUTDOWN 指令后执行 shutdown -h now

Description
工控机断电保护
Readme 6.3 MiB
Languages
C 99.3%
Shell 0.3%
Assembly 0.3%