序:
1、说实在的,这个问题不是很难,应该对于刚入手的人来说,也不容易。全都是边学边摸索边总结,经过几天的煎熬,终于实现。
2、需要耐心分析原理,步骤。先看别人的代码,能跑起来的跑一遍。
3、问题所在:别人的示例,仅单纯的示例,自己的项目是已经集成了多个功能,哪个也不能去掉,是不断附加的过程,代码后期再优化。所以就难到这了,由于C语言也不是很熟练,一知半解,才备受几天的煎熬。不会再翻视频学习学习,查资料看看。很多基本的数据模型,全局定义变量定义,类型转换等还是会磕磕绊绊的。继续努力学习中。
转入正题:
1、环境:安信可IDE,模块8266
2、实现功能:OTA在线一键升级。
结果展示:
需要说明:写入flash之前必须先擦除指定扇区。准备中。。。
至此,模块收到升级指令--准备下载--擦除扇区--写入扇区--重启模块
注意关于flash分配问题,参考:https://blog.csdn.net/u011852211/article/details/81390009
服务端下载(我是IIS,搭建比较简单)
在您已经备案的域名下直接新建个文件夹比如(updatebin放入user1.xxx.bin,user2.xxx.bin文 件和说明文件xxx.txt)
user1.4096.new.4.bin 这2个文件可以一样,也可以不一样;文件名不要一样。
user2.4096.new.4.bin 不同模块,或许名称不一样,当然可以重命名。一般默认。我的是4MBflash=32Mbit
比如您的模块运行的(boot引导的是user1,下载就下载user2,否则下载user1)
主要代码及总结
1、烧录事项(生成user1.xxx.bin时)找到项目根目录的makefile修改如下
软件:
主要代码参考:(2个文件 fotaxxx.c,fotaxxx.h)
1、升级调用时机(很多实例都是联网成功后即升级,我这是MQTT下发升级指令),我可以在内网任意一台电脑或手机对某个模块下发指令均可自动升级(当然需要知道一些列参数,有token身份验证等)
2、初始化---设置链接和断开回调函数-联网成功-设置发送接收回调-开始升级-升级过程回调-成功重启模块。
LOCAL void ICACHE_FLASH_ATTR
fota_upgrade_begin(struct espconn *pespconn, struct upgrade_server_info *server)
{
uint8 user_bin[30] = {0};//升级的文件名称
server->pespconn = pespconn;
os_memcpy(server->ip, pespconn->proto.tcp->remote_ip, 4);//ip(如果是域名此前DNS解析后传过来)
server->port = OTA_SERVER_PORT;//升级的端口(如果http即80)其他端口请设置(配置文件user_config.h)port
//可加个版本号的判断是否需要升级
server->check_cb = fota_upgrade_rsp;//升级过程回调*****
server->check_times = 120000;//120秒(此值视网络环境好坏定,建议一般不少于20秒)
if (server->url == NULL) {
server->url = (uint8 *)os_zalloc(1024);//分配http连接头 空间
}
//注意事项(如果当前运行的是user1.bin升级的文件名是user2的升级包文件,反之为user2.bin-->user1.xxxx.bin)
//文件名根据您的升级包文件修改(规范写法),注意根据flash大小,文件名会不同!!!!
//如果灵活,文件名通过参数传递过来也行
if (system_upgrade_userbin_check() == UPGRADE_FW_BIN1) {//user1.bin时
os_memcpy(user_bin, "user2.4096.new.4.bin", 21);//32Mbflash(512+512),查阅资料或函数回到看结果 system_get_flash_size_map()
} else if (system_upgrade_userbin_check() == UPGRADE_FW_BIN2) {//user2.bin时
os_memcpy(user_bin, "user1.4096.new.4.bin", 21);//第3参数:是文件名长度
}
//拼接参数url(如果想灵活,可以自定义路径 如updatebin,连接方法,先测试能否通过连接下载文件!);成功与否这很重要!!!!顶部宏定义 pheadbuffer
//不同服务器架构,连接方式稍微改变一下,通过文件路径加参数形式或直接下载的形式我通过iis直接下载路径。
//os_sprintf(server->url, "GET /updatebin/%s HTTP/1.0\r\nHost: "IPSTR":%d\r\n"pheadbuffer"",
// user_bin,IP2STR(server->ip));//文件名和服务器地址(转换为了字符串形式的ip)
os_sprintf(server->url, "GET http://您的域名或ip/updatebin/%s HTTP/1.1\r\nHost:您的域名或ip地址:端口\r\n"pheadbuffer"",
user_bin);//文件名和服务器地址(转换为了字符串形式的ip)
//如果传IP的形式,注意格式转换!u8 ota_server_ip[4] = {xxx,xxx,xxx,xxx};//否则解析错误
os_printf("****[HTTP_OTA]download url***\n%s\n",server->url);//回显打印url的信息 看对不对!!
if (system_upgrade_start(server) == false) {
os_printf("[HTTP_OTA] upgrade is already started\n");
}
}
//升级过程状态反馈(在启动程序上方哦,编译时在前)
LOCAL void ICACHE_FLASH_ATTR
fota_upgrade_rsp(void *arg)
{
struct upgrade_server_info *server = arg;
struct espconn *pespconn = server->pespconn;
if (server->upgrade_flag == true) {
mbUpgradeByNet=FALSE;
system_upgrade_flag_set(0x02);//设置升级的标志(2完成,1升级中,0未知)
os_printf("\r\n****[HTTP_OTA] fota upgarde successfully\r\n\r\n");
system_upgrade_reboot();//重启!!!!
} else {
os_printf("\r\n[HTTP_OTA] fota upgrade failed\r\n");
}
//释放分配空间资源********************
os_free(server->url);
server->url = NULL;
os_free(server);
server = NULL;
}
调用升级入口前,要检查网络的初始化,需要下载的文件名称,地址解析等。
//TCP连接断开成功的回调函数
void ICACHE_FLASH_ATTR
tcp_client_disconnect_cb(void *arg)
{
os_printf("[HTTP_OTA] tcp_client_disconnect_cb_OK\n");
}
//发送回调 成功发送网络数据的回调函数
LOCAL void ICACHE_FLASH_ATTR
tcp_client_sent_cb(void *arg)
{
struct espconn *pespconn = arg;
os_printf("[HTTP_OTA] tcp_client_sent_cb_OK\n");
}
//断开(重连)回调
LOCAL void ICACHE_FLASH_ATTR
tcp_client_recon_cb(void *arg, sint8 err)
{
struct espconn *pespconn = (struct espconn *)arg;
//espconn_connect(pespconn); // 连接TCP-server
os_printf("[HTTP_OTA] tcp_client_recon_cb\n");
}
//成功接收网络数据的回调函数【参数1:网络传输结构体espconn指针、参数2:网络传输数据指针、参数3:数据长度】
LOCAL void ICACHE_FLASH_ATTR
tcp_client_recv_cb(void *arg, char *pusrdata, unsigned short length)
{
struct espconn *pespconn = arg;
os_printf("[HTTP_OTA] tcp_client_recv_cb\n%s\n", pusrdata);
}
//wifi连接成功
LOCAL void ICACHE_FLASH_ATTR
tcp_client_connect_cb(void *arg)
{
struct espconn *pespconn = arg;//结构体
struct upgrade_server_info *server = NULL;
os_printf("[HTTP_OTA]tcp_client_connect_cb\n");
if (wifi_get_opmode() == STATIONAP_MODE ) {
wifi_set_opmode(STATION_MODE);//如果是混合模式,重置为网络STA模式
//wifi_set_opmode_current(STATION_MODE);//运行模式(不存)
}
//连接函数中 注册3个 接收和发送\断开
espconn_regist_recvcb(pespconn, tcp_client_recv_cb);//接收回调
espconn_regist_sentcb(pespconn, tcp_client_sent_cb);//发送回调 注册网络数据发送成功的回调函数
espconn_regist_disconcb((struct espconn *)arg,tcp_client_disconnect_cb); // 注册成功断开TCP连接的回调函数
//可以扩展,发送请求报文,读取网络是否有升级的固件信息!
//espconn_send((struct espconn *)arg, HTTP_Message_BinInfo, os_strlen(HTTP_Message_BinInfo)); // 发送HTTP报文
server = (struct upgrade_server_info *)os_zalloc(sizeof(struct upgrade_server_info));
server->upgrade_version[15] = '\0';//结束符 \0
os_printf("[HTTP_OTA]fota_upgrade_begin\r\n");
//---------------------------------------------------------------
fota_upgrade_begin(pespconn, server);//升级开始!!!!!!!!!
//---------------------------------------------------------------
}
基本所有工作做完了。写个文档花费很长时间....
固件下载体验:可以关注 x5zj.com或csdn下载区(近期调试完上传)可以私信留言。
目前完成功能:
1、智能配网(esptouch安卓版,我发布的有个 http://x5zj.com/?p=44看说明,吾爱也有)
2、配网支持airkiss(安信可公众号配网)
3、MQTT自检服务器(mqttx)通讯及主题订阅发布。我的各种客户端(吾爱或我的博客里看)
4、OTA在线一键升级(随时可升级,自定义发送参数或固定参数)
5、DHT11实时在线温度推送
6、LED指示灯开关(自建一套指令发送和解析方案)
7、WEBSOCKET+MQTT(H5实现见下图)体验地址http://x5zj.com/x5zjbox/8266.html 我已经3月没关电脑了(不知道电费多少,还没缴费)
配套参考
测试多客户端
我发布的还有几款基于websocket+tcp的客户端,博客看。此服务端是TCP+WEBSOCKET+MQTT三维互通服务。彻底打通互联。已打通前2个互通(中间件要学习redis哦)服务端支持每秒数万个并发应该没问题,费了我几个月的时间!!!
以服务的形式运行,我写的还有个服务看门狗(吾爱有发),监控服务不停止自动启动,还有邮件(进程列表)上报等软件。
很多很多,不再一一叙述。。。。。敬请关注。我在努力学习,放弃一切了。。。
到此结束,费了2小时左右写一篇博文。