打印
[应用方案]

M451 USB 设备不能再Host 被识别.

[复制链接]
787|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
iibull|  楼主 | 2019-12-16 10:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
os, USB, AD, App
本帖最后由 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?


使用特权

评论回复
沙发
小明的同学| | 2019-12-17 21:29 | 只看该作者
固件更新后先运行这个USBD_Open/USBD_Start

使用特权

评论回复
板凳
heisexingqisi| | 2019-12-18 11:15 | 只看该作者
不清楚,官方的参考例子有没有这种

使用特权

评论回复
地板
iibull|  楼主 | 2019-12-20 12:58 | 只看该作者
小明的同学 发表于 2019-12-17 21:29
固件更新后先运行这个USBD_Open/USBD_Start

试过了, 没用

使用特权

评论回复
5
vsfopen| | 2019-12-20 13:25 | 只看该作者
451不知道,不过484是通过PHYCTL控制的:
https://github.com/vsfteam/vsf/blob/master/source/vsf/hal/driver/Nuvoton/M480/common/usb/dc/usbd_hs.c
里面搜索m480_usbd_hs_connect和m480_usbd_hs_disconnect。不过我们是自己的协议栈,不是用新塘的,所以没有什么USBD_Open和USBD_Start。

https://github.com/vsfteam/vsf/blob/master/source/example/usrapp/usbd_demo_msc/main.c
应用层demo里,需要额外的代码,来控制连接状态:
static void __usrapp_on_timer(vsf_callback_timer_t *timer)
{
    vk_usbd_connect(&__usrapp.usbd.dev);
}

int main(void)
{
#if VSF_USE_TRACE == ENABLED
    vsf_trace_init(NULL);
    vsf_stdio_init();
#endif

    vk_usbd_init(&__usrapp.usbd.dev);
    vk_usbd_disconnect(&__usrapp.usbd.dev);
    __usrapp.usbd.connect_timer.on_timer = __usrapp_on_timer;
    vsf_callback_timer_add_ms(&__usrapp.usbd.connect_timer, 200);
    return 0;
}

使用特权

评论回复
6
iibull|  楼主 | 2019-12-23 13:55 | 只看该作者
算了, 还是让host端重启一下整个总线轮训吧, 试了2天, 没有办法

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

17

帖子

1

粉丝