ESP8266学习笔记(16)

您所在的位置:网站首页 ota平台英文全称 ESP8266学习笔记(16)

ESP8266学习笔记(16)

2023-12-13 13:40| 来源: 网络整理| 查看: 265

一、简介

OTA 是英文全称『Over-the-Air Technology』的缩写,翻译过来的中文含义也就是『空中下载技术』的意思。可支持通过 Wi-Fi 从云端下载新版本 ESP8266 固件,进行升级。

二、资料准备 2.1 下载SDK

下载 ESP8266_NONOS_SDK-3.0【1xl4】

2.2 复制工程

将待编译的 ESP8266_NONOS_SDK\examples\IoT_Demo 文件夹复制到 \ESP8266_NONOS_SDK 根目录下

2.3 修改用户参数区位置

根据实际使用的 ESP8266 硬件模块 Flash 大小,修改的用户参数区位置 以使用 2048 KB Flash,512+512 map 为例 在 IoT_Demo\user\user_main.c 中 #define SPI_FLASH_SIZE_MAP 4 修改为4 其中 SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR 0x7c000 为0x7c

三、工作流程

搭建TCP客户端 ↓ 接收服务器升级请求 ↓ 向服务器返回响应 ↓ 获取升级版本号 ↓ 升级开始 ↓ 获取服务器信息 ↓ 检查当前运行的bin文件 ↓ 下载升级固件 ↓ 下载完成,重启

四、代码修改

接入乐鑫云查看 ESP8266学习笔记(14)——接入乐鑫云Iot·Espressif 在文章 2.8.1 处理GET请求URL 中 configSystemUpgrade(pStr); // 配置系统升级 函数

4.1 configSystemUpgrade /** @brief 配置系统升级 @param pStr -[in] 待比较字符串 @return 无 */ static void ICACHE_FLASH_ATTR configSystemUpgrade(char *pStr) { struct upgrade_server_info *pServerInfo = NULL; sendResponse(s_receiveData); pServerInfo = (struct upgrade_server_info *) os_zalloc(sizeof(struct upgrade_server_info)); os_memcpy(pServerInfo->upgrade_version, pStr + 12, 16); pServerInfo->upgrade_version[15] = '\0'; os_sprintf(pServerInfo->pre_version,"%s%d.%d.%dt%d(%s)", VERSION_TYPE, IOT_VERSION_MAJOR,\ IOT_VERSION_MINOR, IOT_VERSION_REVISION, device_type, UPGRADE_FALG); espPlatformUpgradeBegin(pServerInfo); }

创建升级结构体 struct upgrade_server_info *pServerInfo = NULL; 回复服务器响应 sendResponse(s_receiveData); 获取升级版本号 os_memcpy(pServerInfo->upgrade_version, pStr + 12, 16); 升级开始 espPlatformUpgradeBegin(pServerInfo);

4.2 sendResponse /** @brief 发送响应 @param pRecvData -[in] 接收的数据 @return 无 */ static void ICACHE_FLASH_ATTR sendResponse(uint8 *pRecvData) { int nonce = 0; char *pSendData = (char *) os_zalloc(SEND_DATA_SIZE); nonce = parseNonceFromReceiveData(pRecvData); if(pSendData != NULL) { os_sprintf(pSendData, TCP_SERVER_RESPONSE_FRAME, nonce); os_printf("%s\n", pSendData); espconn_sent(&s_espPlatformTcpEspconn, pSendData, os_strlen(pSendData)); os_free(pSendData); pSendData = NULL; } } 4.2.1 parseNonceFromReceiveData /** @brief 解析随机数 @param pRecvData -[in] 接收的数据 @return 随机数值 */ static int ICACHE_FLASH_ATTR parseNonceFromReceiveData(char *pRecvData) { char *pStr = NULL; char *pParse = NULL; char nonceStr[11] = {0}; int nonce = 0; pStr = (char *) os_strstr(pRecvData, "\"nonce\": "); if(pStr != NULL) { pStr += 9; pParse = (char *) os_strstr(pStr, ","); if(pParse != NULL) { os_memcpy(nonceStr, pStr, pParse - pStr); } else { pParse = (char *) os_strstr(pStr, "}"); if(pParse != NULL) { os_memcpy(nonceStr, pStr, pParse - pStr); } else { pParse = (char *) os_strstr(pStr, "]"); if (pParse != NULL) { os_memcpy(nonceStr, pStr, pParse - pStr); } else { return 0; } } } nonce = atoi(nonceStr); } return nonce; } 4.3 espPlatformUpgradeBegin /** @brief ESP平台系统升级开始 @param pServerInfo -[in] 服务器信息 @return 无 */ static void ICACHE_FLASH_ATTR espPlatformUpgradeBegin(struct upgrade_server_info *pServerInfo) { uint8 userBin[9] = {0}; uint8 deviceKey[41] = {0}; GetDeviceKey(deviceKey); pServerInfo->pespconn = &s_espPlatformTcpEspconn; os_memcpy(pServerInfo->ip, s_espPlatformTcpEspconn.proto.tcp->remote_ip, 4); pServerInfo->port = 80; pServerInfo->check_cb = espPlatformUpgradeResponse; pServerInfo->check_times = 120000; if(pServerInfo->url == NULL) { pServerInfo->url = (uint8 *) os_zalloc(512); } if(system_upgrade_userbin_check() == UPGRADE_FW_BIN1) { os_memcpy(userBin, "user2.bin", 10); } else if(system_upgrade_userbin_check() == UPGRADE_FW_BIN2) { os_memcpy(userBin, "user1.bin", 10); } os_sprintf(pServerInfo->url, "GET /v1/device/rom/?action=download_rom&version=%s&filename=%s HTTP/1.0\r\nHost: "IPSTR":%d\r\n"pheadbuffer"", pServerInfo->upgrade_version, userBin, IP2STR(pServerInfo->ip), pServerInfo->port, deviceKey); os_printf("%s\n",pServerInfo->url); if(system_upgrade_start(pServerInfo) == false) { os_printf("upgrade is already started\n"); } }

