本帖最后由 iibull 于 2019-12-16 14:09 编辑
现象:
1. M453, 使用 APROM + IAP方式. flash 布局共三块分区. 为 bootloader / APP / Backup .
系统开机加载bootloader, 然后bootloader 在引导App.
App 为主应用区, 可以通过USB实现在线升级, 升级时吧固件内容烧写在Backup 区, 烧写完毕后, 软复位到 bootloader
bootloader程序检测到backup的内容有效, 则把backup的内容复制到 App区, 然后再加载App内容.
/* Bootloader的代码 */
SYS_UnlockReg();
SYS_Init();
/* Enable FMC ISP function */
FMC_Open();
set_iap_aprom_boot();
FMC_ENABLE_AP_UPDATE();
fw_update_info_t info = {0};
info.fw_addr = FMC_Read(NDADDR_FACTORY);
info.page_cnt = FMC_Read(NDADDR_FACTORY + 4);
if ((info.fw_addr == NDADDR_BAK) && (info.page_cnt > 0x0ul))
{
update_fw_config_area(); /<font color="#ff0000">/把backup的内容复制到 App区</font>
update_fw_data(info.page_cnt); <font color="#ff0000">//更新配置区</font>
}
/* Mask all interrupt before changing VECMAP to avoid wrong interrupt handler fetched */
__set_PRIMASK(1);
/* Change VECMAP for booting to APROM */
FMC_SetVectorPageAddr(NDADDR_APP); <font color="#ff0000">//引导App区 OK</font>
/* Lock protected Register */
SYS_LockReg();
/* Software reset to boot to APROM */
NVIC_SystemReset();
while (1);
App区代码.
============================
开机部分
USBD_Open(&gsInfo, VCOM_ClassRequest, NULL); <font color="#ff0000">//内部实现 包括 SE0 置 1, 即 D+-断电操作</font>
/* Endpoint configuration */
VCOM_Init();
USBD_Start(); <font color="#ff0000">//内部实现有 先延迟 100ms, 然后 SE0 清零, 即 要求 host 端 重新枚举的动作</font>
NVIC_EnableIRQ(USBD_IRQn);
Question:
1. 根据以上流程, bootloader引导App没有问题, App升级固件没有问题, App升级完毕后. 引导bootloader也 OK, 然后bootloader再次引导更新后的App时, 发现 主机端不能识别VCOM了.
2. 通过对M453断电再开机, 主机能识别VCOM了,而且确认新固件能运行. 或者M453不复位, 主机端的usb口拔插一下, 主机端也能识别VCOM了.
从上述现象, 应该是主机端的USB口没有进行usb设备的重枚举, 解决方法我觉得应该是a. 想办法让主机端linux进行设备重枚举
b. 让M453端进行设备重枚举.
经不断试验, 结果如下.
a. 让主机端linux进行设备重枚举. (有方法, 但不是最好的处理方式, 因为主机端要知道何时复位设备所在的USB总线, 而且如果总线挂甚多设备时不合适)
b. 让M453端进行设备重枚举. (看官网资料, 说是USB控制支持软件断开连接功能, 即SE0先置位, 延时后再清零即可. 但看代码USBD_Open/USBD_Start已经做了, 我在App最初的时候也做了一次, 也没有效果)
所以问问群内大牛门, Why and How 让固件更新后M453做什么操作可以让主机端识别到VCOM?
|