Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)


  • 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板。仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
序号 SDK版本 内容 链接
1 nonos2.0 搭建开发环境,开始一个“hellow world”串口打印。 点我访问
2 nonos2.0 利用GPIO开始使用按钮点亮你的“第一盏灯。 点我访问
3 nonos2.0 利用 "软件定时器 " 定时0.5秒闪烁点亮一盏LED。 点我访问
4 nonos2.0 用PWM控制一盏LED的亮度变化。 点我访问
5 nonos2.0 SDK高级使用之封装Post与Get请求云端,拿到“天气预报信息”。 点我访问
6 nonos2.0 了解 SmartConfig与Airkiss一键配网,给8266配网上云端。无需把wifi名字密码写在固件里。 点我访问
7 nonos2.0 了解 softAP热点配网模式原理,仿“机智云”定义自己的热点配网模式协议。 点我访问
8 nonos2.0 你要找的8266作为UDP、TCP客户端或服务端的角色通讯,都在这了。 点我访问
9 nonos2.0 [小实战上篇]Windows系统搭建8266的本地Mqtt服务器,局域网点亮一盏LED灯。 点我访问
10 nonos2.0 [小实战下篇]Windows系统搭建8266的本地Mqtt服务器,局域网点亮一盏LED灯。 点我访问
11 rtos2.0 接入阿里智能,点亮一盏LED灯,期待天猫精灵语音控制的不约而至! 点我访问
12 nonos2.0 图文并茂学习阿里云主机搭建8266MQTT服务器,实现移动网络远程控制一盏LED。 点我访问
13 nonos2.0 动手做个8266毕设小案例,smartConfig + MQTT协议轻松实现远程控制一盏LED。 点我访问
14 rtos2.0 FreeRtos系统学习的正确姿势 ------ 环境搭建、烧录。 点我访问
15 rtos2.0 接入阿里云平台非阿里智能的SDS服务,点亮一盏LED灯。 点我访问
16 nonos2.0 基于Nonos移植红外线H1838,实现红外遥控器配网,远程控制一盏灯。 点我访问
17 nonos2.0 esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。 点我访问
18 nonos2.0 基于NONOS 实现 OTA 远程升级,实现无线“ 热修复 ”升级固件程序。 点我访问
19 nonos2.0 驱动 ds18b20、dht11 温湿度传感器,采集温湿度传感器到服务器。 点我访问
20 nonos2.0 深入学习esp8266的esp now模式,仿机智云做一个小网关,实现无需网络下轻松彼此连接通讯交互数据。 点我访问
21 nonos2.0 浅谈 esp8266 如何在本地局域网网络情况下实现最大效率地和前端实现数据交互。 点我访问
22 nonos2.0 esp8266的工程如何添加第三方静态库文件以及如何自定义文件夹,聊聊那些makeFile的事 点我访问
23 nonos2.0 再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,接触下 lwip的基本知识。 点我访问
24 nonos2.0 渗透学习回顾下esp8266的外置spi芯片25q系列,熟悉8266代码块在其的分布,得心应手放置图片或其他资料。 点我访问
25 rtos2.0 深聊下esp8266的串口 Uart 通讯中断编程,为您准备好了 NONOS 版本 和 RTOS 系统的串口驱动文件。 点我访问
26 nonos2.0 RTOS分析 MQTT 实现过程,实现移植 MQTT协议在 esp8266 rtos实时系统,可断线重连。 点我访问
27 rtos3.0 跟紧脚步,用VisualStudio Code开发 esp8266 rtos SDK v3.0版本,全新的 idf 框架,节省内存模块化开发。 点我访问
28 rtos3.0 教你轻松自如使用cJson在乐鑫 esp8266 如何解析一段json数据以及如何生成一段json数据。 点我访问
29 rtos3.0 百万条消息免费之使用TCP直连模式MQTT协议接入阿里云物联网平台,支持私家服务器对接支持阿里云规则引擎。 点我访问
30 rtos3.0 SDK编程使用 IIC总线驱动 0.96寸的OLED显示屏,显示天气预报信息。 点我访问
31 rtos3.0 当esp8266遇到 Html,该怎么内置网页控制设备,理清内置网页的实现过程,实现无需路由器手机也可以控制esp8266。 点我访问
32 rtos3.0 细聊HmacMD5的加密方法带来的安全性,并实践在esp8266上,最大保障传输的过程的信息的安全性。 点我访问
33 rtos3.0 如何优雅地像乐鑫原厂封装esp8266底层寄存器的逻辑思维,做成自己的静态库库文件,让第三方人使用? 点我访问
34 nonos3.0 编程使用 SPI 驱动基于Max7219芯片的八位数码管,显示日期信息。 点我访问
35 nonos3.0 借助机智云平台做一个商业化的七彩RGB灯泡可调整体方案项目,炫彩夺目高大尚。 点我访问
36 rtos3.0 认识Rtos 3.0 sdk 工程结构,如何向esp-idf工程靠近的,如何自定义头文件编译? 点我访问
37 rtos3.0 你要找的基本外设功能都在这里了,包括Gpio、Pwm 和 Uart 接口使用。 点我访问
38 rtos3.0 一篇文章带你搞掂存储技术 NVS 的认识和使用,如何利用NVS保存整型、字符串、数组以及结构体。 点我访问
39 rtos3.0 带你捋一捋市面上的微信公众号配网智能设备 esp8266 并绑定设备的过程,移植并成功实现在 esp8266 rtos3.1 sdk。 点我访问
40 rtos3.0 基于乐鑫idf框架,研究出超稳定、掉线重连、解决内存泄露问题的Mqtt框架!支持esp8266和esp32! 点我访问
41 rtos3.0 esp8266-12模块基于rtos3.1版本ota功能远程空中升级固件,官网基础之上增加dns域名解析! 点我访问
42 rtos3.0 我又来了,基于rtos3.0版本 SDK编程 SPI 驱动 ws2812b 七彩灯,代码全部开源奉献给你们! 点我访问
43 rtos3.0 基于rtos3.0版本扫描周围获取附近可用的 Wi-Fi 热点路由器信息,同样适合esp32。 点我访问
44 rtos3.0 整理分享那些我在项目中常用的esp8266 rtos3.0版本的常见驱动,Button按键长短按、PWM平滑调光等。 点我访问
45 rtos3.0 内置仅1M的Esp8285,如何攻破最棘手的OTA问题,大大节省资源成本开发产品 点我访问
46 rtos3.0 详细分析Esp8266上电信息打印的数据,如何做到串口通讯上电不乱码打印; 点我访问
47 rtos3.0 无需外网,如何实现在本地局域网与控制端做数据交换的一些开发经验; 点我访问
48 rtos3.0 迟来的1024程序员祝福,开源分享一个驱动 ds18b20 获取温度的工程。 点我访问
49 rtos3.2 aliyun sdk 直连接入阿里云物联网平台,实现天猫精灵找队友零配网功能和语音控制。 点我访问
持续更新,欢迎关注我,QQ群讨论群:434878850

  • 很多人怎么联系我一起学习进步,下面打个小小公告和干货无偿分享:

