赞
踩
参考例程:examples\system\ota\simple_ota_example
选择要升级的程序(bin文件);
打开命令行界面,并进入到包含要升级的程序的目录文件夹下;
输入命令 python2 -m SimpleHTTPServer 8070(有些可能是python -m SimpleHTTPServer 8070),并执行;
保持命令行模式软件不要关闭;
在浏览器输入http://xxx.xxx.xxx.xxx:8070,验证http服务器是否成功;
命令行界面也有提示输出,执行的是GET操作;
在接下来的实验中也要保持命令行模式不要关闭。
void app_main(void) { /*省略了代码,主要作用是芯片初始化、wifi连接等*/ xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL); } void simple_ota_example_task(void *pvParameter) { ESP_LOGI(TAG, "Starting OTA example"); esp_http_client_config_t config = { .url = CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL, //这里即升级程序的URL,在菜单中配置 .cert_pem = (char *)server_cert_pem_start, //https所需要的认证,但这里是http,所以并不需要用到 .event_handler = _http_event_handler, }; esp_err_t ret = esp_https_ota(&config); //连接http,并下载升级程序 if (ret == ESP_OK) { esp_restart(); //下载程序成功,重启即执行升级程序 } else { ESP_LOGE(TAG, "Firmware upgrade failed"); } //一切正常的话不会执行到这里,如下升级程序下载失败则执行下列程序 while (1) { vTaskDelay(1000 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "while ---"); } }
感觉这个例程没有太大的实用性,只是帮助了解OTA的基本操作。
参考资料:阿里云物联网平台->设备端OTA升级
该工程是以 app-MqttToAliyun为基础,所以已经实现了ESP32设备与阿里云之间的通信。
打开阿里云物联网平台,定位到 “物联网平台/监控运维/OTA 升级 ” ,点击 “添加升级包”,如下填完参数,最后点击下方“确认”,升级包随便选择一个工程的.bin文件
升级包上传完成
点击右方“批量升级”
点击左下角 下一步
到这里阿里云物联网平台就配置完了,只要ESP32开发板连接到阿里云平物联网平台的 ESP8266-TEST产品下的dev-esp32设备,就会收到阿里云物联网平台推送的JSON数据,(当然ESP32开发板要实现了OTA程序)
extern const uint8_t server_root_crt_start[] asm("_binary_root_crt_start"); //注意该地方需要修改
extern const uint8_t server_root_crt_end[] asm("_binary_root_crt_end");
esp_http_client_config_t config = {
.url = url_buf,
.cert_pem = (char *)server_root_crt_start,
.event_handler = _http_event_handler,
};
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { esp_mqtt_client_handle_t client = event->client; int msg_id; // your_context_t *context = event->context; switch (event->event_id) { case MQTT_EVENT_CONNECTED: break; case MQTT_EVENT_DISCONNECTED: break; case MQTT_EVENT_SUBSCRIBED: break; case MQTT_EVENT_UNSUBSCRIBED: break; case MQTT_EVENT_PUBLISHED: break; case MQTT_EVENT_DATA: ESP_LOGI(TAG, "MQTT_EVENT_DATA"); printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); //打印主题 printf("DATA=%.*s\r\n", event->data_len, event->data); //打印数据 break; case MQTT_EVENT_ERROR: break; default: break; } return ESP_OK; }
#define AliyunSubscribeTopic_ota_upgrade "/ota/device/upgrade/a1tUbQR2faQ/dev-esp32" #define AliyunPublishTopic_ota_inform "/ota/device/inform/a1tUbQR2faQ/dev-esp32" static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { esp_mqtt_client_handle_t client = event->client; // your_context_t *context = event->context; switch (event->event_id) { ... case MQTT_EVENT_DATA: ESP_LOGI(TAG, "MQTT_EVENT_DATA"); char *topicBuf = (char*)malloc(event->topic_len+1); //void *memcpy(void *s1, const void *s2, size_t n); 函数memcpy从s2指向的对象中复制n个字符到s1指向的对象中。 memcpy(topicBuf, event->topic, event->topic_len); //printf("---Receive topic:\n %s \r\n", topicBuf);//打印接收的消息 temp = strcmp(topicBuf,AliyunSubscribeTopic_ota_upgrade); //判断主题是否是OTA主题,如果是才调用OTA的JSON解析函数 if(0 == temp) { ESP_LOGI(TAG, "OTA DATA PARSE"); //char *strncpy(char *s2, const char *s1, size_t n);函数strncpy从s1指向的数组中最多复制n个字符(不复制空字符后面的字符)到s2指向的数组中。 strncpy(local_data_buffer, event->data, event->data_len); //将指针类型的数据复制到一个数组中 //printf("local_data_buffer:%s ", local_data_buffer); ret = user_parse_json(local_data_buffer,aliyun_ota_config);//解析数据,并使用解析出来的URL下载OTA升级包 if (ret == ESP_OK) //解析并下载OTA升级包成功 { //构造JSON格式数据,该数据用于反馈给阿里云物联网平台,作用是通知升级包接收完成 cJSON *Wroot = cJSON_CreateObject(); cJSON *Pitem = cJSON_CreateObject(); cJSON_AddItemToObject(Wroot, "id", cJSON_CreateString("123")); cJSON_AddItemToObject(Wroot, "params", Pitem); cJSON_AddItemToObject(Pitem, "step", cJSON_CreateString("100")); cJSON_AddItemToObject(Pitem, "desc", cJSON_CreateString("OTA update successfully !")); cJSON_AddItemToObject(Pitem, "module", cJSON_CreateString("MCU")); //printf("%s\n", cJSON_Print(Wroot)); //打印刚才构建的JSON数据,看是否正确 char ota_inform_buf[512]; int len = strlen(cJSON_Print(Wroot)); memcpy(ota_inform_buf, cJSON_Print(Wroot),len); //将JSON格式数据复制到数组中,将以数组的形式传递给发布函数 ota_inform_buf[len] = '\0'; printf("%s\n",ota_inform_buf);//打印数据是否正确 //发布信息到阿里云物联网平台 msg_id = esp_mqtt_client_publish(client, AliyunPublishTopic_ota_inform, ota_inform_buf, strlen(ota_inform_buf), 0, 0); ESP_LOGI(TAG, "sent publish ota inform successful, msg_id=%d", msg_id); // cJSON_Delete(Wroot); //执行这个函数会出错,不知道什么原因 // cJSON_Delete(Pitem); esp_restart(); //ESP32设备重启,重启后将执行刚才下载的程序 } else { ESP_LOGE(TAG, "Firmware upgrade failed"); } } free(topicBuf); break; ... default: break; } return ESP_OK; }
esp_err_t user_parse_json(char *json_data,user_aliyun_ota_config_t ota_config) { cJSON *item = NULL; cJSON *root = NULL; //root 开始------------------------------------------------------------------------- root = cJSON_Parse(json_data); /*json_data 阿里云OTA原始数据*/ if (!root) { printf("Error before: [%s]\n",cJSON_GetErrorPtr()); return ESP_FAIL; } printf("%s\n\n", cJSON_Print(root)); /*将完整的数据以JSON格式打印出来*/ item = cJSON_GetObjectItem(root, "code"); ota_config.code = cJSON_Print(item); //data 开始------------------------------------------------------------------------- cJSON *Pdata = cJSON_GetObjectItem(root, "data"); item = cJSON_GetObjectItem(Pdata, "size"); ota_config.size = item->valueint; //extData 开始------------------------------------------------------------------------- cJSON *PextData = cJSON_GetObjectItem(Pdata, "extData"); item = cJSON_GetObjectItem(PextData, "_package_udi"); ota_config._package_udi = cJSON_Print(item); //extData 结束------------------------------------------------------------------------- item = cJSON_GetObjectItem(Pdata, "sign"); ota_config.sign = cJSON_Print(item); item = cJSON_GetObjectItem(Pdata, "version"); ota_config.version = cJSON_Print(item); item = cJSON_GetObjectItem(Pdata, "url"); ota_config.url = cJSON_Print(item); item = cJSON_GetObjectItem(Pdata, "signMethod"); ota_config.signMethod = cJSON_Print(item); item = cJSON_GetObjectItem(Pdata, "md5"); ota_config.md5 = cJSON_Print(item); //data 结束------------------------------------------------------------------------- item = cJSON_GetObjectItem(root, "id"); ota_config.id = item->valuedouble; item = cJSON_GetObjectItem(root, "message"); ota_config.message = cJSON_Print(item); //root 结束------------------------------------------------------------------------- // cJSON_Delete(root); //执行这个函数会出错,不知道什么原因 // cJSON_Delete(Pdata); // cJSON_Delete(PextData); // cJSON_Delete(item); // printf("code:%s\n", ota_config.code); // printf("size:%d\n", ota_config.size); // printf("_package_udi:%s\n", ota_config._package_udi); // printf("sign:%s\n", ota_config.sign); // printf("version:%s\n", ota_config.version); // printf("url:%s\n", ota_config.url); // printf("signMethod:%s\n", ota_config.signMethod); // printf("md5:%s\n", ota_config.md5); // printf("id:%f\n", ota_config.id); // printf("message:%s\n", ota_config.message); char url_buf[OTA_URL_SIZE]; int len = strlen(ota_config.url); memcpy(url_buf, ota_config.url, len); //将指针型数据复制到数组中, //解析出来的URL包含了双引号"",但数组中的URL不能包含双引号"" for(int i = 0;i < len;i++ ) { url_buf[i] = url_buf[i+1]; //为了去掉数组中的双引号“”,这里是前部分 } url_buf[len - 2] = '\0'; //为了去掉数组中的双引号“”,这里是后部分 printf("buf:%s\n", url_buf); //打印检查URL是否正确 esp_http_client_config_t config = { //. url = "https://xxx" //这里需要双引号"" .url = url_buf, //这里,数组中不能包含双引号"" .cert_pem = (char *)server_root_crt_start, .event_handler = _http_event_handler, }; esp_err_t ret = esp_https_ota(&config); //下载升级包等一系列操作 return ret; }
程序编写完成,编译下载到ESP32设备中,查看串口打印数据,如下
//数据开始 ets Jul 29 2019 12:21:46 ... I (61) boot: Partition Table: //分区表 I (64) boot: ## Label Usage Type ST Offset Length I (72) boot: 0 nvs WiFi data 01 02 00009000 00004000 I (79) boot: 1 otadata OTA data 01 00 0000d000 00002000 I (87) boot: 2 phy_init RF data 01 01 0000f000 00001000 I (94) boot: 3 factory factory app 00 00 00010000 00100000 I (102) boot: 4 ota_0 OTA app 00 10 00110000 00100000 I (109) boot: 5 ota_1 OTA app 00 11 00210000 00100000 I (117) boot: End of partition table I (121) boot: Defaulting to factory image //刚编译并通过有线烧录,默认执行工厂镜像程序 ... I (498) boot: Loaded app from partition at offset 0x10000 //从偏移地址0x10000处加载程序 I (498) boot: Disabling RNG early entropy source... I (498) cpu_start: Pro cpu up. I (502) cpu_start: Application information: //该程序信息 I (507) cpu_start: Project name: app-MqttToAliyun I (513) cpu_start: App version: 5204503a-dirty I (518) cpu_start: Compile time: Jul 3 2021 11:33:25 ... I (0) cpu_start: App cpu up. ... I (1698) wifi station: connected to ap SSID:canbo-418-2.4G password:canbo418 //连接wifi I (1708) MQTT_EXAMPLE: into mqtt_test_task //开始执行mqtt任务,即连接阿里云物联网平台 I (1708) MQTT_EXAMPLE: Other event id:7 I (1948) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED I (1948) MQTT_EXAMPLE: sent publish successful, msg_id=49855 I (1948) MQTT_EXAMPLE: sent subscribe successful, msg_id=15854 I (1998) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=49855 I (2058) MQTT_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=15854 I (2068) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (6228) MQTT_EXAMPLE: MQTT_EVENT_DATA I (6238) MQTT_EXAMPLE: OTA DATA PARSE//收到阿里云物联网平台推送的OTA的JSON格式数据 { "code": "1000", "data": { "size": 822528, "extData": { "_package_udi": "这是阿里云OTA测试程序" }, "sign": "72fd4a8b0e67fc0657b1ea707570e27a", "version": "1.00", "url": "https://iotx-ota.oss-cn-shanghai.aliyuncs.com/ota/6bc61a794bad89c4c1edf4ecf46a1666/ckqnivitr0003268hsmg81bac.bin?Expires=1625537056&OSSAccessKeyId=LTAI4G1TuWwSirnbAzUHfL3e&Signature=39CeoZ34CY1KucXl69yq1ajHqDw%3D", "signMethod": "Md5", "md5": "72fd4a8b0e67fc0657b1ea707570e27a" }, "id": 1625450656015, "message": "success" } buf:https://iotx-ota.oss-cn-shanghai.aliyuncs.com/ota/6bc61a794bad89c4c1edf4ecf46a1666/ckqnivitr0003268hsmg81bac.bin?Expires=1625537056&OSSAccessKeyId=LTAI4G1TuWwSirnbAzUHfL3e&Signature=39CeoZ34CY1KucXl69yq1ajHqDw%3D//解析出升级包的URL I (7808) esp_https_ota: Starting OTA...//开始执行OTA下载等操作 I (7818) esp_https_ota: Writing to partition subtype 16 at offset 0x110000 I (8858) MQTT_EXAMPLE: while---//这里是无操作时while(1)执行的打印 I (15948) MQTT_EXAMPLE: while--- I (22208) esp_https_ota: Connection closed //下载OTA升级包的一些打印信息 I (22218) esp_image: segment 0: paddr=0x00110020 vaddr=0x3f400020 size=0x1deec (122604) map ... I (22808) esp_image: segment 5: paddr=0x001c3b1c vaddr=0x40080404 size=0x151b8 ( 86456) //下面的JSON数据时发布到阿里云物联网的数据 { "id": "123", "params": { "step": "100", "desc": "OTA update successfully !", "module": "MCU" } } I (22868) MQTT_EXAMPLE: sent publish ota inform successful, msg_id=0 //下面是执行了重启函数esp_restart();后关闭wifi等一系列操作 I (22868) wifi:state: run -> init (0) I (22868) wifi:pm stop, total sleep time: 4226386 us / 21765363 us I (22878) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1 W (22888) wifi:hmac tx: stop, discard W (22888) wifi:hmac tx: stop, discard I (22938) wifi:flush txq I (22938) wifi:stop sw txq I (22938) wifi:lmac stop hw txq //下面是开始执行升级后的程序 ets Jul 29 2019 12:21:46 ... I (484) cpu_start: Pro cpu up. I (487) cpu_start: Application information://这里的升级后的程序信息,和前面的不一样了 I (492) cpu_start: Project name: app-AliyunFinishOTA I (498) cpu_start: App version: 5204503a-dirty I (504) cpu_start: Compile time: Jul 3 2021 16:21:00 .. I (513) cpu_start: App cpu up. ... //下面执行的是升级后的程序 I (2184) wifi station: connected to ap SSID:canbo-418-2.4G password:canbo418//连接wifi I (2194) MQTT_EXAMPLE: Other event id:7 I (2364) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED I (2374) MQTT_EXAMPLE: sent publish ota inform successful, msg_id=0 I (2374) MQTT_EXAMPLE: sent publish successful, msg_id=55995 I (2374) MQTT_EXAMPLE: sent subscribe successful, msg_id=39235 I (2484) MQTT_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=39235 I (2484) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2494) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=55995 I (7194) MQTT_EXAMPLE: i am aliyun finish ota I (7904) MQTT_EXAMPLE: MQTT_EVENT_DATA TOPIC=/ota/device/upgrade/a1tUbQR2faQ/dev-esp32 DATA={"code":"1000","data":{"size":822528,"extData":{"_package_udi":"这是阿里云OTA测试程序"},"sign":"72fd4a8b0e67fc0657b1ea707570e27a","version":"1.00","url":"https://iotx-ota.oss-cn-shanghai.aliyuncs.com/ota/6bc61a794bad89c4c1edf4ecf46a1666/ckqnivitr0003268hsmg81bac.bin?Expires=1625537080&OSSAccessKeyId=LTAI4G1TuWwSirnbAzUHfL3e&Signature=o8nS68PWhNy2fAqvn5U5Soxaaco%3D","signMethod":"Md5","md5":"72fd4a8b0e67fc0657b1ea707570e27a"},"id":1625450680578,"message":"success"} I (12194) MQTT_EXAMPLE: i am aliyun finish ota I (17194) MQTT_EXAMPLE: i am aliyun finish ota Done
详细信息请自行测试
工程链接:app-AliyunOTA
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。