ESP8266 OTA之服务器更新

我之前介绍了两篇关于ESP8266的OTA更新方法:

说实话以上这两种方案除有点好玩其实没有什么实用性,由其在开发产品时上述的两种方案就是一种鸡肋,甚至可以说是不可用的。那现在市面上的各种智能设备是怎么更新固件的呢?

我使用过的绝大多数会进行固件更新的IoT设备都是先在手机上提示有新的固件可以更新,如果一确定以后就会自动下载并进行更新。那我们的ESP8266是否也能做到这样的效果呢?

答案显然是肯定的。本文所讲述的OTA做法其实才是做产品的正道。

首先你要准备一台静态文件服务器,并将某个目录作为更新文件存储。当然,如果你希望以后更方便地管理你发布的更新,那么你的更新文件就需要有良好的命名规则,关于这方面可以到百度上去搜一下找个命名规范或者按自己需要定义一套就OK了。

然后将自更新逻辑写入固件:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#define USE_SERIAL Serial

ESP8266WiFiMulti WiFiMulti;

void setup() {

    USE_SERIAL.begin(115200);
    // USE_SERIAL.setDebugOutput(true);

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    WiFi.mode(WIFI_STA);
    WiFiMulti.addAP("SSID", "PASSWORD");
}

void loop() {
    // wait for WiFi connection
    if((WiFiMulti.run() == WL_CONNECTED)) {

        t_httpUpdate_return ret = ESPhttpUpdate.update("http://server/file.bin"); // 编译好的固件文件

        switch(ret) {
            case HTTP_UPDATE_FAILED:
                USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
                break;

            case HTTP_UPDATE_NO_UPDATES:
                USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES");
                break;

            case HTTP_UPDATE_OK:
                USE_SERIAL.println("HTTP_UPDATE_OK");
                break;
        }
    }
}

看完以上代码是否是会有种想骂人的冲动?我当时找资料看ESP的OTA使用的正确姿势时也有种想骂娘的冲动:太TMD简单了!

原理就只是ESPhttpUpdate.update这个方法,调用一下就可以从服务器下载固件并自动更新了!

这个update方法是有多个重载版本的,上面只是用了其中一个最简单的重载版本,因此只有一个参数指向更新文件。

   // This function is deprecated, use rebootOnUpdate and the next one instead
    t_httpUpdate_return update(const String& url, const String& currentVersion,
                               const String& httpsFingerprint, bool reboot) __attribute__((deprecated));
    t_httpUpdate_return update(const String& url, const String& currentVersion = "");
    t_httpUpdate_return update(const String& url, const String& currentVersion,
                               const String& httpsFingerprint);
    t_httpUpdate_return update(const String& url, const String& currentVersion,
                               const uint8_t httpsFingerprint[20]); // BearSSL

    // This function is deprecated, use one of the overloads below along with rebootOnUpdate
    t_httpUpdate_return update(const String& host, uint16_t port, const String& uri, const String& currentVersion,
                               bool https, const String& httpsFingerprint, bool reboot) __attribute__((deprecated));

    t_httpUpdate_return update(const String& host, uint16_t port, const String& uri = "/",
                               const String& currentVersion = "");
    t_httpUpdate_return update(const String& host, uint16_t port, const String& url,
                               const String& currentVersion, const String& httpsFingerprint);
    t_httpUpdate_return update(const String& host, uint16_t port, const String& url,
                               const String& currentVersion, const uint8_t httpsFingerprint[20]); // BearSSL

以下是ESP8266httpUpdate的其它方法:

void rebootOnUpdate(bool reboot)  // 更新后重启
int getLastError(void); // 获取最后出错的错误编号
String getLastErrorString(void); // 获取出错的信息描述

固件更新服务器

以下是ESPhttpUpdate产生的请求头内容:

[HTTP_USER_AGENT] => ESP8266-http-Update [HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA [HTTP_X_ESP8266_AP_MAC] => 1A:FE:AA:AA:AA:AA [HTTP_X_ESP8266_FREE_SPACE] => 671744 [HTTP_X_ESP8266_SKETCH_SIZE] => 373940 [HTTP_X_ESP8266_CHIP_SIZE] => 524288 [HTTP_X_ESP8266_SDK_VERSION] => 1.3.0 [HTTP_X_ESP8266_VERSION] => DOOR-7-g14f53a19

你可以在更新服务器中检测这些请求头是符合法,同时也可以检测当前发出请求的ESP所使用的固件版本是最新的,如果服务端有新的版本可用就重定向到该文件然后就使ESP进行自更新。

以下是用PHP来写一个最简单的更新服务器:

<?PHP

header('Content-type: text/plain; charset=utf8', true);

function check_header($name, $value = false) {
    if(!isset($_SERVER[$name])) {
        return false;
    }
    if($value && $_SERVER[$name] != $value) {
        return false;
    }
    return true;
}

function sendFile($path) {
    header($_SERVER["SERVER_PROTOCOL"].' 200 OK', true, 200);
    header('Content-Type: application/octet-stream', true);
    header('Content-Disposition: attachment; filename='.basename($path));
    header('Content-Length: '.filesize($path), true);
    header('x-MD5: '.md5_file($path), true);
    readfile($path);
}

if(!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater!\n";
    exit();
}

if(
    !check_header('HTTP_X_ESP8266_STA_MAC') ||
    !check_header('HTTP_X_ESP8266_AP_MAC') ||
    !check_header('HTTP_X_ESP8266_FREE_SPACE') ||
    !check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
    !check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
    !check_header('HTTP_X_ESP8266_SDK_VERSION') ||
    !check_header('HTTP_X_ESP8266_VERSION')
) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater! (header)\n";
    exit();
}

