* @file httpsOTA.c
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2026-10-23
*
* @copyright Copyright (c) 2026
*
*/
#include "httpsOTA.h"
#define TAG "Ota"
static TaskHandle_t OtaTaskHandle = NULL;
static void 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 已开始");
break;
case ESP_HTTPS_OTA_CONNECTED:
ESP_LOGI(TAG, "已连接到服务器");
break;
case ESP_HTTPS_OTA_GET_IMG_DESC:
ESP_LOGI(TAG, "阅读图像描述");
break;
case ESP_HTTPS_OTA_VERIFY_CHIP_ID:
ESP_LOGI(TAG, "验证新镜像的芯片 ID: %d", *(esp_chip_id_t *)event_data);
break;
case ESP_HTTPS_OTA_VERIFY_CHIP_REVISION:
ESP_LOGI(TAG, "正在验证新镜像的芯片版本: %d", *(uint16_t *)event_data);
break;
case ESP_HTTPS_OTA_DECRYPT_CB:
ESP_LOGI(TAG, "解密函数的回调");
break;
case ESP_HTTPS_OTA_WRITE_FLASH:
ESP_LOGD(TAG, "写入闪存: %d written", *(int *)event_data);
break;
case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION:
ESP_LOGI(TAG, "引导分区已更新。下一个分区: %d", *(esp_partition_subtype_t *)event_data);
break;
case ESP_HTTPS_OTA_FINISH:
ESP_LOGI(TAG, "OTA 完成");
break;
case ESP_HTTPS_OTA_ABORT:
ESP_LOGI(TAG, "OTA终止");
break;
}
}
}
static char *OtaUrl = NULL;
static int OtaProgress = -1;
static void OtaTask(void *arg){
OtaCallback OtaCallbackFn = (OtaCallback)arg;
ESP_LOGI(TAG,"OtaUrl= %s",OtaUrl);
esp_event_handler_register(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL);
esp_http_client_config_t httpCfg = {
.url = OtaUrl,
.crt_bundle_attach = esp_crt_bundle_attach,
};
esp_https_ota_config_t otaCfg = {
.http_config = &httpCfg,
};
esp_https_ota_handle_t httpsOtaHandle;
if(esp_https_ota_begin(&otaCfg,&httpsOtaHandle) == ESP_OK){
if(httpsOtaHandle != NULL){
int otaImageSize = esp_https_ota_get_image_size(httpsOtaHandle);
ESP_LOGI(TAG,"要下载的OTA镜像有 %d bytes",otaImageSize);
while(esp_https_ota_perform(httpsOtaHandle) == ESP_ERR_HTTPS_OTA_IN_PROGRESS){
int otaGetImageSize = esp_https_ota_get_image_len_read(httpsOtaHandle);
OtaProgress = (int)((float)otaGetImageSize/(float)otaImageSize*100);
OtaCallbackFn(otaImageSize,otaGetImageSize,OtaProgress);
}
if(esp_https_ota_is_complete_data_received(httpsOtaHandle) == true){
OtaCallbackFn(otaImageSize,otaImageSize,100);
esp_https_ota_finish(httpsOtaHandle);
esp_restart();
}else{
OtaCallbackFn(otaImageSize,otaImageSize,-1);
esp_https_ota_abort(httpsOtaHandle);
}
}
}else{
OtaCallbackFn(0,0,-1);
}
OtaProgress = -1;
free(OtaUrl);
esp_event_handler_unregister(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &event_handler);
ESP_LOGE(TAG,"OTA 升级任务结束");
OtaTaskHandle = NULL;
vTaskDelete(OtaTaskHandle);
}
* @brief 启动 https OTA 升级任务
*
* @param Url
*/
void OtaStart(char *Url,OtaCallback OtaCallbackFn){
if(OtaTaskHandle == NULL){
OtaUrl = (char *)malloc(strlen(Url)+1);
if(OtaUrl != NULL){
memset(OtaUrl,0,strlen(Url)+1);
strcpy(OtaUrl,Url);
xTaskCreate(OtaTask,"OtaTask",4096,OtaCallbackFn,0,&OtaTaskHandle);
}
}
}
int GetOtaProgress(){
return OtaProgress;
}