玩转esp8266带你飞、加群付费QQ群,提高门槛,不喜的朋友勿喷勿加:434878850
esp8266源代码免费学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266
esp32源代码免费学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32


文章目录

      • 一、前言;
      • 二、回顾下`OTA`的流程;
      • 三、`lwip`网络框架的知识的使用;
      • 四、如何处理服务器返回的数据?
      • 五、扇区的擦除和烧写?
      • 六、如何调用?
      • 七、好好享用吧!
      • 八、下载:
      • 九、注意事项:

一、前言;


  • esp8266实现OTA已经不是什么奇怪的事情了,主要esp8266还有支持裸跑非系统和rtos实时系统之分,导致现在有2个版本的代码,前面我已经料到了在NONOS怎么实现远程升级我们的固件,那么这篇的话,而是基于freeRtos实时系统的。
  • 主要涉及到知识有以下:
    • lwip网络框架的基本使用,域名和DNS解析的使用。
    • freeRtos的基本认识。
    • http请求的协议认识和原理。
    • esp8266的内存划分的认识。
  • 实现的功能特色有以下:
    • 支持本地服务器和远程广域网服务器。(通过DNS解析)
    • 支持显示下载固件进度。

二、回顾下OTA的流程;


  • 我们已经很清楚,esp8266实现远程升级的原理过程如下:
Created with Raphaël 2.2.0 开始请求服务器资源比如:user2.4096.new.6.bin 网络良好,服务器响应正确。准备下载... ... 下载完毕,确认是否重启? 重启成功!根据 boot 信息,执行user2.4096.new.6.bin。 yes

  • 私有服务的放置其实也是一样,只需要在阿里云或者京东云或者腾讯云这些平台搭建服务器,把编译好的固件放上去,提供链接即可,和本地一样。

  • 注意放上去的2个固件的配置信息必须一致。


三、lwip网络框架的知识的使用;


  • ①:lwip使用DNS来解析网址域名。

