ESP8266的云升级
ESP8266云升级需要了解和注意事项
1、 怎么设置eclispe使ESP8266支持云升级及云升级要注意的事项
2、 怎么确认wifi稳定连接
3、 推荐一个免费的云服务器及使用方法
4、 怎么连接云服务器
5、 怎么从云服务器获取可用的数据
6、 怎么把可用数据写入flash并跳转到新的程序运行
7、怎么个程序执行流程
1、 怎么设置eclispe使ESP8266支持云升级及云升级要注意的事项
A、要使用云升级就必须要清楚的知道使用的ESP8266的flash的大小,我的ESP8266的flash大小为512K,如果以前做个stm32的IAP就知道,在写STM32的bootloader和APP的时候我们要先给它设置分区,同样在给esp8266做升级的时候我们也要考虑这些问题,不过官方已经给我们分配好了,在ESP8266的官方文档里面有个文件叫 2A-ESP8266__IOT_SDK_User_Manual__CN_v1.3.0.pdf里面详细介绍了flash的的分配。
因为我的flash是512k,而且我要的是支持云端升级,咋文档里面可以看到如下图
这就是512kflash的分区,可以看到
0 ----4K是boot的存放区域(也就是0x0000 0000 -----0x0000 1000之间)
4k---240k是user1.bin文件的存放区域(0x0000 1000 ---0x0003 C000之间)
240k—256k是user param存放的区域(0x0003 C000-----0x0004 0000之间)
这上面有分为一个区
下面是另一个区
256k------260k是reserve去,保留的(0x0004 0000-----0x0004 1000之间)
260k-------496k是user2.bin文件的存放的区域(0x0004 1000 -----0x0007 C000之间)
496k--------512k是system param系统参数的区域(0x0007 C000 -------0x0008 0000之间)
B、同时可以看到上面有个提示,编译的时候要设置的,在eclipse里面的makefile里面设置,先来看下不能进行云升级的时候makefile的参数如下
不能进行云升级的配置
可以进行云升级makefile的配置如下
boot赋值为new,意思就是可以升级
APP 赋值为1,就可以生成user1的bin 文件 如果要生成user2的文件 把它改为2就可以了
SPI_SPEED是下载的速度
SPI_MODE是下载模式
SPI_SIZE_MAP是flash的大小这个可以看上面那个文档详细介绍 赋值为0表示使用的flash是512k
C、设置好以后 我们可以看看编译的结果如下
从这里可以看到 boot的开始地址是0x00000 支持的版本必须要1.2版本或以上版本
从生成的user1的名字同样可知道符合我们上面的makefile的配置
2、 怎么确认wifi稳定连接
要想实现云升级,那么wifi必须在连接状态,如果我们的wifi已经设置好了,我们可以通过函数wifi_station_get_connect_status来判断wifi是否连接。如果返回STATION_GOT_IP表明连接成功
3、 推荐一个免费的云服务器及使用方法
网上大部分的云服务器都是要收费的,好不容易找到一个可以免费的云服务器(当然它也有收费项,只是我没用到),七牛云(https://portal.qiniu.com/)
要想之后可以复制链接地址,好像必须的使用谷歌浏览器才可以,
注册一个用户然后就可以上传我们的eclipses生成的bin文件上去。
上面是我的两个用来升级的bin文件,点击右边那个红框就可以从里面复制出来链接,在之后会用到这个链接
4、 怎么连接云服务器
A、在云服务器里面我们得到了上传的文件的网址,那么我们就可以使用get或者post请求,去请求云服务器,得到想要的数据。ESP8266我们可以udp或者TCP和外网建立通信,但是都必须知道它的IP地址,端口号、等。
http://7xt7oy.com2.z0.glb.clouddn.com/user1.512.new.0.bin
这就是user1在云服务器上面的地址,这里并没有直接给出ip地址,所以我们必须要把这个链接给解析出来,得到他的ip,端口号(默认是80)、文件名,在程序中使用函数void ICACHE_FLASH_ATTRhttp_parse_request_url(char *URL,char *host,char *filename,unsignedshort *port){
char *PA;
char *PB;
memset(host,0,sizeof(host));//给host初始化
memset(filename,0,sizeof(filename));//给filename初始化
*port=0;
if(!(*URL))return;//如果url为空就返回
PA=URL;
if(!strncmp(PA,"http://",strlen("http://")))//判断协议名
PA=URL+strlen("http://");//移动PA
if(!strncmp(PA,"https://",strlen("https://")))
PA=URL+strlen("https://");
PB=strchr(PA,'/');//strchr字符查找 返回值是要查找的字符的位置
if(PB){
memcpy(host,PA,strlen(PA)-strlen(PB));
if(PB+1){
memcpy(filename,PB+1,strlen(PB-1));
filename[strlen(PB)-1]=0;
}
host[strlen(PA)-strlen(PB)]=0;
}else{
memcpy(host,PA,strlen(PA));
host[strlen(PA)]=0;
}
PA=strchr(host,':');
if(PA)
*port=atoi(PA+1);
else
*port=80;
}
//http://www.baidu.com:80/..
//http代表协议名
//www.baidu.com:80代表域名 80代表端口号
//.. 这里就是文件名
其中host保存是域名 filename是文件名 port是保存端口 参考上面
B、上面得到了域名 ,我们还得把域名解析成IP地址,调用espconn_gethostbyname函数,就可以得到IP,知道了远程IP和端口,本地IP, 然后在它的回调函数里面完成初始化TCP 客户端就可以,具体的完成过程就不写了,
5、 怎么从云服务器获取可用的数据
可以通过get或者post请求服务器得到数据,
#define HEAD "GET / HTTP/1.1\r\nAccept:*/*\r\nHost: www.baidu.com\r\nConnection: Keep-Alive\r\n\r\n\0"
上面是一个实例,我们可以在TCP连接成功后,通过espconn_sent函数发送请求
,然后就可以在user_tcp_recv_cb接收回调函数,接收到数据如下
发送数据成功!收到数据:HTTP/1.1 200 OK
Date:Tue, 19 Apr 2016 07:12:12 GMT
Server:Apache/2.2.22 (Ubuntu)
Accept-Ranges:bytes
ETag:W/"4096-1461046811000"
Last-Modified:Tue, 19 Apr 2016 06:20:11 GMT
Content-Length:4096
Keep-Alive:timeout=5, max=100
Connection:Keep-Alive
Content-Type: application/octet-stream*/
当然这里是接收到上传的blank.bin的文件大小。从上面可以看到 文件的大小是4096个字节,
下面是通过查看blank.bin的属性得到
可以看到blank.bin的文件大小是4096,和通过get请求获取的大小一样
6、怎么把可用数据写入flash并跳转到新的程序运行
对flash的操作,我们可以看官方提供的
99A-ESP8266__Flash_RW_Operation__CN_v0.2.pdf文档,里面有详细的价绍
这里只是大概的说下,flash在写入之前,都需要事先擦除,flash是块擦除,一块大小是4k,
SpiFlashOpResult spi_flash_erase_sector(uint16 sec)函数用于擦除一个扇区
SpiFlashOpResultspi_flash_write (uint32 des_addr,uint32 *src_addr, uint32 size)
将数据写入
SpiFlashOpResultspi_flash_read(uint32 src_addr,uint32 * des_addr, uint32 size)
读取数据
我们可以利用上面函数把接收到的数据写入到flash,写的时候要注意要写入flash的地址,比如 现在运行的是user1,那么更新的应该是user2,所以要写入的起始地址应该是0x0004 1000(512k的flash),如果是运行的是user2,就要把数据写入到user1中的起始地址0x0000 1000开始。
可以用函数system_get_userbin_addr()来获取正在运行的起始地址
用system_upgrade_userbin_check()来获取运行的是user2还是user2.
在写flash完成之后,调用下面两个函数就可以实现设置升级标志和重启运行新的程序
system_upgrade_flag_set(0x02);//设置升级的标志
system_upgrade_reboot();//重启
7、怎么个程序执行流程