KT26-0607_AC695n-BTE-SDK312/apps/common/dev_manager/dev_update.c
2026-06-07 19:38:16 +08:00

437 lines
11 KiB
C

#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;
}