因为esp8266这个实时系统支持lwip,所以直接调用即可;首先要打开DNS功能,在lwipopts.h头文件有个宏定义LWIP_DNS置为1即可。下面就是调用代码了:

        //dns begin
		dns_init(); //初始化
		struct ip_addr addr;
		//你要解析的域名,比如 www.baidu.com
		char name0[] = "www.baidu.com"; 
		//调用netconn_gethostbyname
		err_t err = netconn_gethostbyname((char*) name0, &addr);
		//定义字符串来接收IP
		char* ipAdress;
		if (err == ERR_OK) {
		    //格式化IP
		    ipAdress = ip_ntoa(&addr);
		    //打印下
			printf("dns ok , the %s ip is:%s",name0, ipAdress);
		}else{
			return;
		}
		//dns over

  • ②:先通过socket连接服务器的端口,一般地,默认是80!其中http请求的格式内容如下:注意这个Host的内容可以是域名或者IP,这个要根据服务器来配置。
GET /api/download/user2.4096.new.6.bin HTTP/1.0
Host: www.baidu.com
Connection: keep-alive
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8

  • ③:如果正确响应的话,也是要遵循一定的规则的,我们可以用postMan工具来看看,这显示下载的大小是296412,单位是Byte;那么下面的话,我们根据这个大小去判断我们下载的进度啦!

Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)_第1张图片


四、如何处理服务器返回的数据?


  • 我们是采用http请求服务器,那么服务器响应正确的话,也是按照一定的协议返回来给我们的 。小徐在尝试了几个服务器,一个是Tomcat,一个是用php搭建的服务器,返回的内容格式有所差别,最大的不同点是:一个是Accept-Length:指定内容大小,一个是Content-Length:指定大小,为此我这次封装的方法文件,是完全可以兼容起来的。详情可以看下面的部分代码。
    //判断 "Accept-Length" 或者 "Context-Length"
	bool isAccept = false;
	if((ptr = (char *)strstr(pusrdata, "Accept-Length")) != NULL)
		isAccept = true;
	else
		isAccept = false;

	if (totallength == 0&& (ptr = (char *)strstr(pusrdata, "\r\n\r\n")) != NULL) {

		ptr = (char *) strstr(pusrdata, "\r\n\r\n");
		length -= ptr - pusrdata;
		length -= 4;

		printf("ota_start_download:upgrade file download pusrdata:%s\n\n",
				pusrdata);

		//返回"Accept-Length: "在pusrdata中首次出现的地址
		if (isAccept)
			ptr = (char *) strstr(pusrdata, "Accept-Length: ");
		else
			ptr = (char *) strstr(pusrdata, "Content-Length: ");

		if (ptr != NULL) {
		
            //注意这个"Accept-Length" 或者 "Context-Length"占用的字节不同的
			if (isAccept)
				ptr += 15;
			else
				ptr += 16;

			ptmp2 = (char *) strstr(ptr, "\r\n");

			if (ptmp2 != NULL) {

				//打印下收到的数据头
				//printf("ptr = %s \n", ptr);

				//清空lengthbuffer
				memset(lengthbuffer, 0, sizeof(lengthbuffer));
				memcpy(lengthbuffer, ptr, ptmp2 - ptr);
				sumlength = atoi(lengthbuffer);

				if (sumlength > 0) {
					if (false == system_upgrade(pusrdata, sumlength)) {
						system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
						goto ota_recycle;
					}
					flash_erased = true;
					ptr = (char *) strstr(pusrdata, "\r\n\r\n");
					if (false == system_upgrade(ptr + 4, length)) {
						system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
						goto ota_recycle;
					}
					totallength += length;
					return;
				}

			} else {
				system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
				goto ota_recycle;
			}

		}

  • 上面我们拿到了这个总数据,那么我们下载固件时候又是怎么样判断是否拉取全部呢?其实通过我们拉取的内容大小和这个总数相比较,就可以得到是否下载完毕。

一般我们都是下载的数据量除于总数据量就是百分比了!由于esp8266不支持浮点类型,也就是不支持小数。 但是我们又要显示进度咋办?yiban其实很简单,算法如下:

  • sumlength为总数据量,totallength是已下载的数据量!
int part =sumlength/100;
int projress = (totallength / part);
printf("已经下载: %d , 总数据: %d , 进度: %d\% \n", totallength, sumlength,projress);

五、扇区的擦除和烧写?


  • 要弄明白esp8266OTA,必须要对其的扇区明明白白。我们现在最常用的是esp8266-12f,其的容量大小是32Mbit,也就是最大代码是1M,2个分区:1024+1024!而大家玩的esp8266-018Mbit, 也即是512+512

  • 从下面官方给的图可以看到,一个支持OTA的扇区分布是对称的,如果你的是8Mbit的话,那么最大的支持就是512K,而32Mbit的就是最大支持1M,其他空间用户数据!说白了,加载的只是这2个空间的任意一个固件!

Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)_第2张图片


  • 下面我再弄一个各个容量大小分布的:

Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)_第3张图片


