数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 70|回复: 2

通过电磁继电器控制硬盘供电实现热插拔

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
我的PCIE转SATA接口支持热插拔,如果你不确定,请不要这么玩。
任何情况导致的坏盘都不要怪我,我不负责。数据无价,珍爱存储。



我最近买了两个14T的盘,有一个常用,一个不常用,不常用的我做了一个USB转GPIO,控制电磁继电器的通断来控制硬盘的电源。

PCIE转SATA使用的是JMB585,支持热插拔,支持HM-SMR/AF格式
  1. lspci |grep JM
  2. 03:00.0 SATA controller: JMicron Technology Corp. JMB58x AHCI SATA controller
复制代码




简单来说就这样




一、USB转GPIO
我是使用了CH552,模拟了CP2112和AMC6821,实现了两个功能:1. USB to I2C + 8GPIO,2. PWM风扇调速和测温。 这两个功能在Linux是免驱的。
  1. cat /etc/modules-load.d/modules.conf

  2. # Generated by sensors-detect on Tue Nov 19 22:11:47 2024
  3. # Chip drivers
  4. coretemp
  5. it87

  6. amc6821

  7. sensors
  8. amc6821-i2c-1-18
  9. Adapter: CP2112 SMBus Bridge on hidraw0
  10. fan1:        1110 RPM  (min =  600 RPM, max = 6000 RPM)
  11. temp1:        +36.0°C  (low  =  -1.0°C, high = +70.0°C)
  12.                        (crit = +90.0°C)
  13. temp2:        +36.0°C  (low  =  -1.0°C, high = +70.0°C)
  14.                        (crit = +90.0°C)
  15. pwm1:             90%  (mode = pwm)  MANUAL CONTROL

  16. acpitz-acpi-0
  17. Adapter: ACPI interface
  18. temp1:        +43.0°C

  19. coretemp-isa-0000
  20. Adapter: ISA adapter
  21. Package id 0:  +44.0°C  (high = +105.0°C, crit = +105.0°C)
  22. Core 0:        +44.0°C  (high = +105.0°C, crit = +105.0°C)
  23. Core 1:        +44.0°C  (high = +105.0°C, crit = +105.0°C)
  24. Core 2:        +44.0°C  (high = +105.0°C, crit = +105.0°C)
  25. Core 3:        +44.0°C  (high = +105.0°C, crit = +105.0°C)
复制代码
控制pwm转速:
  1. echo 180 > `find /sys -name "pwm1"`
复制代码
控制GPIO6、7断开、闭合
  1. gpioset -c 0 6=0 7=0
  2. gpioset -c 0 6=1 7=1
复制代码


二、继电器
某宝买的2路继电器,4.71元,然后连接一大堆电线,很乱。


三、脚本集成
使用方法
  1. ./manage_14t.sh {start|stop}
  2.   start : 执行硬盘上电、检测、休眠配置及挂载
  3.   stop  : 执行安全刷盘、卸载、内核软弹出及断电
复制代码



