/* * @Date: 2024-07-18 16:55:31 * @LastEditors: lzc56 563451665@qq.com * @LastEditTime: 2025-01-02 13:45:42 * @FilePath: \software\main\src\bsp_upgrade.c */ #include "bsp_mqtt.h" #include "esp_wifi.h" #include "drv_fatfs.h" #include "drv_usart.h" #include "bsp_algCom.h" #include "bsp_bleNet.h" #include "bsp_upgrade.h" #include "crcTable.h" // #include "ymodem.h" #define FILE_URL "http://dev.bewatec.com.cn:22223/test/10004/mods/mattress/S1.0.0" #define FILE_PATH "/spiflash/OTA.bin" #define PACKET_SIZE 512 CRC32_CTX ota_ctx; ota_info_t ota_info; TaskHandle_t upgrade_TaskHandle; static const char *TAG = "bsp/upgrade"; uint32_t deviceUpgradeNum = 0; int LastPacketLessSize = 0; char otaSendBuffer[PACKET_SIZE] = {0}; char LastPacketBuffer[PACKET_SIZE] = {0}; extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start"); extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end"); // extern void dump_hex(const uint8_t *buf, uint32_t size); extern esp_err_t nvs_write_otaInfo(ota_info_t *pOta_info_t, uint32_t len); #define OTA_URL_SIZE 256 static void send_GoIntoOTA(void); static void send_ota_Info(void); void send_ota_Upgrade(void); long fsize(FILE *fp); void Ymodem_Exit(void); void prepareUpgrade(void); void protobufSendOta(void); char Ymodem_checkFile(void); void list_dir(const char *path); void CRC32_Init(CRC32_CTX *ctx); void upgradeTimeOut_Reboot(void); void dump_hex(const uint8_t *buf, uint32_t size); void download_file_task(void *pvParameters); void CRC32_Final(CRC32_CTX *ctx, unsigned char *md); void CRC32_Update(CRC32_CTX *ctx, const unsigned char *data, size_t len); static char send_ota_bin(char *data, int len, uint32_t packetNum); /* Event handler for catching system events */ static void ota_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (event_base == ESP_HTTPS_OTA_EVENT) { switch (event_id) { case ESP_HTTPS_OTA_START: ESP_LOGI(TAG, "OTA started"); break; case ESP_HTTPS_OTA_CONNECTED: ESP_LOGI(TAG, "Connected to server"); break; case ESP_HTTPS_OTA_GET_IMG_DESC: ESP_LOGI(TAG, "Reading Image Description"); break; case ESP_HTTPS_OTA_VERIFY_CHIP_ID: ESP_LOGI(TAG, "Verifying chip id of new image: %d", *(esp_chip_id_t *)event_data); break; case ESP_HTTPS_OTA_DECRYPT_CB: ESP_LOGI(TAG, "Callback to decrypt function"); break; case ESP_HTTPS_OTA_WRITE_FLASH: ESP_LOGD(TAG, "Writing to flash: %d written", *(int *)event_data); break; case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION: ESP_LOGI(TAG, "Boot partition updated. Next Partition: %d", *(esp_partition_subtype_t *)event_data); break; case ESP_HTTPS_OTA_FINISH: ESP_LOGI(TAG, "OTA finish"); break; case ESP_HTTPS_OTA_ABORT: ESP_LOGI(TAG, "OTA abort"); break; } } } static esp_err_t validate_image_header(esp_app_desc_t *new_app_info) { if (new_app_info == NULL) { return ESP_ERR_INVALID_ARG; } const esp_partition_t *running = esp_ota_get_running_partition(); esp_app_desc_t running_app_info; if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version); } #ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) { ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update."); // return ESP_FAIL; } #endif return ESP_OK; } static esp_err_t _http_client_init_cb(esp_http_client_handle_t http_client) { esp_err_t err = ESP_OK; /* Uncomment to add custom headers to HTTP request */ // err = esp_http_client_set_header(http_client, "Custom-Header", "Value"); return err; } void selfUpgradeTask(void *pvParameter) { char url_Buffer[128] = {0}; memcpy(url_Buffer, ota_info.url, sizeof(ota_info.url)); strcat(url_Buffer, "/"); strcat(url_Buffer, ota_info.wifiPath); ESP_LOGI(TAG, "url : %s", url_Buffer); ESP_LOGI(TAG, "Starting Advanced OTA example"); esp_err_t ota_finish_err = ESP_OK; esp_http_client_config_t config = { .url = url_Buffer, // .cert_pem = (char *)server_cert_pem_start, .timeout_ms = 5000, .keep_alive_enable = true, }; esp_https_ota_config_t ota_config = { .http_config = &config, .http_client_init_cb = _http_client_init_cb, // Register a callback to be invoked after esp_http_client is initialized }; esp_https_ota_handle_t https_ota_handle = NULL; esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle); int imageSize = esp_https_ota_get_image_size(https_ota_handle); ESP_LOGI(TAG, "Sum Size is %d", imageSize); if (err != ESP_OK) { ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed"); char temp_Buffer[128] = {0}; // TODO:上报升级失败 再 复位 sprintf(temp_Buffer, "{\"ota\": -1}"); mqtt_UploadOTAInfo(temp_Buffer); vTaskDelay(500 / portTICK_PERIOD_MS); esp_restart(); vTaskDelete(NULL); } esp_app_desc_t app_desc; err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_https_ota_read_img_desc failed"); goto ota_end; } err = validate_image_header(&app_desc); if (err != ESP_OK) { ESP_LOGE(TAG, "image header verification failed"); goto ota_end; } float progress = 0.0f; char temp_Buffer[64] = {0}; while (1) { err = esp_https_ota_perform(https_ota_handle); if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) { break; } // esp_https_ota_perform returns after every read operation which gives user the ability to // monitor the status of OTA upgrade by calling esp_https_ota_get_image_len_read, which gives length of image // data read so far. int currentSize = esp_https_ota_get_image_len_read(https_ota_handle); // ESP_LOGI(TAG, "currentSize %d ,imageSize %d", currentSize, imageSize); progress = ((float)currentSize / (float)imageSize) * 100.0f; ESP_LOGI(TAG, "%.3f%%", progress); sprintf(temp_Buffer, "{\"type\":\"COM\",\"ota_progress\":\"%.2f%%\"}", progress); if (((int)progress % 5) == 0) mqtt_UploadOTAProgress(temp_Buffer); // xTimerReset(upgradeTimeOut_timer, 0); } if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) { // the OTA image was not completely received and user can customise the response to this situation. ESP_LOGE(TAG, "Complete data was not received."); } else { ota_finish_err = esp_https_ota_finish(https_ota_handle); if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) { char Temp[] = {"{\"ota\":1}"}; send_ota_bin(otaSendBuffer, PACKET_SIZE, deviceUpgradeNum * PACKET_SIZE); for (int i = 0; i < 5; i++) { com_SendData("\xA5\x5A\x01\x00\xFF", 5); // STM32部分的复位指令 vTaskDelay(pdMS_TO_TICKS(50)); } ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ..."); mqtt_UploadOTAInfo(Temp); vTaskDelay(1000 / portTICK_PERIOD_MS); esp_restart(); } else { if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) { ESP_LOGE(TAG, "Image validation failed, image is corrupted"); } ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err); vTaskDelete(NULL); } } ota_end: esp_https_ota_abort(https_ota_handle); ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed"); vTaskDelete(NULL); } /** * @description: selfUpgrade * @return {*} */ int countPkg = 0; long sumSize = 0; long algTotalSize = 0; char upgradeFlag = 0; unsigned char crcValue[4] = {0}; void selfUpgrade(void) { BaseType_t err = xSemaphoreTake(OTA_deviceUpgradeDoneSemaphore, portMAX_DELAY); ESP_LOGI(TAG, "OTA example app_main start"); ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &ota_event_handler, NULL)); #if defined(CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE) /** * We are treating successful WiFi connection as a checkpoint to cancel rollback * process and mark newly updated firmware image as active. For production cases, * please tune the checkpoint behavior per end application requirement. */ const esp_partition_t *running = esp_ota_get_running_partition(); esp_ota_img_states_t ota_state; if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) { if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) { if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) { ESP_LOGI(TAG, "App is valid, rollback cancelled successfully"); } else { ESP_LOGE(TAG, "Failed to cancel rollback"); } } } #endif #if CONFIG_BT_ENABLED /* Ensure to disable any WiFi power save mode, this allows best throughput * and hence timings for overall OTA operation. */ esp_wifi_set_ps(WIFI_PS_NONE); #else /* WIFI_PS_MIN_MODEM is the default mode for WiFi Power saving. When both * WiFi and Bluetooth are running, WiFI modem has to go down, hence we * need WIFI_PS_MIN_MODEM. And as WiFi modem goes down, OTA download time * increases. */ esp_wifi_set_ps(WIFI_PS_MIN_MODEM); #endif // CONFIG_BT_ENABLED xTaskCreate(&selfUpgradeTask, "selfUpgradeTask", 1024 * 12, NULL, 5, NULL); } //---------------------------------------------------------------------------- esp_err_t http_event_handler(esp_http_client_event_t *evt) { float progress = 0.0f; char temp_Buffer[64] = {0}; switch (evt->event_id) { case HTTP_EVENT_ERROR: printf("HTTP_EVENT_ERROR\n"); break; case HTTP_EVENT_REDIRECT: printf("HTTP_EVENT_REDIRECT\n"); break; case HTTP_EVENT_ON_CONNECTED: sumSize = 0; countPkg = 0; ota_Fatfs_Init(); printf("HTTP_EVENT_ON_CONNECTED\n"); break; case HTTP_EVENT_HEADER_SENT: printf("HTTP_EVENT_HEADER_SENT\n"); break; case HTTP_EVENT_ON_HEADER: printf("HTTP_EVENT_ON_HEADER, key=%s, value=%s\n", evt->header_key, evt->header_value); if (strcmp(evt->header_key, "Content-Length") == 0) algTotalSize = atoi(evt->header_value); break; case HTTP_EVENT_ON_DATA: countPkg++; sumSize += evt->data_len; if (sumSize < algTotalSize) CRC32_Update(&ota_ctx, evt->data, evt->data_len); else if (sumSize == algTotalSize) { // 获取结尾校验相关 ota_ctx.rec = 0; ESP_LOGI(TAG, "Last Packet..."); CRC32_Update(&ota_ctx, evt->data, evt->data_len - 4); memcpy(&ota_ctx.rec, evt->data + (evt->data_len - 4), 4); ESP_LOGI(TAG, "ota_ctx.rec : %lx", ota_ctx.rec); } // printf("HTTP_EVENT_ON_DATA, len=%d count %d sumSize %ld \r\n", // evt->data_len, countPkg, sumSize); if (!esp_http_client_is_chunked_response(evt->client)) { // Write received data to a file FILE *f = fopen(FILE_PATH, "a"); if (f == NULL) { printf("Failed to open file for writing\n"); return ESP_FAIL; } fwrite(evt->data, 1, evt->data_len, f); fclose(f); } progress = ((float)sumSize / (float)algTotalSize) * 100.0f; ESP_LOGI(TAG, "%.3f%%", progress); sprintf(temp_Buffer, "{\"type\":\"DL\",\"ota_progress\":\"%.2f%%\"}", progress); if (((int)progress % 5) == 0) mqtt_UploadOTAProgress(temp_Buffer); break; case HTTP_EVENT_ON_FINISH: printf("HTTP_EVENT_ON_FINISH\n"); CRC32_Final(&ota_ctx, crcValue); printf(" ota_ctx : %lx\n", ota_ctx.crc); // if (ota_ctx.crc == ota_ctx.rec) if (1) { upgradeFlag = 1; // 需要进行升级算法 ESP_LOGI(TAG, "File Check Success"); FILE *f = fopen(FILE_PATH, "rb"); printf("Done Size :%ld\n", fsize(f)); fclose(f); ota_Fatfs_deinit(); } else { upgradeFlag = 0; // 不需要进行升级算法 ESP_LOGE(TAG, "File Check Fail"); // TODO:上报升级失败 再 复位 sprintf(temp_Buffer, "{\"ota\": -1}"); mqtt_UploadOTAInfo(temp_Buffer); esp_restart(); } break; case HTTP_EVENT_DISCONNECTED: printf("HTTP_EVENT_DISCONNECTED\n"); break; } return ESP_OK; } void download_file_task(void *pvParameters) { char temp_Buffer[128] = {0}; // TODO: 如果之前就有文件则不进行下载 判断升级正常之后 重新进行升级流程 if (Ymodem_checkFile() == 1) goto file_exist; #if 1 char url_Buffer[128] = {0}; memcpy(url_Buffer, ota_info.url, sizeof(ota_info.url)); strcat(url_Buffer, "/"); strcat(url_Buffer, ota_info.mattressPath); ESP_LOGI(TAG, "url : %s", url_Buffer); esp_http_client_config_t config = { .url = url_Buffer, .event_handler = http_event_handler, }; esp_http_client_handle_t client = esp_http_client_init(&config); // Set up file to store the downloaded data ota_Fatfs_Init(); FILE *f = fopen(FILE_PATH, "w+"); printf("Empty Size :%ld\n", fsize(f)); if (f == NULL) { printf("Failed to create file for writing\n"); remove(FILE_PATH); // 移除文件 return; } fclose(f); ota_Fatfs_deinit(); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK && upgradeFlag == 1) { printf("File downloaded successfully\n"); } else { printf("File download failed\n"); char temp_Buffer[128] = {0}; // TODO:上报升级失败 再 复位 sprintf(temp_Buffer, "{\"ota\": -1}"); mqtt_UploadOTAInfo(temp_Buffer); vTaskDelay(500 / portTICK_PERIOD_MS); esp_restart(); } esp_http_client_close(client); esp_http_client_cleanup(client); #else upgradeFlag = 1; algTotalSize = 214796; #endif file_exist: printf("File DL Done\r\n"); while (1) { const TickType_t xFrequency = 200; if (upgradeFlag) { printf("Ready Ymodem Upgrade\n"); // xTimerStart(upgradeTimeOut_timer, 0); // TODO: 增加文件大小的存储 NVS ota_info.mattressBinSize = algTotalSize; ESP_LOGI(TAG, "mattressBinSize :%ld ", ota_info.mattressBinSize); // nvs_write_otaInfo(&ota_info, sizeof(ota_info)); // TODO: 升级增加 准备工序 send_GoIntoOTA(); send_ota_Info(); // 发送 send_ota_Upgrade(); // xTimerStop(upgradeTimeOut_timer, 0); // 发生设备升级完成状态指示二值信号量 xSemaphoreGive(OTA_deviceUpgradeDoneSemaphore); vTaskDelete(NULL); } // vTaskDelay(pdMS_TO_TICKS(25)); } } void deviceUpgrade(void) { CRC32_Init(&ota_ctx); xTaskCreate(&download_file_task, "download_file_task", 4096, NULL, 5, NULL); } //---------------------------------------------------------------------------- void upgrade_task(void *arg) { uint32_t KeepAlive = 0; while (1) { KeepAlive++; BaseType_t err = xSemaphoreTake(OTA_startSemaphore, 50); if (err == pdPASS) { ESP_LOGI(TAG, "---------------OTA Start---------------\r\n"); // 如果刚上电就升级 if (xTimerIsTimerActive(NetConfig_timer) == pdTRUE) { xTimerStop(NetConfig_timer, 0); vTaskDelete(BLE_NetTasks_TaskHandle); // 关闭配网线程 vTaskDelete(ParseTaskHandle); // 关闭解析线程 } // 长时间运行的线程 if (esp_task_wdt_status(Alg_TaskHandle) == ESP_OK) esp_task_wdt_delete(Alg_TaskHandle); vTaskSuspend(MQTT_TaskHandle); // vTaskDelete(Alg_TaskHandle); // 其他设备升级 OTA deviceUpgrade(); // Test: xSemaphoreGive(OTA_deviceUpgradeDoneSemaphore); // 自身 OTA selfUpgrade(); } vTaskDelay(pdMS_TO_TICKS(1000)); ESP_LOGI(TAG, "KeepAlive = %ld, arg = %s", KeepAlive, (char *)arg); } } void CRC32_Init(CRC32_CTX *ctx) { ctx->crc = 0xFFFFFFFFL; } void CRC32_Update(CRC32_CTX *ctx, const unsigned char *data, size_t len) { for (size_t i = 0; i < len; i++) { ctx->crc = (ctx->crc >> 8) ^ crc32_table[(ctx->crc & 0xFF) ^ *data++]; } } void CRC32_Final(CRC32_CTX *ctx, unsigned char *md) { ctx->crc ^= 0xFFFFFFFFUL; *md++ = (ctx->crc & 0xFF000000UL) >> 24; *md++ = (ctx->crc & 0x00FF0000UL) >> 16; *md++ = (ctx->crc & 0x0000FF00UL) >> 8; *md++ = (ctx->crc & 0x000000FFUL); } long fsize(FILE *fp) { long n; fpos_t fpos; // 当前位置 fgetpos(fp, &fpos); // 获取当前位置 fseek(fp, 0, SEEK_END); n = ftell(fp); fsetpos(fp, &fpos); // 恢复之前的位置 return n; } void list_dir(const char *path) { DIR *dir; struct dirent *entry; printf(" ------------------------ \n"); if ((dir = opendir(path)) == NULL) { perror("opendir() error\n"); } else { puts("contents of directory:"); while ((entry = readdir(dir)) != NULL) { printf(" %s\n", entry->d_name); } closedir(dir); } printf(" ------------------------ \n"); } char Ymodem_checkFile(void) { ota_Fatfs_Init(); list_dir("/spiflash"); // -------------------------------------------------------- // TODO :先读取有没有文件 大小是否满足要求 uint32_t fileSize = 0; FILE *fp = fopen(FILE_PATH, "a"); fileSize = fsize(fp); printf("File Size :%ld\n", fileSize); fclose(fp); ota_Fatfs_deinit(); if (fileSize == ota_info.mattressBinSize && fileSize >= 200000) { // 检测文件大小是否满足要求 upgradeFlag = 1; algTotalSize = fileSize; // 是 :跳过下载文件流程 return 1; // 否 :擦除文件 继续下载 } else { ota_Fatfs_Init(); remove(FILE_PATH); // 升级完成 移除文件 ota_Fatfs_deinit(); } return 0; // -------------------------------------------------------- } #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') void dump_hex(const uint8_t *buf, uint32_t size) { int i, j; for (i = 0; i < size; i += 16) { printf("%08X: ", i); for (j = 0; j < 16; j++) { if (i + j < size) { printf("%02X ", buf[i + j]); } else { printf(" "); } } printf(" "); for (j = 0; j < 16; j++) { if (i + j < size) { printf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.'); } } printf("\n"); } } static void send_GoIntoOTA(void) { char buff[9]; uint32_t crc; EventBits_t Event; buff[0] = 0xA5; buff[1] = 0x5A; buff[2] = 0x05; buff[3] = 0x00; buff[4] = 0x10; // 控制字 crc = My_crc32((unsigned char *)buff, 5); buff[5] = (uint8_t)crc; buff[6] = (uint8_t)(crc >> 8); buff[7] = (uint8_t)(crc >> 16); buff[8] = (uint8_t)(crc >> 24); for (int i = 0; i < 30; i++) { com_SendData("\xA5\x5A\x01\x00\x10", 5); Event = xEventGroupWaitBits(xComEventGroup, COM_OTA_MSG_OK | COM_OTA_MSG_DONE | COM_OTA_MSG_RESEND, pdTRUE, pdFALSE, (150 / portTICK_PERIOD_MS)); if (Event & COM_OTA_MSG_OK) { ESP_LOGI(TAG, "GO INTO OTA COM_OTA_MSG_OK resend: %d", i); return; } else if (Event & COM_OTA_MSG_RESEND) ESP_LOGI(TAG, "GO INTO OTA COM_OTA_MSG_RESEND resend: %d", i); else ESP_LOGI(TAG, "GO INTO OTA COM_OTA_MSG_DONE resend: %d", i); } } static void send_ota_Info(void) { uint32_t crc; char buff[17], i; EventBits_t Event; buff[0] = 0xA5; buff[1] = 0x5A; buff[2] = 0x0D; buff[3] = 0x00; buff[4] = 0x11; // 控制字 buff[5] = ota_info.version[0]; buff[6] = ota_info.version[1]; buff[7] = ota_info.version[2]; buff[8] = ota_info.version[3]; buff[9] = (uint8_t)ota_info.mattressBinSize; buff[10] = (uint8_t)(ota_info.mattressBinSize >> 8); buff[11] = (uint8_t)(ota_info.mattressBinSize >> 16); buff[12] = (uint8_t)(ota_info.mattressBinSize >> 24); crc = My_crc32((unsigned char *)buff, 13); buff[13] = (uint8_t)crc; buff[14] = (uint8_t)(crc >> 8); buff[15] = (uint8_t)(crc >> 16); buff[16] = (uint8_t)(crc >> 24); for (i = 0; i < 25; i++) { com_SendData((const char *)buff, 17); Event = xEventGroupWaitBits(xComEventGroup, COM_OTA_MSG_OK | COM_OTA_MSG_DONE | COM_OTA_MSG_RESEND, pdTRUE, pdFALSE, (150 / portTICK_PERIOD_MS)); if (Event & COM_OTA_MSG_OK) { ESP_LOGI(TAG, "GO INTO OTA COM_OTA_MSG_OK resend: %d", i); return; } else if (Event & COM_OTA_MSG_RESEND) ESP_LOGI(TAG, "GO INTO OTA COM_OTA_MSG_RESEND resend: %d", i); else ESP_LOGI(TAG, "GO INTO OTA COM_OTA_MSG_DONE resend: %d", i); } } static char send_ota_bin(char *data, int len, uint32_t packetNum) // 数据的长度(不是一帧的长度) { char buff[len + 13]; EventBits_t Event; uint32_t crc; int i; memset(buff, 0, sizeof(buff)); buff[0] = 0xA5; buff[1] = 0x5A; buff[2] = (uint8_t)(len + 9); buff[3] = (uint8_t)((len + 9) >> 8); buff[4] = 0x12; // 控制字 /*第几包*/ buff[5] = (uint8_t)(packetNum); buff[6] = (uint8_t)(packetNum >> 8); buff[7] = (uint8_t)(packetNum >> 16); buff[8] = (uint8_t)(packetNum >> 24); for (i = 0; i < len; i++) buff[9 + i] = data[i]; crc = My_crc32((unsigned char *)buff, len + 9); buff[9 + len] = (uint8_t)crc; buff[9 + len + 1] = (uint8_t)(crc >> 8); buff[9 + len + 2] = (uint8_t)(crc >> 16); buff[9 + len + 3] = (uint8_t)(crc >> 24); ESP_LOGD(TAG, " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BinCurrentNo: %ld !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", packetNum); for (i = 0; i < 5; i++) { com_SendData(buff, len + 13); ESP_LOGI(TAG, " packetNum: %ld", packetNum); Event = xEventGroupWaitBits(xComEventGroup, COM_OTA_MSG_OK | COM_OTA_MSG_DONE | COM_OTA_MSG_RESEND, pdTRUE, pdFALSE, (100 / portTICK_PERIOD_MS)); if (Event & COM_OTA_MSG_OK) { ESP_LOGI(TAG, "COM_OTA_MSG_OK,OTAInfo BinCurrentByte: %ld", packetNum); return 1; } else if (Event & COM_OTA_MSG_RESEND) { ESP_LOGI(TAG, "COM_OTA_MSG_RESEND,OTAInfo resend: %d", i); return 0; } else if (Event & COM_OTA_MSG_DONE) { ESP_LOGI(TAG, "COM_OTA_MSG_DONE,OTAInfo resend: %d", i); ESP_LOGI(TAG, "OTA bin sent over BinCurrentByte: %ld", packetNum); return 1; } else { ESP_LOGI(TAG, "OTAflag=0,OTAInfo resend: %d", i); return 0; } } return 0; } void send_ota_Upgrade(void) { FILE *f = NULL; char comStatus = 0; float progress = 0.0f; char temp_Buffer[128] = {0}; uint32_t lessSize = 0; uint32_t packet_num = 0; uint32_t currentSendSize = 0; lessSize = ota_info.mattressBinSize % PACKET_SIZE; packet_num = ota_info.mattressBinSize / PACKET_SIZE; ESP_LOGI(TAG, "packet_num %ld\r\n", packet_num); ESP_LOGI(TAG, "lessSize %ld\r\n", lessSize); LastPacketLessSize = lessSize; ota_Fatfs_Init(); ESP_LOGI(TAG, "------------------------- Start -------------------------"); for (int i = 0; i < packet_num; i++) { memset(otaSendBuffer, 0, sizeof(otaSendBuffer)); ESP_LOGI(TAG, "------packet_num %ld\r\n", packet_num); ESP_LOGI(TAG, "------lessSize %ld\r\n", lessSize); // xTimerReset(upgradeTimeOut_timer, 0); // TODO:读取文件 f = fopen(FILE_PATH, "r"); if (f == NULL) { i = 0; continue; } ESP_LOGI(TAG, "Write pack : %d ", i); fseek(f, i * PACKET_SIZE, SEEK_SET); fread(otaSendBuffer, 1, PACKET_SIZE, f); // dump_hex((uint8_t *)otaSendBuffer, PACKET_SIZE); vTaskDelay(pdMS_TO_TICKS(250)); // comStatus = 1; comStatus = send_ota_bin(otaSendBuffer, PACKET_SIZE, i * PACKET_SIZE); fclose(f); if (comStatus != 1) { i--; continue; } currentSendSize = (i + 1) * PACKET_SIZE; progress = ((float)currentSendSize / (float)ota_info.mattressBinSize) * 100.0f; ESP_LOGI(TAG, "%.3f%%", progress); sprintf(temp_Buffer, "{\"type\":\"ALG\",\"ota_progress\":\"%.2f%%\"}", progress); if (((int)progress % 5) == 0) mqtt_UploadOTAProgress(temp_Buffer); } // TODO:读取文件 f = fopen(FILE_PATH, "r"); // 最后一包 fseek(f, packet_num * PACKET_SIZE, SEEK_SET); fread(otaSendBuffer, 1, lessSize, f); vTaskDelay(pdMS_TO_TICKS(500)); fclose(f); deviceUpgradeNum = packet_num; memcpy(LastPacketBuffer, otaSendBuffer, LastPacketLessSize); //--------------------------------------------------------------- 测试 // send_ota_bin(otaSendBuffer, PACKET_SIZE, packet_num * PACKET_SIZE); // for (int i = 0; i < 5; i++) // { // com_SendData("\xA5\x5A\x01\x00\xFF", 5); // STM32部分的复位指令 // vTaskDelay(pdMS_TO_TICKS(50)); // } //--------------------------------------------------------------- sprintf(temp_Buffer, "{\"type\":\"ALG\",\"ota_progress\":\"100%%\"}"); mqtt_UploadOTAProgress(temp_Buffer); ESP_LOGI(TAG, "------------------------- End -------------------------"); vTaskDelay(50); remove(FILE_PATH); // 升级完成 移除文件 ota_Fatfs_deinit(); }