CH592接wifi模块,通过串口ota,升级参考OTA例程BackupUpgrade_OTA,IAP擦写校验新固件成功后,卡在jumpApp()这里,无法正常启动app。
1、编译生成的固件包app.bin,通过BackupUpgrade_OTA例程可以正常升级启动,固件包应该没有问题。
2、串口数据接收后,通过了MD5校验,没有丢帧,FLASH_ROM_VERIFY也正常通过。
3、四个分区地址也跟demo保持一致。
请教下app启动异常的原因可能有哪些,怎么排查。
CH592接wifi模块,通过串口ota,升级参考OTA例程BackupUpgrade_OTA,IAP擦写校验新固件成功后,卡在jumpApp()这里,无法正常启动app。
1、编译生成的固件包app.bin,通过BackupUpgrade_OTA例程可以正常升级启动,固件包应该没有问题。
2、串口数据接收后,通过了MD5校验,没有丢帧,FLASH_ROM_VERIFY也正常通过。
3、四个分区地址也跟demo保持一致。
请教下app启动异常的原因可能有哪些,怎么排查。
app的地址分配
“卡在jumpApp()这里,无法正常启动app”
执行jumpAPP()后会怎样,会复位吗,还是串口打印日志不再继续运行了?
IAP层代码是基于哪个工程修改的,如果是基于UART1历程修改的,注意.s文件中要配置更高的权限(.s文件倒数几行,有一处原0x88,需要改为0x1888);如果是基于BLEOTA的IAP层代码修改的,那此处默认配置好了。
执行jumpAPP()后一直复位,IAP层代码是基于BLEOTA的IAP层代码修改的,默认配置。
这是我擦写imageB 分区的代码,是否有问题呢。麻烦大佬帮忙看下
void earse_imageB() { OpAdd = 0; uint32_t op; while(1) { op = FLASH_ROM_ERASE(IMAGE_B_START_ADD + OpAdd, FLASH_BLOCK_SIZE); if(op) { App_Printf("Ota E fail %08x\n", IMAGE_B_START_ADD + OpAdd); continue; } OpAdd += FLASH_BLOCK_SIZE; if(OpAdd >= IMAGE_B_SIZE) { App_Printf("Ota E succ\n"); OpAdd = 0; break; } } } void OTA_write_imageB(unsigned char *data ,UINT32 datalen) { uint32_t op = 0; UINT32 write_len=datalen; UINT32 data_offset=0; UINT8 OTA_DATA[1025]={0}; memcpy(OTA_DATA,data,write_len); while(write_len) { if(write_len>128) { op = FLASH_ROM_WRITE(IMAGE_B_START_ADD + OpAdd,OTA_DATA+data_offset, 128); op |= FLASH_ROM_VERIFY(IMAGE_B_START_ADD + OpAdd,OTA_DATA+data_offset, 128); if(!op) { App_Printf("Ota W success %08x ,OpAdd=%d ,data_offset=%d\n", IMAGE_B_START_ADD + OpAdd, OpAdd,data_offset); OpAdd += 128; } else { App_Printf("Ota W fail %08x %d\n", IMAGE_B_START_ADD + OpAdd, OpAdd); } } else { op = FLASH_ROM_WRITE(IMAGE_B_START_ADD + OpAdd,OTA_DATA+data_offset, write_len); op |= FLASH_ROM_VERIFY(IMAGE_B_START_ADD + OpAdd,OTA_DATA+data_offset, write_len); if(!op) { App_Printf("Ota W success %08x ,OpAdd=%d ,data_offset=%d\n", IMAGE_B_START_ADD + OpAdd, OpAdd,data_offset); OpAdd += write_len; if(OpAdd == OTA_total_len) { App_Printf("Ota to B complete \n"); if(MD5_check_ok == 1) { App_Printf("Ota start...\n"); SYS_DisableAllIrq(NULL); SwitchImageFlag(IMAGE_IAP_FLAG); while(1) SYS_ResetExecute(); } else { App_Printf("Ota Cksum fail\n"); } } } else { App_Printf("Ota W fail %08x %d\n", IMAGE_B_START_ADD + OpAdd, OpAdd); } write_len=-1; break; } write_len=write_len-128; data_offset=data_offset+128; } }
UART接收新固件的代码,基于BLE的OTA方案中的IAP例程修改,那么.s和.ld文件可以不改。
有没有在IAP中添加串口中断?
如果添加了中断功能(无论添加了何种中断都要处理,以最可能用到的串口中断为例),在跳转到APP层代码前,要将串口中断关闭,否则在APP层代码中一旦启用同一个串口中断,但找不到中断服务函数入口,会导致MCU不断复位。
IAP使用的就是demo的代码,没有做修改,也没有添加中断。
IAP代码完全没有改动,“四个分区地址也跟demo保持一致”,那IAP层代码应该没问题。“通过BackupUpgrade_OTA例程可以正常升级启动”那APP层代码本身是可以工作。可能在固件转发环节中出了问题。
“编译生成的固件包app.bin”
升级使用的APP层代码的bin文件,①是MRS编译器直接生成的,②还是使用hex转bin工具转换而来的?
①方式中,bin文件从头开始即存放APP层代码。
②方式中,bin文件可能会填充前4K内容,从4K开始存放APP层代码。
OTA升级方案中,手机APP会截掉bin文件的前4K内容再下发给MCU,要用②方式中填充头部内容的bin文件来做升级。
①②方式下生成的bin文件可以都拿来升级试试看,或者看看WIFI模块收到的bin,是不是从APP层代码的起始位置开始下发的。
MRS编译器直接生成bin文件的方式:MRS CH573 CH582生成BIN文件 - debugdabiaoge - 博客园
若仍有异常,可以邮件联系沟通更多细节 zhaiyw@wch.cn
确实是hex转bin的时候,填充了前4K的内容,截掉这4K可以正常升级了,感谢大佬的支持。