Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
USB主机_host
RT-Thread一般讨论
20
USBHOST读写U盘,无限NAK真正问题原因
发布于 2022-01-20 11:51:38 浏览:2491
订阅该版
``` rt_err_t rt_usbh_storage_read10(struct uhintf* intf, rt_uint8_t *buffer, rt_uint32_t sector, rt_size_t count, int timeout) { struct ustorage_cbw cmd; rt_base_t level; /* parameter check */ if(intf == RT_NULL) { rt_kprintf("interface is not available\n"); return -RT_EIO; } RT_ASSERT(intf->device != RT_NULL); RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbh_storage_read10\n")); /* construct the command block wrapper */ level = rt_hw_interrupt_disable(); rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); cmd.signature = CBW_SIGNATURE; cmd.tag = CBW_TAG_VALUE; cmd.xfer_len = SECTOR_SIZE * count; cmd.dflags = CBWFLAGS_DIR_IN; cmd.lun = 0; cmd.cb_len = 10; cmd.cb[0] = SCSI_READ_10; cmd.cb[1] = 0; cmd.cb[2] = (rt_uint8_t)(sector >> 24); cmd.cb[3] = (rt_uint8_t)(sector >> 16); cmd.cb[4] = (rt_uint8_t)(sector >> 8); cmd.cb[5] = (rt_uint8_t)sector; cmd.cb[6] = 0; cmd.cb[7] = (count & 0xff00) >> 8; cmd.cb[8] = (rt_uint8_t) count & 0xff; rt_hw_interrupt_enable(level); return rt_usb_bulk_only_xfer(intf, &cmd, buffer, timeout); } ``` ``` static rt_err_t rt_usb_bulk_only_xfer(struct uhintf* intf, ustorage_cbw_t cmd, rt_uint8_t* buffer, int timeout) { ... do { /* send the cbw */ size = rt_usb_hcd_pipe_xfer(stor->pipe_out->inst->hcd, stor->pipe_out, cmd, SIZEOF_CBW, timeout); if(size != SIZEOF_CBW) { rt_kprintf("CBW size error\n"); return -RT_EIO; } if (cmd->xfer_len != 0) { pipe = (cmd->dflags == CBWFLAGS_DIR_IN) ? stor->pipe_in : stor->pipe_out; size = rt_usb_hcd_pipe_xfer(pipe->inst->hcd, pipe, (void*)buffer, cmd->xfer_len, timeout); if(size != cmd->xfer_len) { rt_kprintf("request size %d, transfer size %d\n", cmd->xfer_len, size); break; } } /* receive the csw */ size = rt_usb_hcd_pipe_xfer(stor->pipe_in->inst->hcd, stor->pipe_in, &csw, SIZEOF_CSW, timeout); if(size != SIZEOF_CSW) { rt_kprintf("csw size error\n"); return -RT_EIO; } }while(0); ... } ``` ###错误包 ![image.png](https://oss-club.rt-thread.org/uploads/20220120/4ef19fcfce572d9f8acd74edd29200ee.png) ###正确包 ![image.png](https://oss-club.rt-thread.org/uploads/20220120/4c826e38eff75e68b724b476af619073.png) 如上所示: 我在基于4.03,4.04版本,使用USB_FS,only_host模式读写U盘时,能够正常识别U盘,但是读写U盘时经常型的陷入无限NAK的循环中。也在论坛中查看了相关的问题分享,参照修改驱动后,并没能解决问题。 后面我又在多个版本下测试USBHOST 读写U盘 (1)TM官方的裸机USBhost读写U盘工程,U盘热插拔,读写均无问题 (2)裸机工程加入nano3.15,U盘热插拔,读写无问题; (3)裸机工程中的usbhost 的相关驱动,完整移植到4.04中,u盘识别要十几秒的时间,无法正常读写。 (4)裸机工程中的usbhost 的相关驱动,完整移植到4.02中,U盘热插拔,读写均无问题 (5) 4.02下使用rtt的usb驱动,U盘读写无问题; (6)将4.02的内核替换至4.03下,U盘读写异常,仍然是无限NAK。 前两天在论坛上看到一位大佬提到,使用usb协议抓包分析,发现是主机在提交一个读请求时被中断打断,导致U盘回复NAK。后经仿真调试确定每次都是在 ``` size = rt_usb_hcd_pipe_xfer(stor->pipe_out->inst->hcd, stor->pipe_out, cmd, SIZEOF_CBW, timeout); if(size != SIZEOF_CBW) { rt_kprintf("CBW size error\n"); return -RT_EIO; } if (cmd->xfer_len != 0) { pipe = (cmd->dflags == CBWFLAGS_DIR_IN) ? stor->pipe_in : stor->pipe_out; size = rt_usb_hcd_pipe_xfer(pipe->inst->hcd, pipe, (void*)buffer, cmd->xfer_len, timeout); if(size != cmd->xfer_len) { rt_kprintf("request size %d, transfer size %d\n", cmd->xfer_len, size); break; } } ``` 发生CBW命令后,传输出错。 下单购买了一个USB协议分析仪 ![image.png](https://oss-club.rt-thread.org/uploads/20220120/3990033633399af6daa7346c9c15ea31.png.webp) 经过一上午的抓包分析,确定每次读U盘陷入无限nak错误的时候,就是因为发送 CBW 指令出错。 正确的一包 读数据的时候 CBW 指令 55 53 42 43 78 56 34 12 00 02 00 00 80 00 0A 28 00 00 00 88 00 00 00 01 00 00 00 00 00 00 00 而出错时,分析仪抓包到的 数据是 EE 6D FA EB DA 8D (不固定,但确实不是上面那个正确的包) 尝试修复这个bug ``` level = rt_hw_interrupt_disable(); HAL_HCD_HC_SubmitRequest(&stm32_hhcd_fs, pipe->pipe_index, //通道号 direction, pipe->ep.bmAttributes, token, buffer, nbytes, 0); rt_thread_mdelay(1); rt_hw_interrupt_enable(level); ``` 在发送包的时候,关闭中断,甚至加入延时,都无法避免这个问题。 本人由于不是很熟悉STM32 USB数据发送过程,不知道怎么去避免USB数据发送出错的情况,所以这个bug 还请论坛的大佬们帮忙看看,要怎么改...
查看更多
4
个回答
默认排序
按发布时间排序
出出啊
2022-01-20
恃人不如自恃,人之为己者不如己之自为也
结论是啥?是因为中断吗?
梅江松子
2022-01-20
这家伙很懒,什么也没写!
跪求大佬翻牌,在线做大佬的提线偶,一起探讨这个问题?
sakumisu
认证专家
2022-01-20
https://github.com/sakumisu
看你的分析,看样子是os调度影响了 usb通信,NAK的行为是device的,所以主机发送错误以后,device才会nack,主机发送错误,主要可能是os调度卡在了某个位置,使得complete irq么有完成,但是可能是完成了,调度没有结束,又重新走了一遍。
SukTry
2022-09-13
这家伙很懒,什么也没写!
大佬,最后解决这个问题了吗?我也遇到该问题了,不知道怎么解决了。我的现象是基于V4.0.3内核及驱动实现是没有问题的,可以正常读取数据,但是基于RTT最新内核V4.1.1就不行,无限nak ```c cmd size 1024, size 1024 rt_usbh_storage_read10 334 cmd size 1024, size 1024 rt_usbh_storage_read10 334 cmd size 1024, size 0 request size 1024, transfer size 0 pipes1 0x20019470, 0x200194ac receive the csw after stall failed in pipe error usb mass_storage read failed ``` 搞了两三天了,没找到头绪,我也互相移植了usb驱动,未果。。。
撰写答案
登录
注册新账号
关注者
2
被浏览
2.5k
关于作者
梅江松子
这家伙很懒,什么也没写!
提问
12
回答
18
被采纳
3
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
a1012112796
13
个答案
1
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部