STMCU小助手
发布时间:2021-1-26 11:00
|
STM32 OTG主机库U盘应用中的NAK处理
经常碰到有人在利用USB OTG做U盘的应用过程中遇到一些识别或读取问题。这里分享一篇STM32芯片的OTG模块做U盘应用过程中关于NAK处理的解析过程供参考。文章源于ST官方FAE技术应用文档,本文底部有网站地址介绍,可供原文及参考代码下载。 问题: 某客户使用STM32F4的OTG库做USB主机控制Wifi网卡。使用BULK传输时,从设备读取数据时,如果设备需要返回把设备返回的NAK状态告知上层应用,该如何修改OTG库。 调研: 先来看看OTG库当前对BULK类型传输,IN和OUT方向上的NAK的处理方式:
一旦重新使能该通道,主机硬件又自动发送IN令牌企图从设备获取数据,直到设备准备好数据不再回复NAK,而回复主机要获取的数据,然后主机硬件回复ACK结束本次transfer。 BULK IN通道对NAK的处理和CTRLIN通道对NAK的处理,在ISR中是一样的;但是在驱动库里,对CTRL IN有超时限制,而对BULK IN没有。就是说对于常用来做枚举传输的CTRL传输,当启动从设备获取信息,但是久久未得的情况下,会走到Timeout的处理分支。从代码里我们可以看到:
但是BULK IN通道对NAK的接收没有超时控制,因为BULK传输本身的性质就是不保证带宽的,即如果主机上有很多其他优先级更高的周期类型的传输(同步ISO传输和中断INT传输),则在BULK传输有可能无限延迟。 CTRL IN对NAK有超时处理,那么CTRL OUT对NAK是如何处理的呢? 从代码里可以看到CTRL OUT收到NAK后会把该状态上传APP。
然后在库代码处理控制传输时,如果检测到这个状态,就会重新发送OUT令牌和数据包。
因此,当CTRL IN收到NAK后,如果想把状态上传给App,则可以模仿CTRL OUT对NAK的处理。首先, ISR中的处理可以模仿CTRL OUT,在BULK传输的处理中,对每次发送IN令牌的地方(USBH_BulkReceiveData)查询传输状态,如果URB_NOTREADY就由App来决定如何处理。 处理: 基于U盘读写的例程,在每次USBH_BulkReceiveData之后检查状态,如果是URB_NOTREADY就重新发送IN令牌。全项目USBH_BulkReceiveData有三个地方,且都在USBH_HandleBOTXfer()中调用,即在BOT传输中若干次读数据阶段(多次数据包整数长度读取和最后一次的尾巴数据读取)和CSW阶段的读取。
需要对每次BULK IN传输后检测状态,如果收到NAK则重新发起刚才的那次BULK IN传输:
经过以上修改,以FS和HS都能对U盘正确读取。 修改后的参考固件代码,请去WWW.STMCU.COM.CN官网实战经验处下载。
文章出处: 茶话MCU |
微信公众号
手机版