Job_SignsPads/ESP32/software/main/src/bsp_upgrade.c
2025-04-22 10:29:37 +08:00

840 lines
27 KiB
C

/*
* @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();
}