#include #include /** * @Author: 李建 * @Date: 2025/3/26 14:21 * Description: OTA功能实现 * Copyright: Copyright (©) 2025 永续绿建. All rights reserved. */ #include #include #include #include #include #include "ota.h" #include "stdint.h" #include "sub_device/command.h" #include "system/miscellaneous_interface.h" #include "display/lv_display.h" #include "lvgl_port.h" #include "main.h" #include "xf_controller.h" #include "lcd_st7701.h" extern const uint8_t server_cert_pem_start[] asm("_binary_ssl_pem_start"); extern const uint8_t server_cert_pem_end[] asm("_binary_ssl_pem_end"); static const char *TAG = "ota"; uint32_t downloaded_size = 0; static ota_info_t ota_info; uint32_t old_progress = 0; uint32_t progress = 0; static bool isUpdating = false; static esp_err_t http_event_handler(esp_http_client_event_t *evt) { switch (evt->event_id) { case HTTP_EVENT_ERROR: ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); lvgl_port_lock(-1); lv_obj_remove_flag(guider_ui.OTAPage_btn_exit, LV_OBJ_FLAG_HIDDEN); lvgl_port_unlock(); break; case HTTP_EVENT_ON_CONNECTED: ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED"); break; case HTTP_EVENT_HEADER_SENT: ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); break; case HTTP_EVENT_ON_HEADER: ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); break; case HTTP_EVENT_ON_DATA: downloaded_size += evt->data_len; progress = (downloaded_size * 100) / ota_info.fileSize; if(progress != old_progress) { ESP_LOGI(TAG, "progress=%lu%%", progress); old_progress = progress; } break; case HTTP_EVENT_ON_FINISH: ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH"); break; case HTTP_EVENT_DISCONNECTED: ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED"); break; case HTTP_EVENT_REDIRECT: ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT"); break; } return ESP_OK; } _Noreturn void ota_task(void *pv) { ESP_LOGI(TAG, "Starting OTA example task, %ld,%ld",esp_get_free_internal_heap_size(), esp_get_minimum_free_heap_size()); esp_http_client_config_t config = { .url = ota_info.url, .cert_pem = (char *) server_cert_pem_start, .event_handler = http_event_handler, .keep_alive_enable = true, }; #ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK config.skip_cert_common_name_check = true; #endif esp_https_ota_config_t ota_config = { .http_config = &config, }; ESP_LOGI(TAG, "Attempting to download update from %s", config.url); esp_err_t ret = esp_https_ota(&ota_config); if (ret == ESP_OK) { ESP_LOGI(TAG, "OTA Succeed, Rebooting..."); // vTaskDelay( pdTICKS_TO_MS(3000)); esp_restart(); } else { ESP_LOGE(TAG, "Firmware upgrade failed"); lvgl_port_lock(-1); lv_obj_remove_flag(guider_ui.OTAPage_btn_exit, LV_OBJ_FLAG_HIDDEN); lvgl_port_unlock(); } while (1) { vTaskDelay(1000 / portTICK_PERIOD_MS); } } _Noreturn static void progress_task(void * pv) { while (1) { lvgl_port_lock(-1); lv_bar_set_value(guider_ui.OTAPage_bar_ota_progress, (int32_t) progress, false); lvgl_port_unlock(); vTaskDelay(100 / portTICK_PERIOD_MS); } } static void start_ota() { lcd_st7701_backlight_on(); ui_load_scr_animation(&guider_ui, &guider_ui.OTAPage, guider_ui.OTAPage_del, &guider_ui.screen_main_del, setup_scr_OTAPage, LV_SCR_LOAD_ANIM_MOVE_LEFT, 200, 0, false, false); lv_label_set_text(guider_ui.OTAPage_lab_ota_remote_version, ota_info.version); esp_app_desc_t * desc = esp_app_get_description(); lv_label_set_text(guider_ui.OTAPage_lab_ota_current_version, desc->version); if(xTaskCreate(&ota_task, "ota_task", 8192, NULL, 5, NULL)!=pdTRUE) { ESP_LOGE(TAG, "create ota_task failed"); lvgl_port_lock(-1); lv_obj_remove_flag(guider_ui.OTAPage_btn_exit, LV_OBJ_FLAG_HIDDEN); lvgl_port_unlock(); } xTaskCreate(&progress_task, "update_task", 1024 * 2, NULL, 5, NULL); } /** * 设备OTA升级 * @param params */ void on_dev_upgrade(char *params) { if(isUpdating)return; cJSON *root = cJSON_Parse(params); cJSON *file_size = cJSON_GetObjectItemCaseSensitive(root, "file_size"); cJSON *url = cJSON_GetObjectItemCaseSensitive(root, "url"); cJSON *version = cJSON_GetObjectItemCaseSensitive(root, "version"); ota_info.fileSize = file_size->valueint; snprintf(ota_info.url, sizeof(ota_info.url), "%s", url->valuestring); snprintf(ota_info.version, sizeof(ota_info.version), "%s", version->valuestring); stop_xf_controller(); start_ota(); cJSON_Delete(root); ESP_LOGI(TAG, "OTA info: fileSize=%lu, url=%s, version=%s", ota_info.fileSize, ota_info.url, ota_info.version); isUpdating = true; } // 初始化平台OTA功能指令 void ota_init() { sparrow_command ota_cmd = { .name = "devUpgrade", .unpack = &on_dev_upgrade, }; register_sparrow_command(ota_cmd); }