脚本源码:
  1. cat manage_14t.sh
  2. #!/bin/bash

  3. # ==================== 配置项 ====================
  4. MOUNT_POINT="/media/14t-2"
  5. DISK_ID="/dev/disk/by-id/wwn-0x5000cca274XXXXXX"
  6. TIMEOUT=500
  7. # ================================================

  8. # 确保以 root 权限运行
  9. if [ "$EUID" -ne 0 ]; then
  10.     echo "错误:请使用 root 权限或 sudo 运行此脚本。"
  11.     exit 1
  12. fi

  13. # 打印使用说明
  14. usage() {
  15.     echo "使用方法: $0 {start|stop}"
  16.     echo "  start : 执行硬盘上电、检测、休眠配置及挂载"
  17.     echo "  stop  : 执行安全刷盘、卸载、内核软弹出及断电"
  18.     exit 1
  19. }

  20. # 1. 上电与挂载流程
  21. do_start() {
  22.     echo "=== 开始执行上电与挂载流程 ==="

  23.     # 检查是否已挂载
  24.     if mountpoint -q "$MOUNT_POINT"; then
  25.         echo "提示:分区 $MOUNT_POINT 已经挂载,无需重复操作。"
  26.         exit 0
  27.     fi

  28.     # 检查设备节点是否存在
  29.     if [ ! -e "$DISK_ID" ]; then
  30.         echo "未检测到设备节点,开始执行硬盘上电控制..."

  31.         # 异步执行上电命令,2秒后结束进程
  32.         gpioset -c 0 6=1 7=1 &
  33.         GPIO_PID=$!
  34.         sleep 2
  35.         kill $GPIO_PID 2>/dev/null
  36.         echo "电磁继电器上电信号已发送。"

  37.         # 循环检查设备节点是否出现,设置超时
  38.         echo "正在等待系统识别硬盘分区(最多等待 ${TIMEOUT} 秒)..."
  39.         ELAPSED=0
  40.         while [ ! -e "$DISK_ID" ]; do
  41.             if [ $ELAPSED -ge $TIMEOUT ]; then
  42.                 echo "错误:等待超时,系统在 ${TIMEOUT} 秒内未识别到硬盘,挂载失败。"
  43.                 exit 1
  44.             fi
  45.             sleep 1
  46.             ((ELAPSED++))

  47.             # 每 10 秒打印一次进度
  48.             if [ $((ELAPSED % 10)) -eq 0 ]; then
  49.                 echo "已等待 $ELAPSED 秒..."
  50.             fi
  51.         done
  52.         echo "硬盘节点已成功识别!"

  53.         # 触发内核重新扫描,加速 Btrfs 节点就绪
  54.         echo "正在触发系统块设备重新扫描..."
  55.         partprobe 2>/dev/null || udevadm settle
  56.     fi

  57.     # 获取真实设备名并设置 30 分钟休眠策略
  58.     REAL_DEV=$(basename "$(readlink -f "$DISK_ID")")
  59.     echo "正在为 /dev/$REAL_DEV 设置 30 分钟自动休眠策略 (hdparm -S 241)..."
  60.     hdparm -S 241 "/dev/$REAL_DEV"

  61.     # 执行挂载
  62.     echo "正在执行 mount -a 挂载硬盘分区..."
  63.     echo "提示:由于是 Btrfs + SMR 硬盘,挂载过程可能会比较慢,请耐心等待..."

  64.     if mount -a; then
  65.         if mountpoint -q "$MOUNT_POINT"; then
  66.             echo "成功:硬盘分区已成功挂载到 $MOUNT_POINT!"
  67.         else
  68.             echo "警告:mount -a 执行成功,但未能在 $MOUNT_POINT 找到该分区,请检查 /etc/fstab 配置。"
  69.             exit 1
  70.         fi
  71.     else
  72.         echo "错误:mount -a 执行失败。"
  73.         exit 1
  74.     fi
  75. }

  76. # 2. 卸载与断电流程
  77. do_stop() {
  78.     echo "=== 开始执行安全卸载与断电流程 ==="

  79.     # 检查并执行卸载
  80.     if ! mountpoint -q "$MOUNT_POINT"; then
  81.         echo "提示:分区 $MOUNT_POINT 本就未挂载。"
  82.     else
  83.         echo "正在将缓存数据同步到硬盘 (sync),请稍候..."
  84.         sync

  85.         echo "正在卸载 $MOUNT_POINT..."
  86.         if umount "$MOUNT_POINT"; then
  87.             echo "成功:分区 $MOUNT_POINT 已成功卸载。"
  88.         else
  89.             echo "错误:卸载失败!硬盘可能正被进程占用。"
  90.             echo "当前占用进程如下:"
  91.             lsof "$MOUNT_POINT" 2>/dev/null || fuser -v "$MOUNT_POINT" 2>/dev/null
  92.             echo "请手动关闭上述进程或释放目录后再试。"
  93.             exit 1
  94.         fi
  95.     fi

  96.     # 检查设备节点是否存在,执行软弹出
  97.     if [ -e "$DISK_ID" ]; then
  98.         REAL_DEV=$(basename "$(readlink -f "$DISK_ID")")

  99.         if [ -b "/dev/$REAL_DEV" ]; then
  100.             echo "正在通知硬盘执行立即休眠 (hdparm -y)..."
  101.             hdparm -y "/dev/$REAL_DEV" 2>/dev/null
  102.             sleep 3 # 给 14T 盘片留出完全平稳停转的时间

  103.             echo "正在向内核发送设备移除指令,优雅注销设备节点..."
  104.             echo 1 > "/sys/block/$REAL_DEV/device/delete"
  105.             sleep 2
  106.         fi
  107.     fi

  108.     # 执行物理断电
  109.     echo "内核已安全卸载设备,开始执行硬盘物理断电控制..."
  110.     gpioset -c 0 6=0 7=0 &
  111.     GPIO_PID=$!
  112.     sleep 2
  113.     kill $GPIO_PID 2>/dev/null
  114.     echo "电磁继电器断电信号已发送。"

  115.     # 最终结果验证
  116.     if [ ! -e "$DISK_ID" ]; then
  117.         echo "安全断电完成:硬盘设备已彻底安全移除,dmesg 无异常报错。"
  118.     else
  119.         echo "提示:设备节点注销较慢,但物理断电信号已安全发出。"
  120.     fi
  121. }

  122. # 参数路由分发
  123. case "$1" in
  124.     start)
  125.         do_start
  126.         ;;
  127.     stop)
  128.         do_stop
  129.         ;;
  130.     *)
  131.         usage
  132.         ;;
  133. esac
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 2 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 16 分钟前 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|数码之家-技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-8-31 13:45 , Processed in 0.140400 second(s), 12 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

快速回复 返回顶部 返回列表