1. OTA是什么 OTA(Over The Air),通常也称为FOTA(Firmware Over The Air),意思是硬件中的固件通过无线升级版本。众所周知,硬件固件的部署,以及固件版本升级颇为繁琐,很多时候得通过人工完成,成本很高。所以OTA是一个颇为实用、也是很实惠的功能。 手环等设备,其实也有这类问题,一般都是通过APP升级-> ->蓝牙固件升级的方式。
2. 乐鑫对OTA的支持 ESP8266的厂商乐鑫提供了FOTA的功能,AT固件和NONSDK的都支持。 根据官方资料,乐鑫的FOTA是通过HTTP协议实现,且支持自建FOTA下载服务(WEB服务器)。 但乐鑫对常用功能和传感器的支持力度较少,需要不停造轮子、找轮子,效率相对较低。 在乐鑫以外,esp-open-rtos等也可以支持OTA功能,该有的功能都已经具备。 加之对mqtt、传感器的驱动支持更好,因此esp-open-rtos是个不错的选择, 本文基于esp-open-rtos的OTA实现了在线升级的简单例子,并对原理进行说明。 关于esp-open-rtos详细,可参照前文http://blog.csdn.net/ydogg/article/details/75194902
3. Esp-open-rtos的OTA简介 Esp-open-rtos的OTA实现也很简洁: 通过tftp协议在线下载固件,利用rboot进行新旧固件的切换和硬件重启。
其中固件下载支持client和server两种模式,可根据具体情况选择一种,也可同时使用。 Client模式下,是从tftp服务器中下载固件; Server模式下,是esp8266作为tftp服务,接收tftp客户端发送的新固件。
总的来说,Client模式更加灵活些,可以通过各种事件进行触发(如mqtt通知),且硬件侧的负载更轻。 本文基于Client模式进行说明。
4. OTA环境准备
主要是tftp的安装,下面命令以CentOS为例:
1 yum install tftp-server tftp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 默认情况下tftp是托管给xinit,其配置文件位于/etc/xinit.d/tftp,内容如下: service tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /var/lib/tftpboot -c disable = yes per_source = 11 cps = 100 2 flags = IPv4 }
server_args中 –s指明了tftp服务所使用的磁盘路径;如果需要上传,需要增加-c选项。 在OTA只需要下载,因此可以不开启-c。(直接复制新固件到/var/lib/tftpboot下即可)
测试:
如果能成功取得xxx.bin,说明tftp服务正常。 另外, tftp的端口为69,如有防火墙,注意相关设置需要放开。
5. OTA代码准备
在esp-open-rtos/examples/ota_basic下,有OTA的示例代码, 但因为有固件验证等功能,略复杂,理解方便起见,精简为如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #include <string.h> #include "espressif/esp_common.h" #include "esp/uart.h" #include "FreeRTOS.h" #include "task.h" #include "esp8266.h" #include "ssid_config.h" #include "ota-tftp.h" #include "rboot-api.h" #define TFTP_IMAGE_SERVER "192.168.31.192" #define TFTP_IMAGE_FILENAME1 "fm1.bin" #define TFTP_IMAGE_FILENAME2 "fm2.bin" void download_and_restart (char * filename) { if ( !filename ) { return ; } rboot_config conf = rboot_get_config(); int slot = (conf.current_rom + 1 ) % conf.count; if (slot == conf.current_rom) { printf ("FATAL ERROR: Only one OTA slot is configured!¥n" ); return ; } printf ("Downloading %s to slot %d...¥n" , filename, slot); int res = ota_tftp_download(TFTP_IMAGE_SERVER, TFTP_PORT, filename, 1000 , slot, NULL ); printf ("ota_tftp_download %s result %d¥n" , filename, res); if ( res != 0 ) { return ; } uint32_t length = 0 ; bool valid = rboot_verify_image(conf.roms[slot], &length, NULL ); if ( !valid ) { printf ("Not valid after all :(¥n" ); return ; } printf ("Rebooting into slot %d...¥n" , slot); rboot_set_current_rom(slot); sdk_system_restart(); } void update_fm_task (void *pvParameters) { printf ("update task starting...¥n" ); while (1 ) { vTaskDelay(20000 / portTICK_PERIOD_MS); download_and_restart(TFTP_IMAGE_FILENAME2); } } void user_init (void ) { uart_set_baud(0 , 115200 ); rboot_config conf = rboot_get_config(); printf ("¥r¥n¥r¥nOTA Basic demo.¥r¥nCurrently running on flash slot %d / %d.¥r¥n¥r¥n" , conf.current_rom, conf.count); printf ("Image addresses in flash:¥r¥n" ); for (int i = 0 ; i <conf.count; i++) { printf ("%c%d: offset 0x%08x¥r¥n" , i == conf.current_rom ? '*' :' ' , i, conf.roms[i]); } printf ("fm1 is runnning!¥n" ); struct sdk_station_config config = { .ssid = "your_wifi_ssid" , .password = "your_pass" , }; sdk_wifi_set_opmode(STATION_MODE); sdk_wifi_station_set_config(&config); xTaskCreate(&update_fm_task, "update_fm _task" , 2048 , NULL , 2 , NULL ); }
Makefile内容如下:
1 2 3 PROGRAM=otatest EXTRA_COMPONENTS=extras/rboot-ota include ../../common.mk
执行:
1 2 make cp ./firmware/otatest.bin /var/lib/tftpboot/fm1.bin
另外需要做成固件2,变更上面的第37行和第84行:
1 2 3 4 5 download_and_restart(TFTP_IMAGE_FILENAME2); printf ("fm1 is runnning!¥n" );---> download_and_restart(TFTP_IMAGE_FILENAME1); printf ("fm2 is runnning!¥n" );
执行:
1 2 make cp ./firmware/otatest.bin /var/lib/tftpboot/fm2.bin
6 固件下载
将fm1.bin下载到esp8266(具体硬件是nodemcu dev1.0), 注意nodemcu的SPI Mode是DIO。
写入成功后,首先是fm1运行,20s后,如果网络正常,会被更新为fm2。 Fm2运行后20s再次更新成fm1,如此循环往复。fm1->fm2->fm1… 如果首先下载的是fm2,则上述过程则会反过来。fm2->fm1->fm2…
通过串口,可看到如下日志如下 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 SP-Open-SDK ver: 0.0.1 compiled @ Jul 26 2017 12:56:25 phy ver: 273, pp ver: 8.3 OTA Basic demo. Currently running on flash slot 0 / 2. >>>>>>>2个slot,当前是0(写入地址是0x2000) Image addresses in flash: *0: offset 0x00002000 1: offset 0x00202000 fm1 is runnning! >>>>>>>第一次是fm1运行 … mode : sta(5c:cf:7f:a3:13:83) add if0 TFTP client task starting... >>>>>>>下载线程 … connected with iotwifi, channel 7 dhcp client start... ip:192.168.31.170,mask:255.255.255.0,gw:192.168.31.1 >>>下载线程 Downloading fm2.bin to slot 1... >>>>>>>fm2被下载到slot1 ota_tftp_download fm2.bin result 0 Rebooting into slot 1... >>>>>>>从slot1重启,切换为fm2 … rBoot v1.4.0 - richardaburton@gmail.com Flash Size: 32 Mbit Flash Mode: DIO Flash Speed: 40 MHz rBoot Option: Big flash rBoot Option: RTC data Booting rom 1. system param error ESP-Open-SDK ver: 0.0.1 compiled @ Jul 26 2017 12:56:25 phy ver: 273, pp ver: 8.3 OTA Basic demo. Currently running on flash slot 1 / 2. >>>>>>>2个slot,当前是1 Image addresses in flash: 0: offset 0x00002000 *1: offset 0x00202000 fm2 is runnning! >>>>>>>fm2运行!固件更新成功。 mode : sta(5c:cf:7f:a3:13:83) add if0 TFTP client task starting... scandone add 0 aid 2 cnt connected with iotwifi, channel 7 dhcp client start... ip:192.168.31.170,mask:255.255.255.0,gw:192.168.31.1 Downloading fm1.bin to slot 0... >>>>>>>fm1被下载到slot0 ota_tftp_download fm1.bin result 0 ---- Rebooting into slot 0... >>>>>>>从slot0重启,重新切换为fm1
目前切换slot时,启动会提示system param error,并dump信息。 经过确认esp-open-rtos的代码后,原因是启动时checksum,导致打印警告信息, 具体原因还没有查清,但固件本身的功能没有受到影响。
如要使用Server模式更新固件,在wifi连接成功并取得IP后,调用如下代码即可: ota_tftp_init_server(YOUR_TFTP_PORT);
参考url: 乐鑫:http://espressif.com/zh-hans/support/download/documents esp-open-rtos:https://github.com/SuperHouse/esp-open-rtos/wiki/OTA-Update-Configuration
相关链接(侵删)
ESP8266通过OTA更新固件的实践
=================我是分割线=================
欢迎到公众号来唠嗑: