#include "dev_update.h" #include "dev_manager.h" #include "update/update.h" #include "update/update_loader_download.h" #include "app_config.h" #include "avctp_user.h" #if defined(CONFIG_SD_UPDATE_ENABLE) || defined(CONFIG_USB_UPDATE_ENABLE) #define DEV_UPDATE_EN 1 #else #define DEV_UPDATE_EN 0 #endif #ifdef DEV_UPDATE_SUPPORT_JUMP extern void __JUMP_TO_MASKROM(); extern void save_spi_port(); extern void update_close_hw(void *filter_name); extern void ram_protect_close(void); #endif //endif DEV_UPDATE_SUPPORT_JUMP extern bool uart_update_send_update_ready(char *file_path); extern bool get_uart_update_sta(void); extern void storage_update_loader_download_init_with_file_hdl( int type, char *update_path, void *fd, void (*cb)(void *priv, int type, u8 cmd), void *cb_priv, u8 task_en ); static char update_path[48] = {0}; extern const char updata_file_name[]; struct __update_dev_reg { char *logo; int type; union { UPDATA_SD sd; } u; }; #if TCFG_SD0_ENABLE static const struct __update_dev_reg sd0_update = { .logo = "sd0", .type = SD0_UPDATA, .u.sd.control_type = SD_CONTROLLER_0, #if (TCFG_SD0_PORTS=='A') .u.sd.control_io = SD0_IO_A, #elif (TCFG_SD0_PORTS=='B') .u.sd.control_io = SD0_IO_B, #elif (TCFG_SD0_PORTS=='C') .u.sd.control_io = SD0_IO_C, #elif (TCFG_SD0_PORTS=='D') .u.sd.control_io = SD0_IO_D, #elif (TCFG_SD0_PORTS=='E') .u.sd.control_io = SD0_IO_E, #elif (TCFG_SD0_PORTS=='F') .u.sd.control_io = SD0_IO_F, #endif .u.sd.power = 1, }; #endif//TCFG_SD0_ENABLE #if TCFG_SD1_ENABLE static const struct __update_dev_reg sd1_update = { .logo = "sd1", .type = SD1_UPDATA, .u.sd.control_type = SD_CONTROLLER_1, #if (TCFG_SD1_PORTS=='A') .u.sd.control_io = SD1_IO_A, #else .u.sd.control_io = SD1_IO_B, #endif .u.sd.power = 1, }; #endif//TCFG_SD1_ENABLE #if TCFG_UDISK_ENABLE static const struct __update_dev_reg udisk_update = { .logo = "udisk0", .type = USB_UPDATA, }; #endif//TCFG_UDISK_ENABLE #if TCFG_NOR_FAT static const struct __update_dev_reg dev_flash_update = { .logo = "fat_nor", .type = DEV_NORFLASH_UFW_UPDATA, }; #endif static const struct __update_dev_reg *update_dev_list[] = { #if TCFG_UDISK_ENABLE &udisk_update, #endif//TCFG_UDISK_ENABLE #if TCFG_SD0_ENABLE &sd0_update, #endif// #if TCFG_SD1_ENABLE &sd1_update, #endif//TCFG_SD1_ENABLE #if TCFG_NOR_FAT &dev_flash_update, #endif }; static void dev_update_callback(void *priv, int type, u8 cmd) { struct __update_dev_reg *parm = (struct __update_dev_reg *)priv; if (cmd == UPDATE_LOADER_OK) { update_mode_api(type); } else { printf("update fail, cpu reset!!!\n"); cpu_reset(); } } static void *dev_update_get_parm(int type) { struct __update_dev_reg *parm = NULL; for (int i = 0; i < ARRAY_SIZE(update_dev_list); i++) { if (update_dev_list[i]->type == type) { parm = (struct __update_dev_reg *)update_dev_list[i]; } } if (parm == NULL) { return NULL; } return (void *)&parm->u.sd; } struct strg_update { void *fd; char *update_path; u32 offset_addr; u8 update_target; }; static struct strg_update strg_update = {0}; #define __this (&strg_update) static u16 strg_f_open(void) { if (!__this->update_path) { printf("file path err "); return false; } if (__this->fd) { return true; /* fclose(__this->fd); __this->fd = NULL; */ } __this->fd = fopen(__this->update_path, "r"); if (!__this->fd) { printf("file open err "); return false; } return true; } static u16 strg_f_read(void *fp, u8 *buff, u16 len) { if (!__this->fd) { return (u16) - 1; } len = fread(__this->fd, buff, len); return len; } static int strg_f_seek(void *fp, u8 type, u32 offset) { if (!__this->fd) { return (int) - 1; } offset += __this->offset_addr; int ret = fseek(__this->fd, offset, type); /* return 0; // 0k */ return ret; } static u16 strg_f_stop(u8 err) { if (__this->fd) { fclose(__this->fd); __this->fd = NULL; } return true; } static int strg_update_set_file_path_and_hdl(char *update_path, void *fd) { __this->update_path = update_path; __this->fd = fd; return true; } static const update_op_api_t strg_dev_update_op = { .f_open = strg_f_open, .f_read = strg_f_read, .f_seek = strg_f_seek, .f_stop = strg_f_stop, }; static void dev_update_set_offset_addr(u32 offset) { __this->offset_addr = offset; strg_f_seek(__this->fd, SEEK_SET, 0); //确定好偏移 } static void dev_update_param_private_handle(UPDATA_PARM *p) { u16 up_type = p->parm_type; #ifdef CONFIG_SD_UPDATE_ENABLE if ((up_type == SD0_UPDATA) || (up_type == SD1_UPDATA)) { int sd_start = (u32)p + sizeof(UPDATA_PARM); void *sd = NULL; sd = dev_update_get_parm(up_type); if (sd) { memcpy((void *)sd_start, sd, UPDATE_PRIV_PARAM_LEN); } else { memset((void *)sd_start, 0, UPDATE_PRIV_PARAM_LEN); } } #endif #ifdef CONFIG_USB_UPDATE_ENABLE if (up_type == USB_UPDATA) { printf("usb updata "); int usb_start = (u32)p + sizeof(UPDATA_PARM); memset((void *)usb_start, 0, UPDATE_PRIV_PARAM_LEN); } #endif #if TCFG_NOR_FAT if (up_type == DEV_NORFLASH_UFW_UPDATA) { printf("dev_flash updata "); int flash_start = (u32)p->parm_priv; memset((void *)flash_start, 0, UPDATE_PRIV_PARAM_LEN); } #endif memcpy(p->file_patch, updata_file_name, strlen(updata_file_name)); } static void dev_update_before_jump_handle(u16 up_type) { #ifdef DEV_UPDATE_SUPPORT_JUMP #if TCFG_BLUETOOTH_BACK_MODE //后台模式需要把蓝牙关掉 if (BT_MODULES_IS_SUPPORT(BT_MODULE_LE)) { ll_hci_destory(); } hci_controller_destory(); #endif update_close_hw("null"); ram_protect_close(); save_spi_port(); printf("update jump to mask...\n"); /* JL_UART0->CON0 = 0; */ /* JL_UART1->CON0 = 0; */ __JUMP_TO_MASKROM(); #else printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__); cpu_reset(); #endif //DEV_UPDATE_SUPPORT_JUMP } static void dev_update_state_cbk(int type, u32 state, void *priv) { update_ret_code_t *ret_code = (update_ret_code_t *)priv; switch (state) { case UPDATE_CH_EXIT: if ((0 == ret_code->stu) && (0 == ret_code->err_code)) { update_mode_api_v2(type, dev_update_param_private_handle, dev_update_before_jump_handle); } else { printf("update fail, cpu reset!!!\n"); cpu_reset(); } break; } } static mutil_ufw_info *update_choose_info(mutil_ufw_info *info, u32 cnt, char *name) { mutil_ufw_info *p = NULL; if (info) { for (int i = 0; i < cnt; i++) { printf(">>>[test]:i = %d, name = %s\n", i, info[i].name); if (strcmp(info[i].name, name) == 0) { p = &info[i]; break; } } } return p; } u16 dev_update_check(char *logo) { if (update_success_boot_check() == true) { return UPDATA_NON; } __this->offset_addr = 0; __this->update_target = 0; struct __dev *dev = dev_manager_find_spec(logo, 0); if (dev) { #if DEV_UPDATE_EN //<查找设备升级配置 struct __update_dev_reg *parm = NULL; for (int i = 0; i < ARRAY_SIZE(update_dev_list); i++) { if (0 == strcmp(update_dev_list[i]->logo, logo)) { parm = (struct __update_dev_reg *)update_dev_list[i]; } } if (parm == NULL) { printf("dev update without parm err!!!\n"); return UPDATA_PARM_ERR; } //<尝试按照路径打开升级文件 char *updata_file = (char *)updata_file_name; if (*updata_file == '/') { updata_file ++; } memset(update_path, 0, sizeof(update_path)); sprintf(update_path, "%s%s", dev_manager_get_root_path(dev), updata_file); printf("update_path: %s\n", update_path); FILE *fd = fopen(update_path, "r"); if (!fd) { ///没有升级文件, 继续跑其他解码相关的流程 printf("open update file err!!!\n"); return UPDATA_DEV_ERR; } strg_update_set_file_path_and_hdl(update_path, (void *)fd); #if MUTIL_CPU_UART_UPDATE_ENABLE mutil_ufw_info *ufw_info = NULL; int cnt = update_target_check(&strg_dev_update_op, (void *)ufw_info); if (cnt > 0) { //多芯片升级ufw结构 ufw_info = (mutil_ufw_info *)malloc(cnt * sizeof(mutil_ufw_info)); ASSERT(ufw_info); printf(">>>[test]:check ufw second\n"); cnt = update_target_check(&strg_dev_update_op, (void *)ufw_info); } else { __this->update_target = 0x1; //原始的单ufw结构 } mutil_ufw_info *p = update_choose_info(ufw_info, cnt, "ad100_fw.ufw"); if (p) { printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__); dev_update_set_offset_addr(p->ufw_addr); if (uart_update_init_uart_type()) { return UPDATA_PARM_ERR; } uart_update_send_data(&strg_dev_update_op, (void *)p); /* while(1); */ } p = NULL; p = update_choose_info(ufw_info, cnt, "update.ufw"); if (__this->update_target == 1 || p) { printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__); /* while(1); */ if (p) { dev_update_set_offset_addr(p->ufw_addr); } else { dev_update_set_offset_addr(0); } ///进行升级 update_mode_info_t info = { .type = parm->type, .state_cbk = dev_update_state_cbk, .p_op_api = &strg_dev_update_op, .task_en = 0, }; #if (LED_LYRICS_ENABLE && TCFG_LRC_LYRICS_ENABLE) user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL); #endif app_active_update_task_init(&info); } if (ufw_info) { free(ufw_info); ufw_info = NULL; } #else #if(TCFG_UPDATE_UART_IO_EN) && (TCFG_UPDATE_UART_ROLE) uart_update_send_update_ready(update_path); while (get_uart_update_sta()) { os_time_dly(10); } #else //进行升级 update_mode_info_t info = { .type = parm->type, .state_cbk = dev_update_state_cbk, .p_op_api = &strg_dev_update_op, .task_en = 0, }; app_active_update_task_init(&info); #endif #endif #endif//DEV_UPDATE_EN } return UPDATA_READY; }