WEBKT

基于GPIO触发的树莓派OTA更新:SFTP自动下载与安装实战

129 0 0 0

在物联网(IoT)应用中,远程设备更新至关重要。本文将探讨如何在树莓派上实现一个由GPIO触发的OTA(Over-The-Air)更新机制。当特定的GPIO引脚被拉高时,树莓派将通过SFTP从指定服务器下载最新的应用程序二进制文件,并执行预设的安装脚本,从而实现远程设备的自动升级。

一、准备工作

  1. 树莓派环境: 确保你已经安装了最新版本的Raspberry Pi OS,并且可以正常连接到互联网。
  2. SFTP服务器: 你需要一个SFTP服务器来存放你的应用程序二进制文件和安装脚本。可以使用现有的服务器,或者在本地搭建一个。例如,使用openssh-server在Linux服务器上搭建SFTP服务。
  3. 应用程序二进制文件和安装脚本: 准备好你需要部署到树莓派上的应用程序二进制文件,以及一个用于安装、配置和启动该应用程序的shell脚本。

二、实现步骤

  1. 配置SSH免密登录

    为了让树莓派能够自动从SFTP服务器下载文件,我们需要配置SSH免密登录。这可以通过生成SSH密钥对并将其公钥添加到SFTP服务器的authorized_keys文件中来实现。

    • 在树莓派上生成SSH密钥对:

      ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
      
    • 将公钥复制到SFTP服务器的authorized_keys文件中:

      ssh-copy-id -i ~/.ssh/id_rsa.pub user@sftp_server_ip
      
    • 测试免密登录:

      ssh user@sftp_server_ip
      

      如果不需要输入密码即可登录,则说明免密登录配置成功。

  2. 编写下载和安装脚本

    创建一个shell脚本(例如update.sh),用于从SFTP服务器下载最新的应用程序二进制文件并执行安装脚本。

    #!/bin/bash
    
    # 定义SFTP服务器的地址、用户名、远程文件路径和本地保存路径
    SFTP_SERVER="user@sftp_server_ip"
    REMOTE_FILE="/path/to/latest/application"
    LOCAL_FILE="/home/pi/application"
    INSTALL_SCRIPT="/home/pi/install.sh"
    
    # 使用sftp下载文件
    sftp -o StrictHostKeyChecking=no "$SFTP_SERVER:$REMOTE_FILE" "$LOCAL_FILE"
    
    # 检查下载是否成功
    if [ $? -eq 0 ]; then
        echo "File downloaded successfully."
    else
        echo "File download failed."
        exit 1
    fi
    
    # 赋予执行权限
    chmod +x "$LOCAL_FILE"
    
    # 执行安装脚本
    bash "$INSTALL_SCRIPT"
    
    # 检查安装脚本是否成功执行
    if [ $? -eq 0 ]; then
        echo "Installation script executed successfully."
    else
        echo "Installation script execution failed."
        exit 1
    fi
    
    echo "Update completed."
    

    注意事项:

    • StrictHostKeyChecking=no 参数用于避免在第一次连接SFTP服务器时出现主机密钥验证提示。在生产环境中,建议使用更安全的密钥验证方式。
    • 根据实际情况修改脚本中的变量,包括SFTP服务器地址、用户名、远程文件路径、本地保存路径和安装脚本路径。
    • 安装脚本(install.sh)需要包含安装、配置和启动应用程序的必要步骤。例如,停止旧版本、复制新文件、更新配置文件、启动新版本等。
  3. 编写GPIO监控脚本

    创建一个Python脚本(例如gpio_monitor.py),用于监控指定的GPIO引脚。当该引脚被拉高时,执行update.sh脚本。

    import RPi.GPIO as GPIO
    import time
    import subprocess
    
    # 定义GPIO引脚
    GPIO_PIN = 17  # 修改为你实际使用的GPIO引脚
    
    # 设置GPIO模式
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(GPIO_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    
    # 定义更新函数
    def update_application():
        print("GPIO triggered, starting update...")
        try:
            subprocess.run(['/home/pi/update.sh'], check=True)
            print("Update process completed.")
        except subprocess.CalledProcessError as e:
            print(f"Error during update: {e}")
    
    # 循环监控GPIO引脚
    try:
        while True:
            if GPIO.input(GPIO_PIN) == GPIO.HIGH:
                update_application()
                time.sleep(5)  # 避免重复触发
            time.sleep(0.1)
    except KeyboardInterrupt:
        print("Exiting...")
    finally:
        GPIO.cleanup()
    

    注意事项:

    • 确保已经安装了RPi.GPIO库:sudo apt-get install python3-rpi.gpio
    • GPIO_PIN变量修改为你实际使用的GPIO引脚。
    • pull_up_down=GPIO.PUD_DOWN 设置下拉电阻,确保在没有外部信号时,引脚处于低电平状态。
    • time.sleep(5) 用于避免由于引脚抖动或持续高电平而导致重复触发更新。
  4. 设置开机自启动

    为了让GPIO监控脚本在树莓派启动时自动运行,你可以将其添加到rc.local文件中。

    • 编辑rc.local文件:

      sudo nano /etc/rc.local
      
    • exit 0之前添加以下内容:

      sudo python3 /home/pi/gpio_monitor.py &
      
    • 保存并关闭文件。

    注意事项:

    • 确保rc.local文件具有执行权限:sudo chmod +x /etc/rc.local
    • & 符号用于在后台运行脚本,避免阻塞启动过程。

三、测试

  1. 将最新的应用程序二进制文件和安装脚本上传到SFTP服务器。
  2. 将指定的GPIO引脚拉高(例如,使用跳线连接到3.3V引脚)。
  3. 观察树莓派是否自动下载并安装了最新的应用程序。
  4. 检查应用程序是否正常运行。

四、安全考虑

  • SFTP服务器安全: 确保SFTP服务器具有足够的安全措施,例如使用强密码、限制IP访问等。
  • 代码签名: 对应用程序二进制文件进行签名,并在安装脚本中验证签名,以防止恶意代码被部署到设备上。
  • 错误处理: 在脚本中添加完善的错误处理机制,以便在更新过程中出现问题时能够及时发现并采取相应的措施。
  • 回滚机制: 实现回滚机制,以便在更新失败时能够恢复到之前的版本。

五、总结

本文介绍了如何在树莓派上实现一个由GPIO触发的OTA更新机制。通过配置SSH免密登录、编写下载和安装脚本、编写GPIO监控脚本以及设置开机自启动,可以实现远程设备的自动升级。同时,也需要考虑安全性问题,并采取相应的安全措施,以确保设备的安全性。这种方法适用于需要在特定事件触发时进行更新的场景,例如,当检测到新的传感器数据或接收到特定的指令时。

自动化极客 树莓派OTA更新GPIO触发

评论点评