WEBKT

使用 MQTT 协议远程触发树莓派 OTA 更新:告别 GPIO 引脚的依赖

145 0 0 0

在物联网 (IoT) 项目中,树莓派 (Raspberry Pi) 经常被用作边缘计算设备。为了方便管理和维护,远程更新这些设备至关重要。传统的 OTA (Over-The-Air) 更新方法可能依赖于 GPIO 引脚触发,但这在某些场景下并不方便。本文将探讨如何使用 MQTT (Message Queuing Telemetry Transport) 协议来远程触发树莓派的 OTA 更新,从而摆脱对 GPIO 引脚的依赖,实现更灵活的远程管理。

为什么选择 MQTT?

MQTT 是一种轻量级的发布/订阅消息协议,特别适合在低带宽、不可靠的网络环境下进行通信。它的主要优点包括:

  • 轻量级: 协议头部非常小,节省带宽。
  • 发布/订阅模式: 设备只需要订阅感兴趣的主题,无需知道发布者的具体信息。
  • QoS (Quality of Service): 支持不同的服务质量等级,保证消息的可靠传输。
  • 易于实现: 许多编程语言和平台都有 MQTT 客户端库。

实现步骤

  1. 准备工作

    • 树莓派: 准备一台已经安装好操作系统(例如 Raspberry Pi OS)的树莓派。

    • MQTT Broker: 选择一个 MQTT Broker,例如 Mosquitto (开源)、EMQX (开源) 或 CloudMQTT (云服务)。本文以 Mosquitto 为例。

    • 开发环境: 准备好 Python 开发环境,并安装 paho-mqtt 库 (用于 MQTT 客户端)。

      sudo apt-get update
      sudo apt-get install mosquitto mosquitto-clients
      pip3 install paho-mqtt
      
  2. 配置 MQTT Broker

    • 安装 Mosquitto: 如果选择 Mosquitto,可以使用以下命令安装:

      sudo apt-get install mosquitto mosquitto-clients
      
    • 配置 Mosquitto: 默认情况下,Mosquitto 允许匿名访问。为了安全起见,建议配置用户名和密码。

      • 创建密码文件:

        sudo mosquitto_passwd -c /etc/mosquitto/passwd <用户名>
        
      • 修改 Mosquitto 配置文件 /etc/mosquitto/mosquitto.conf,添加以下内容:

        allow_anonymous false
        password_file /etc/mosquitto/passwd
        
      • 重启 Mosquitto 服务:

        sudo systemctl restart mosquitto
        
  3. 树莓派端 MQTT 客户端

    • 编写 Python 脚本: 在树莓派上编写一个 Python 脚本,用于连接 MQTT Broker,订阅一个特定的主题 (例如 rpi/ota/trigger),并监听 OTA 更新指令。

      import paho.mqtt.client as mqtt
      import subprocess
      import os
      
      MQTT_BROKER = "<你的 MQTT Broker 地址>"
      MQTT_PORT = 1883  # 默认端口
      MQTT_USER = "<你的 MQTT 用户名>"
      MQTT_PASSWORD = "<你的 MQTT 密码>"
      MQTT_TOPIC = "rpi/ota/trigger"
      
      def on_connect(client, userdata, flags, rc):
          print("Connected with result code " + str(rc))
          client.subscribe(MQTT_TOPIC)
      
      def on_message(client, userdata, msg):
          print(msg.topic + " " + str(msg.payload.decode()))
          if msg.payload.decode() == "update":
              print("Received OTA update trigger. Starting update...")
              # 执行 OTA 更新脚本
              try:
                  subprocess.run(["/home/pi/ota_update.sh"], check=True) # 确保脚本具有执行权限
              except subprocess.CalledProcessError as e:
                  print(f"OTA update script failed with error: {e}")
      
      client = mqtt.Client()
      client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
      client.on_connect = on_connect
      client.on_message = on_message
      
      client.connect(MQTT_BROKER, MQTT_PORT, 60)
      
      client.loop_forever()
      
    • 创建 OTA 更新脚本 (ota_update.sh): 这个脚本负责执行实际的 OTA 更新过程。这部分逻辑根据你的实际 OTA 方案而定。以下是一个简单的示例,假设使用 apt-get update && apt-get upgrade 来更新系统:

      #!/bin/bash
      
      echo "Starting OTA update..."
      sudo apt-get update
      sudo apt-get upgrade -y
      echo "OTA update completed."
      sudo reboot # 可选:更新完成后重启
      

      重要提示:

      • 安全性: OTA 更新脚本需要小心编写,避免引入安全漏洞。例如,不要从不可信的来源下载软件包。
      • 错误处理: 脚本需要处理各种错误情况,例如网络连接失败、软件包下载失败等。
      • 原子性: 尽量保证 OTA 更新的原子性,即要么完全成功,要么完全失败,避免更新过程中断导致系统损坏。
      • 权限: 确保 ota_update.sh 脚本具有执行权限 (chmod +x ota_update.sh)。
    • 运行 MQTT 客户端脚本: 使用以下命令运行 Python 脚本:

      python3 your_mqtt_client.py
      
  4. 远程触发 OTA 更新

    • 使用 MQTT 客户端工具: 可以使用 mosquitto_pub 命令或其他 MQTT 客户端工具来发布消息到 rpi/ota/trigger 主题,触发 OTA 更新。

      mosquitto_pub -h <你的 MQTT Broker 地址> -u <你的 MQTT 用户名> -P <你的 MQTT 密码> -t rpi/ota/trigger -m "update"
      
    • 编写控制程序: 也可以编写一个控制程序 (例如 Python 脚本或 Web 应用),通过 MQTT 协议远程触发 OTA 更新。

总结

通过使用 MQTT 协议,我们可以方便地远程触发树莓派的 OTA 更新,而无需依赖 GPIO 引脚。这种方法具有更高的灵活性和可扩展性,特别适合大规模部署的 IoT 设备。在实际应用中,需要根据具体的 OTA 方案和安全需求,对 OTA 更新脚本进行定制和优化。

一些建议

  • 差分更新: 使用差分更新技术可以减少 OTA 更新的数据量,节省带宽。
  • A/B 分区: 使用 A/B 分区可以提高 OTA 更新的可靠性,避免更新失败导致系统无法启动。
  • 监控: 实施监控机制,可以实时了解 OTA 更新的进度和状态。

希望本文能帮助你使用 MQTT 协议实现树莓派的远程 OTA 更新。

嵌入式老司机 MQTT树莓派OTA 更新

评论点评