六、如何调用?


  • 因为个人小徐是个喜欢封装代码降低耦合的程序员,做项目都要明确划分功能。那么这次的封装也是基于面对对象思想做的,用回调实现进度显示:

  • 判断当前是处于哪个分区,如果是分区一那么我们拉取的就是分区二的代码,反而也是这样;
     //注册回调函数
	system_ota_register_callBack(ota_call_back);
	//如果当前是处于 user1.bin,那么就拉取云端 user2.bin 升级
	if(system_upgrade_userbin_check()==UPGRADE_FW_BIN1){
		printf("now is user1.bin\n");
		system_ota_config_start("www.baidu.com","api/v1/emq/download/iot?bin2.bin",80,true,true);
	//如果当前是处于 user2.bin,那么就拉取云端 user1.bin 升级
	}else if(system_upgrade_userbin_check()==UPGRADE_FW_BIN2){
		printf("now is user2.bin.\n");
		system_ota_config_start("www.baidu.com","api/v1/emq/download/iot?bin1.bin",80,true,true);
	}else{
	    //不支持云端升级
		printf("now is not support FOTA..\n");
	}

  • 看看我们刚刚注册的那个回调函数:
void ota_call_back(int progress, ota_code code) {

    //下载中,可看到进度数值。
	if (code == OTA_DOWNLOADING) {
		printf("ota_DowmLoading: %d%% \n",progress);
	//下载完毕
	} else if (code == OTA_SUCCEED) {
		printf("OTA_SUCCEED! \n");
		system_upgrade_deinit();
		// 看你需要,下载完毕是否重启系统
		system_upgrade_reboot();
	}
}

  • 这是小徐专心封装的函数和方法,直接调用即可:
typedef enum {
	OTA_FAIL = 0,    //下载失败,可能是网速问题
	OTA_SUCCEED ,  //下载并且烧录成功,请重启系统
	OTA_DOWNLOADING ,  //下载中,可看进度条
	OTA_INIT_ERROR ,	 //初始化失败,网址有误。
	OTA_INIT_OK ,	 //初始化成功。
}ota_code;

//progress是进度条,code是状态码
typedef void (*ota_download_CallBack)(int progress,ota_code code);

//注册下载服务器bin文件的进度百分比回调函数:0到100% (整型);
void system_ota_register_callBack(ota_download_CallBack callBack);

/******************************************************************************
 * FunctionName : system_ota_config_start
 * Description  : 传入网址,并且开始下载
 * Parameters   : char *domainName : 域名或ip地址
 *                char* requestResource : 请求的资源地址
 *                int port         : 端口号
 *                bool isDNS       : 是否要DNS解析
 *                bool isGet       : get请求或者post提交
 * Returns      : 是否成功
 *******************************************************************************/
bool system_ota_config_start(char *domainName, char* requestResource,int port,
		bool isDNS, bool isGet);

七、好好享用吧!


  • 下面是我串口打印截图:

Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)_第4张图片


Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)_第5张图片


八、下载:


  • 这个是小徐根据官方的代码。适配了私有服务器、适配了返回数据内容的,而且还支持下载进度显示,真是老费力了!所以代码收点小费,也就是一包烟的事情。这个比某宝上的方案代码便宜了几十倍。

  • 这个demo需要注意的是:如果你的服务器地址直接是IP的,就不用DNS解析;如果是域名,那么就需要DNS的;还有需要啰嗦的一点就是:注意你的网络良好、服务器是否访问、还有最为重要的分区说明。

  • 好了,如果你确保上面问题,那么这个demo发生有趣的问题,就是不断来回升级,在两个分区跳转。。呵呵。

  • 代码工程:http://www.demodashi.com/demo/13533.html

  • esp8266学习汇总:https://github.com/xuhongv/StudyInEsp8266

  • esp32学习汇总:https://github.com/xuhongv/StudyInEsp32

  • 小徐QQ群,少走弯路,玩转8266SDK编程:434878850


九、注意事项:

  • 根据不同的服务器不一样,有可能会出现多余的body内容返回,导致下载成功,但是校验不通过的情况,从而升级失败!,感谢群里的一个小伙伴的解决方法提供如下:
    • 修改下接受的校验和处理即可!!
      Esp8266 进阶之路23【高级篇】再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,还可以显示下载升级进度哦。(附带Demo)_第6张图片

你可能感兴趣的:(8266,乐鑫esp8266学习之旅)