USB论坛
直播中

刘洋

8年用户 1352经验值
私信 关注
[问答]

USB 3.0CX3中的辅助引导加载程序后无法识别怎么解决?

我正在为CYPRESS™ CX3 (FX3) 开发辅助引导加载程序 (SBL),它从 SPI Flash 加载应用程序并执行它。 但是,通过 SBL 启动应用程序时,USB 3.0 枚举失败。
我的引导加载程序实现基于来自boot_fw/src/spi_test.c的参考代码。

观察到的行为

1当直接加载应用程序(不使用 SBL)时 →USB 3.0 工作正常。
2. 通过辅助引导加载程序引导时 → USB 枚举失败(未检测到设备或处于未知状态)。
3. 两种情况下使用相同的应用程序二进制文件,但 USB 的行为不同。
4. 在应用程序中添加调试打印语句可以使 USB 枚举工作,但删除它们会导致失败。
5.引导加载程序根本不初始化 USB。 它只是从 SPI 加载应用程序并跳转到CyFx3BootJumpToProgramEntry() 。
调试观察

USB 3.0 链路状态和 PHY 状态寄存器显示工作和非工作情况之间的差异:

  • 工作案例(无引导加载程序):

    • USB3 Link State: 0x60000000
    • USB3 PHY Status: 0x110010
  • 失败案例(引导加载程序之后):

    • USB3 Link State: 0x60000053
    • USB3 PHY Status: 0x110010
      - 引导加载程序和应用程序之间的 SPI 设置在不同,但都可以正确访问闪存。
      - 调试和非调试版本之间存在内存布局差异,影响.text部分的大小。
      - 引导加载程序正确地从 SPI 加载应用程序二进制文件(通过 UART 日志和内存转储验证)。

问题


  • 仅通过 SBL 启动时导致 USB 3.0 枚举失败的原因是什么?
  • 从 SBL 跳转后,USB PHY 或链路状态是否需要明确重新初始化?
  • 内存布局的差异(由于调试打印)会影响 USB 操作吗?
  • 引导加载程序执行后,是否有任何 USB 寄存器/设置需要手动重置或重新配置?
  • 从引导加载程序转换到应用程序时,如何确保 USB 3.0 链接正确初始化?

回帖(1)

徐开

2025-5-8 18:13:59

针对CYPRESS™ CX3 (FX3)辅助引导加载程序(SBL)导致USB 3.0枚举失败的问题,以下是逐步解决方案:


1. 检查内存配置和资源释放



  • 确保SBL释放所有硬件资源:在跳转到应用程序前,调用CyU3PDeviceStop()停止外设,并使用CyU3PMemoriesRelease()释放DMA缓冲区。

  • 验证内存布局:检查链接脚本(.ld文件),确认SBL和应用程序的RAM使用区域无重叠,尤其是USB相关缓冲区。


// 在SBL跳转前添加资源释放代码
CyU3PDeviceStop();         // 停止设备
CyU3PMemoriesRelease();    // 释放内存和DMA通道

2. 复位外设和时钟



  • 复位USB控制器:在跳转前调用CyU3PDeviceDeInit(),确保USB控制器处于初始状态。

  • 避免时钟冲突:SBL中若修改了时钟配置,应在跳转前恢复默认设置或由应用程序显式重新配置。


CyU3PDeviceDeInit();       // 复位外设和时钟

3. 中断处理



  • 禁用全局中断:在跳转前禁用中断,避免残留中断影响应用程序。

  • 验证应用程序的中断向量表(IVT):确保应用程序的IVT正确加载到RAM起始位置。


// 在SBL跳转前禁用中断
CyU3PIntrDisable();        // 关闭所有中断

4. 添加延时或同步机制



  • 在USB初始化前插入延时:若SPI Flash加载后硬件需要稳定时间,可在应用程序的USB初始化代码前添加CyU3PBusyWait(1000);(1ms)。

  • 轮询关键状态寄存器:检查USB PHY是否就绪,例如等待CY_U3P_USB_PHY_READY标志。


5. 调试应用程序的启动流程



  • 检查堆栈和全局变量初始化:确保应用程序的启动代码(如Reset_Handler)正确初始化堆栈和BSS段。

  • 验证应用程序入口点:确认SBL正确跳转到应用程序的入口地址(通常为0x40000000)。


6. 使用调试工具定位问题



  • GPIO调试:在关键步骤(如USB初始化)前后切换GPIO引脚,用示波器观察时序。

  • JTAG调试:连接调试器,单步执行应用程序的USB初始化代码,检查寄存器状态(如CY_U3P_USB_CONTROLLER_ID)是否正确。


7. 修复应用程序的USB初始化顺序



  • 显式重新初始化USB:即使SBL已初始化USB,应用程序仍需完整执行USB配置流程,包括描述符提交和连接使能。


// 应用程序中的USB初始化示例
CyU3PUsbStart();              // 启动USB模块
CyU3PUsbSetDesc(usbDescriptors); // 设置描述符
CyU3PUsbRegisterSetupCallback(handleUsbSetup, TRUE); // 注册回调
CyU3PUsbRegisterLpmRequestCallback(handleLpmRequest); // 低功耗回调
CyU3PUsbRegisterVendorExtension(handleVendorCmd);    // 扩展命令
CyU3PUsbConnect(TRUE);        // 连接USB

8. 检查SPI Flash加载的正确性



  • 验证固件完整性:确保从SPI Flash读取的应用程序固件未被损坏,可计算CRC并与原始文件对比。

  • 调整SPI时钟速度:过高的SPI时钟可能导致读取错误,尝试降低SPI速率(如从33MHz降至10MHz)。


9. 参考官方示例调整代码



  • 对比spi_test.c中的跳转代码,确保流程一致:


// 正确跳转到应用程序的流程
void JumpToApp() {
    typedef void (*EntryPoint)(void);
    EntryPoint appEntry = (EntryPoint)(0x40000000);

    // 关闭中断,复位外设
    CyU3PIntrDisable();
    CyU3PDeviceDeInit();

    // 设置堆栈指针(根据应用程序的向量表)
    __set_MSP(*(uint32_t*)0x40000000);

    appEntry(); // 跳转到应用程序
}

总结


问题通常源于SBL未完全清理硬件状态或应用程序未能正确重新初始化。重点检查内存冲突、外设复位、中断清理、时钟配置,并通过调试工具验证硬件状态。若添加打印后问题消失,可尝试在关键步骤(如USB连接前)插入短延时,或优化初始化顺序确保硬件就绪。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分