#include "board_config.h" #include "system/includes.h" #include "asm/power_interface.h" #include "app_config.h" #include "dual_bank_updata_api.h" #include "update.h" #include "update_loader_download.h" #include "app_main.h" #include "event.h" #undef _DEBUG_H_ #define LOG_TAG_CONST DUAL_OTA //修改成文件名 #define LOG_TAG "[DUAL_OTA]" #include "debug.h" #define LOG_v(t) log_tag_const_v_ ## t #define LOG_i(t) log_tag_const_i_ ## t #define LOG_d(t) log_tag_const_d_ ## t #define LOG_w(t) log_tag_const_w_ ## t #define LOG_e(t) log_tag_const_e_ ## t #define LOG_c(t) log_tag_const_c_ ## t #define LOG_tag(tag, n) n(tag) const char LOG_tag(LOG_TAG_CONST,LOG_v) AT(.LOG_TAG_CONST) = 0; const char LOG_tag(LOG_TAG_CONST,LOG_i) AT(.LOG_TAG_CONST) = 1; const char LOG_tag(LOG_TAG_CONST,LOG_d) AT(.LOG_TAG_CONST) = 1; //log_debug const char LOG_tag(LOG_TAG_CONST,LOG_w) AT(.LOG_TAG_CONST) = 1; const char LOG_tag(LOG_TAG_CONST,LOG_e) AT(.LOG_TAG_CONST) = 1; const char LOG_tag(LOG_TAG_CONST,LOG_c) AT(.LOG_TAG_CONST) = 1; /******************************************************************************* * #define CONFIG_DOUBLE_BANK_ENABLE 1 * #define CONFIG_FLASH_SIZE FLASH_SIZE_512K //配置FLASH大小 * #define CONFIG_DB_UPDATE_DATA_GENERATE_EN 1 * #define CONFIG_ONLY_GRENERATE_ALIGN_4K_CODE 1 * * 检查isd_config.ini文件 * BR22_TWS_DB = YES; // dual bank flash framework enable * FLASH_SIZE = 0x100000; // flash_size cfg * BR22_TWS_VERSION = 0; // default fw version * DB_UPDATE_DATA = YES; // generate db_update_data.bin * FORCE_4K_ALIGN = YES; // force aligin with 4k bytes * SPECIAL_OPT = 0; // only generate one flash.bin * * const int support_dual_bank_update_en = 1; * const int support_vm_data_keep = 1; *******************************************************************************/ #define MAX_PACKET_LEN 4096//(512 * 8)//(512 * 4) //最大包长,至少512,最好4K,需要自行组包 //0:CRC-16/XMODEM Standard 杰理默认的 //1:客户自行选择crc16的算法类型,重定义 dual_ota_crc_calc() #define CRC_TYPE 1 __attribute__((weak)) u16 dual_ota_crc_calc(u8 *buf, u32 len, u16 init) { log_debug("%s weak func", __func__); //CRC16-XMODEM u16 poly = 0x1021; u16 crc = init; while(len--){ u16 data = *buf++; crc ^= data << 8; //逆序 for (u8 i = 0; i < 8; ++i){ crc = crc & 0x8000 ? (crc << 1) ^ poly : crc << 1; //逆序 } } return crc; } enum{ DUAL_OTA_NOTIFY_SUCCESS = 0, DUAL_OTA_NOTIFY_FAIL, DUAL_OTA_NOTIFY_CONTINUE, }; typedef enum{ DUAL_OTA_STEP_START = 0, DUAL_OTA_STEP_WRITE, DUAL_OTA_STEP_VERIFY, }DUAL_OTA_STEP; typedef struct { u32 file_size; // db_update_data.bin u32 file_crc; // CRC_TYPE 的对应值 u32 max_pkt_len; // MAX_PACKET_LEN }dual_ota_info; static dual_ota_info ota_info; static u8 *bin_buf=NULL;//[MAX_PACKET_LEN]; static DUAL_OTA_STEP dual_ota_step = DUAL_OTA_STEP_START; static int dual_ota_written_size = 0; static u8 dual_ota_idle = 1; // 置 1 可进睡眠, 置 0 不可进睡眠 u8 usr_get_ota_status() { return dual_ota_idle; } static u8 dual_ota_idle_query(void) { if(dual_ota_idle){ return 1; }else{ return 0; } } REGISTER_LP_TARGET(dual_ota_lp_target) = { .name = "dual_ota_lp", .is_idle = dual_ota_idle_query, }; static u32 read_32(u8 *p) { return ((u32)(p[3]) << 24) | ((u32)(p[2]) << 16) | ((u32)(p[1]) << 8) | (p[0]); } extern void ram_protect_close(void); extern void hwi_all_close(void); static void dual_ota_fail_exit(void) { log_info("%s[step:%d]", __func__, dual_ota_step); if(bin_buf){ free(bin_buf); bin_buf = NULL; } memset(&ota_info, 0x00, sizeof(ota_info)); dual_ota_step = DUAL_OTA_STEP_START; dual_ota_written_size = 0; dual_ota_idle = 0; } static void dual_ota_succ_exit(void) { log_info("%s[step:%d]", __func__, dual_ota_step); if(bin_buf){ free(bin_buf); bin_buf = NULL; } memset(&ota_info, 0x00, sizeof(ota_info)); dual_ota_step = DUAL_OTA_STEP_START; dual_ota_written_size = 0; dual_ota_idle = 0; } enum { OTA_START_UPDATE = 0, OTA_START_UPDATE_READY, OTA_START_VERIFY, OTA_UPDATE_OVER, OTA_UPDATE_ERR, OTA_UPDATE_SUCC, }; #include "update_tws_new.h" void usr_ota_event_post(u32 type, u8 event); static void dual_ota_cpu_reset(void) { log_info("%s", __func__); dual_ota_succ_exit(); usr_var.usr_ota_succ_flag=2; //os_task_del("dw_update"); //update_result_set(UPDATA_SUCC); //dual_bank_passive_update_exit(NULL); //ram_protect_close(); //hwi_all_close(); //cpu_reset(); //sys_enter_soft_poweroff(NULL); //wdt_init(WDT_256MS); //while(1); usr_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_OVER); } static void dual_ota_fail_cpu_reset(void) { log_info("%s", __func__); dual_ota_fail_exit(); usr_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR); } void usr_ota_exit() { sys_timeout_add(NULL, dual_ota_fail_cpu_reset, 300); } extern void ble_multi_trans_disconnect(void); static void dual_ota_success_reset(void) { log_info("%s", __func__); usr_var.usr_ota_succ_flag=1; ble_multi_trans_disconnect(); sys_timeout_add(NULL, dual_ota_cpu_reset, 300); /* 通知上位机升级完整,准备复位 */ //dual_ota_notify_msg_to_app(DUAL_OTA_NOTIFY_SUCCESS); } static void dual_ota_fail_reset(void) { log_info("%s", __func__); usr_var.usr_ota_succ_flag=3; ble_multi_trans_disconnect(); dual_ota_fail_exit(); //sys_timeout_add(NULL, dual_ota_fail_cpu_reset, 300); wdt_init(WDT_512MS); while(1); /* 通知上位机升级完整,准备复位 */ //dual_ota_notify_msg_to_app(DUAL_OTA_NOTIFY_SUCCESS); } static int dual_ota_boot_info_cb(int err) { log_info("%s[err:%d]", __func__, err); if (err == 0) { dual_ota_success_reset(); } else { dual_ota_fail_reset(); } return 0; } extern int dual_bank_update_verify_without_crc(void); //0:success 1:fail static int dual_ota_verify_result(int res) //1:success 0:fail { log_info("%s[res:%d %s]", __func__, res, res ? "success" : "fail"); if(res){ /* 校验成功 */ dual_bank_update_burn_boot_info(dual_ota_boot_info_cb); } else{ /* 校验失败 */ usr_var.usr_ota_succ_flag=1; flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK); dual_ota_fail_reset(); } return 0; } static void dual_ota_crc_init_cb(void) { log_info("%s", __func__); } static u32 dual_ota_crc_calc_cb(u32 init_crc, u8 *data, u32 len) { u32 crc16 = 0; crc16 = dual_ota_crc_calc(data, len, init_crc); log_debug("%s[init_crc:0x%x len:%d crc:0x%x]", __func__, init_crc, len, crc16); return crc16; } static int dual_ota_update_verify(void) { log_info("%s[file_crc:0x%x]", __func__, ota_info.file_crc); clk_set("sys", 120 * 1000000L); os_time_dly(1); if(ota_info.file_crc){ if(CRC_TYPE){ dual_bank_update_verify(dual_ota_crc_init_cb, dual_ota_crc_calc_cb, dual_ota_verify_result); }else{ dual_bank_update_verify(NULL, NULL, dual_ota_verify_result); } }else{ int ret = dual_bank_update_verify_without_crc(); dual_ota_verify_result(ret ? 0 : 1); } return 0; } static int dual_ota_write_cb(void *priv) { int ret = (int)priv; if (ret) { log_info("%s -> fail", __func__); dual_ota_fail_reset(); return -1; }else{ //log_info("%s -> success", __func__); /* 通知上位机发送下一组数据 */ dual_ota_notify_msg_to_app(DUAL_OTA_NOTIFY_CONTINUE); return 0; } } static int dual_ota_update_init(u32 file_size, u32 file_crc, u32 pkt_len) { log_info("%s[size:%d crc:0x%x ptk_len:%d]",__func__,file_size, file_crc, pkt_len); if(bin_buf) return -1; bin_buf = malloc(MAX_PACKET_LEN); if(bin_buf == NULL) return -2; if((u32)bin_buf % 4) {//4byte对齐 log_info("buf err !!!!!!!"); ASSERT(0, "%s: bin_buf addr unaligned !!!!", __func__); } memset(bin_buf, 0x00, MAX_PACKET_LEN); int ret = 0; log_info("0000000000000000"); ret = dual_bank_passive_update_init(file_crc, file_size, pkt_len, NULL); log_info("1111111111111111"); if(ret == 0){ ret = dual_bank_update_allow_check(file_size); log_info("222222222222"); if(ret == 0){ dual_ota_idle = 0; dual_ota_written_size = 0; ota_info.file_size = file_size; ota_info.file_crc = file_crc; ota_info.max_pkt_len = pkt_len; /* 可以升级,需要通知上位机准备发包 */ dual_ota_notify_msg_to_app(DUAL_OTA_NOTIFY_CONTINUE); } } log_info("%s[ret:%d]", __func__, ret); if(ret){ dual_ota_fail_reset(); //dual_ota_fail_exit(); /* 无法升级 */ return -3; } return ret; } static int dual_ota_update_deal(u8 step, u8 *buf, u32 len) //升级流程处理 { int ret = 0; int w_ret = 0xffff; //log_info("%s[step:%d]", __func__, step); switch(step){ case DUAL_OTA_STEP_START: u32 *data = (u32 *)buf; //buf 地址需要aligned(4) u32 file_size = data[0]; u32 file_crc = data[1]; /* update_mode_info_t info = { .type = BLE_APP_UPDATA, .state_cbk = NULL, .p_op_api = NULL, .task_en = 1, };*/ //app_active_update_task_init(&info); //os_time_dly(2); ret = dual_ota_update_init(file_size, file_crc, MAX_PACKET_LEN); break; case DUAL_OTA_STEP_WRITE: //OS_ENTER_CRITICAL(); w_ret=dual_bank_update_write(buf, len, dual_ota_write_cb); dual_ota_written_size += len; //printf("w_ret = %d written_size=%d\n",w_ret,dual_ota_written_size); //OS_EXIT_CRITICAL(); break; case DUAL_OTA_STEP_VERIFY: dual_ota_update_verify(); break; } return ret; } /******************************************************************************** * 跟上位机通信接口 * 自行按照协议,自行修改,这个写法只是个demo * 数据来源:串口、USB、BLE等 * 数据包很小,需要缓存成一包大包:MAX_PACKET_LEN,才能调用dual_bank_update_write * MAX_PACKET_LEN 定义成 小包的整数倍 : MAX_PACKET_LEN == len * n * 必须在低优先级任务执行,不能在中断函数、蓝牙回调函数执行 * https://gitee.com/Jieli-Tech/fw-AC63_BT_SDK/issues/I79ORW *********************************************************************************/ int dual_ota_app_data_deal(u32 msg, u8 *buf, u32 len) { if((buf == NULL) || (len == 0)){ log_info("%s para is error", __func__); return -1; } //log_info("%s[msg:%d len:%d]", __func__, msg, len); /* log_debug_hexdump(buf, len); */ int ret = 0; static u32 size = 0; if(dual_ota_step == DUAL_OTA_STEP_WRITE){ //log_info("##### size = %d len = %d ota_info.max_pkt_len = %d\n",size,len,ota_info.max_pkt_len); if((size < ota_info.max_pkt_len) && (size + len <= ota_info.max_pkt_len)){ memcpy(bin_buf + size, buf, len); size += len; }else{ log_info("%s size + len over MAX_PACKET_LEN", __func__); } if((size == ota_info.max_pkt_len) ||(size + dual_ota_written_size >= ota_info.file_size)) { if(size + dual_ota_written_size >= ota_info.file_size){ dual_ota_step = DUAL_OTA_STEP_VERIFY; } dual_ota_update_deal(DUAL_OTA_STEP_WRITE, bin_buf, size); size = 0; } }else{ log_info("444444444444444"); if((buf[0] == 0x55) && (buf[1] == 0xAA)){ u32 data[2]; data[0] = read_32(buf + 2); //file_size data[1] = read_32(buf + 6); //file_crc flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK); ret = dual_ota_update_deal(DUAL_OTA_STEP_START, (u8 *)data, sizeof(data)); if(ret == 0){ log_info("555555555555"); dual_ota_step = DUAL_OTA_STEP_WRITE; } } if((buf[0] == 0xAA) && (buf[1] == 0x55)){ dual_ota_update_deal(DUAL_OTA_STEP_VERIFY, NULL, 0); } } return ret; } extern int uart_tr_send_data(u8 *data, u32 len); /* int dual_ota_notify_msg_to_app(u32 msg, u8 *buf, u32 len) */ int dual_ota_notify_msg_to_app(u32 msg) { int ret = 0; char * str = NULL; //log_info("%s[msg:%d]", __func__, msg); switch(msg) { case DUAL_OTA_NOTIFY_SUCCESS: //成功 str = "success\r\n"; log_info("#########3 DUAL_OTA_NOTIFY_SUCCESS"); break; case DUAL_OTA_NOTIFY_FAIL: //失败 str = "fail\r\n"; log_info("#########3 DUAL_OTA_NOTIFY_FAIL"); break; case DUAL_OTA_NOTIFY_CONTINUE: //上一组数据处理成功,继续下一组 str = "continue\r\n"; // log_info("#########3 DUAL_OTA_NOTIFY_CONTINUE"); break; } // uart_tr_send_data((u8 *)str, strlen(str)); return ret; } int bt_ota_event_handler(struct bt_event *bt) { int ret = 0; switch (bt->event) { case OTA_START_UPDATE: log_info("OTA_START_UPDATE\n"); break; case OTA_UPDATE_OVER: log_info("11OTA_UPDATE_OVER@##################3\n"); // update_result_set(UPDATA_SUCC); // //os_time_dly(5); dual_bank_passive_update_exit(NULL); cpu_reset(); break; case OTA_UPDATE_ERR: log_info("111OTA_UPDATE_ERR@##################3\n"); dual_bank_passive_update_exit(NULL); cpu_reset(); break; /*case OTA_UPDATE_SUCC: printf("OTA_UPDATE_SUCC\n"); update_result_set(UPDATA_SUCC); dual_bank_passive_update_exit(NULL); sys_enter_soft_poweroff((void *)1); break;*/ default: break; } return 0; } void usr_ota_event_post(u32 type, u8 event) { struct sys_event e; log_info("usr_ota_event_post = %d\n",event); e.type = SYS_BT_EVENT; e.arg = (void *)type; e.u.bt.event = event; sys_event_notify(&e); }