获取连接句柄 pServerInfo->pespconn = &s_espPlatformTcpEspconn; 获取服务器IP os_memcpy(pServerInfo->ip, s_espPlatformTcpEspconn.proto.tcp->remote_ip, 4); 获取服务器端口 pServerInfo->port = 80; 升级完成后回调函数 pServerInfo->check_cb = espPlatformUpgradeResponse; 定时回调时间 pServerInfo->check_times = 120000; 获取系统的目前加载的是哪个bin文件 system_upgrade_userbin_check() 获取服务器URL os_sprintf(pServerInfo->url, "GET /v1/device/rom/?action=download_rom&version=%s&filename=%s HTTP/1.0\r\nHost: "IPSTR":%d\r\n"pheadbuffer"", pServerInfo->upgrade_version, userBin, IP2STR(pServerInfo->ip), pServerInfo->port, deviceKey); 开始下载升级固件 system_upgrade_start()

4.3.1 GetDeviceKey /** @brief 获取设备密码 @param pToken -[in&out] 密钥 @return 无 */ void ICACHE_FLASH_ATTR GetDeviceKey(uint8_t *pDeviceKey) { if(!pDeviceKey) { return ; } os_memcpy(pDeviceKey, s_flahSavedParam.devkey, sizeof(s_flahSavedParam.devkey)); } 4.3.2 espPlatformUpgradeResponse /** @brief ESP平台系统升级响应 @param arg -[in] 指向传递给这个回调函数来使用的参数 @return 无 */ static void ICACHE_FLASH_ATTR espPlatformUpgradeResponse(void *arg) { struct upgrade_server_info *pServerInfo = arg; struct espconn *pEspconn = pServerInfo->pespconn; uint8 deviceKey[41] = {0}; char *pAction = NULL; GetDeviceKey(deviceKey); uint8 *pSendData = (char *) os_zalloc(SEND_DATA_SIZE); if(pServerInfo->upgrade_flag == true) { os_printf("user_esp_platform_upgarde_successfully\n"); pAction = "device_upgrade_success"; os_sprintf(pSendData, UPGRADE_FRAME, deviceKey, pAction, pServerInfo->pre_version, pServerInfo->upgrade_version); os_printf("%s\n", pSendData); espconn_sent(pEspconn, pSendData, os_strlen(pSendData)); system_upgrade_reboot(); // 升级后重启 if(pSendData != NULL) { os_free(pSendData); pSendData = NULL; } } else { os_printf("user_esp_platform_upgrade_failed\n"); pAction = "device_upgrade_failed"; os_sprintf(pSendData, UPGRADE_FRAME, deviceKey, pAction, pServerInfo->pre_version, pServerInfo->upgrade_version); os_printf("%s\n", pSendData); espconn_sent(pEspconn, pSendData, os_strlen(pSendData)); if(pSendData != NULL) { os_free(pSendData); pSendData = NULL; } } os_free(pServerInfo->url); pServerInfo->url = NULL; os_free(pServerInfo); pServerInfo = NULL; } 五、烧录

例如4M的Flash

• 由 Leung 写于 2019 年 10 月 11 日

• 参考:ESP8266 Non-OS SDK API参考[7qq6]     ESP8266 Non-OS SDK IoT Demo指南[kvle]     ESP8266云端升级指南[5oh3]     Esp8266进阶之路18 esp8266 基于NONOS实现 OTA 远程升级



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3