$db = array(
    "18:FE:AA:AA:AA:AA" => "DOOR-7-g14f53a19",
    "18:FE:AA:AA:AA:BB" => "TEMP-1.0.0"
);

if(isset($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']])) {
    if($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION']) ) {
        sendFile("./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']]."bin");
    } else {
        header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
    }
    exit();
}

header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ESP8266 OTA升级是一种通过无线网络更新设备固件的方法。在Arduino中,可以使用ESP8266WiFi库和ESP8266HTTPUpdate库来实现OTA升级。首先,需要将设备连接到WiFi网络,然后使用HTTPUpdate库从服务器下载新的固件并更新设备。这种方法可以方便地更新设备,而无需将设备连接到计算机或使用编程器进行更新。 ### 回答2: ESP8266 OTA升级Arduino是一种便捷的方式,能够让我们省去了通过USB或串口连接板子进行上传的麻烦。在使用OTA升级之前,需要配置好Wi-Fi连接和局域网设置。 首先,我们需要使用Arduino IDE打开一个示例程序,这个程序需要以OTA的方式上传到Arduino板子上。在示例程序中,我们需要添加OTA库,来实现固件的OTA升级。具体步骤是:Sketch->Include Library->Manage Libraries->OTA->Install。 接下来需要修改OTA的SSID和密码,这是为了让我们的Arduino板子能够连接上Wi-Fi。修改的位置在OTA代码的WiFi.begin(ssid,password)这一行中。 然后我们需要在代码中加入一个标识,每次升级时比较版本号,以避免重复上传已经上传过的固件。我们可以通过把当前版本号写在代码的一个常量中,每次更新时对比这个版本号和上传固件中的版本号是否相同,来判断是否需要升级。 最后,我们需要打开“OTA port”,以便在本地局域网内访问Arduino板子。我们可以通过在代码中添加“ArduinoOTA.begin()”来完成打开OTA port的操作。 在此之后,我们就可以使用“Sketch->Upload using OTA”命令将程序通过OTA的形式上传到Arduino板子上,实现便捷的固件升级。相比传统的USB或串口上传方式,OTA升级更加方便快捷,极大提高了调试和开发效率。 ### 回答3: ESP8266是一款非常流行的Wi-Fi模块,它也可以被用来控制Arduino板子。OTA即Over-The-Air升级,是一种不需要通过串口或USB线连接板子就可以升级固件的方式,通过Wi-Fi实现。 实现ESP8266 OTA升级Arduino主要有两种方式:基于HTTPServer和基于MQTT。 基于HTTPServer的方式需要我们在ESP8266上搭建一个Web服务器,通过浏览器或者Python等程序向服务器发送固件升级信息。首先,我们需要使用ESP8266的WebServer库,搭建一个HTTP服务器,配置网络和路由,使其能够处理HTTP请求。然后我们需要在Arduino程序中定义一个固件升级的接口,将固件文件上传到这个接口,如果上传成功就将文件保存到SPIFFS文件系统中,接着重启系统切换到新的固件程序。 基于MQTT的OTA升级方式,则需要我们在ESP8266与Arduino中运用MQTT,通过MQTT传递消息。在ESP8266中,我们需要连接一个MQTT代理服务,监听指定主题。Arduino中的程序需要将当前版本号,固件信息和更新程序上传到MQTT代理上,这样ESP8266就能收到消息,进行升级操作了。 在进行ESP8266 OTA升级Arduino时,需要注意一下几点: 1. 电源充足:OTA升级需要大量网络传输和Flash读写操作,需要保证合适的供电 2. 固件安全:OTA升级开启后,需要考虑固件的安全性,防止文件被篡改 3. 程序稳定:OTA升级无疑会对当前程序造成影响,需要谨慎处理,确保升级后程序的稳定性和完整性。 总之,ESP8266 OTA升级Arduino需要考虑很多因素,但它可以有效提升开发效率和用户体验,是非常有价值的一个技术。如果你对此比较感兴趣,可以继续进行深入研究。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值