|
STM32系列 MCU模拟双盘符 U盘的应用 ( P$ O) _' |5 T$ `9 r4 M/ t! K应用背景 客户使用STM32F429系列MCU,存储介质有两种,分别为SDIO连接TF-card,SPI Flash,目的是通过1个usb口连接到PC后,能够看到两个盘符,PC能够分别对TF-card和SPI Flash进行读写操作。. O$ q+ p6 P$ u& u; g 9 l8 H& Q7 J' `$ m- A( c: r1 c5 U: s8 S 问题分析 抓包分析,出现STALL的情况; M8 L" B) G5 @# Q& E/ c
走读代码,发现函数 static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)3 ?) V' t8 A, ^ 函数里面8 n3 S) w: Y$ V. c( {) F3 J if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 ) if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0) if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len) } a. k3 l- }- O 这几处如果不成功,就会返回,使得端点STALL! 解决方案 考虑到客户使用的SPI FLASH,将block size设置为4096(而非通常意义上的512),因为这个SPI FLASH读写都是以4096Bytes为单位的。所以模拟利用stm32eval板,板上自带了tf-card的驱动,这时使用RAM模拟另一个盘,同时将其block size设为1024(容量有限,只要不是512即可),成功复现了客户的问题,走读代码,发现函数static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params) 函数里面 if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )/ b& w$ `6 `. `# g( L8 P8 D if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0) if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)8 p" ^) d* i1 q, f7 y& O 这几处如果不成功,就会返回,使得端点STALL!" t/ E2 o2 l- _2 v" R! K 继续跟代码,发现是这两个全局变量导致问题的(由于2个盘设定不一,导致使用混乱错误) hmsc->scsi_blk_size hmsc->scsi_blk_nbr+ p/ o1 P- F+ x: G0 `4 F' J 所以在读写的时候,需要对这两个全局变量进行重新赋值,如:! ~% s' ^ D$ t3 [9 \ Switch (lun) {3 o+ S. c2 k. T Lun 0: // TF-Card hmsc->scsi_blk_size = 512 ;- ]0 h5 R# e L% h- p/ n hmsc->scsi_blk_nbr = tf-card_SIZE / 512 -1 ; ?7 Q, P) Z( M$ i# u, Z / x/ m1 R* t& {# ^/ z6 X Break; ) }. K7 l5 ~3 h% V6 s O Lun 1: // SPI-Flash/ s! W! M% U& |( P3 a% @ hmsc->scsi_blk_size = 1024 ; hmsc->scsi_blk_nbr = 64 - 1; // use 64k RAM to simulate RAM-disk$ e6 L) o7 { [$ M ' X; ?; k4 `. s" d9 [9 ] Break;- f; k8 m8 y& r5 H& U Default:* J3 O0 m" ` d! @& q& d( W' t9 ? Break;. R' f# A. d4 Q9 e I' J: z. j2 z }, Q* i* E7 u: x* Y- a 3 u0 \1 F( r5 `) m% i 附代码的使用 : 7 C1 v m2 }5 l& z+ J# M STM32Cube_FW_F4_V1.12.0\Projects\STM324x9I_EVAL\Applications\USB_Device. e0 [/ r+ q. {' ~. x7 S" G
MSC_2storage_test.7z. z. t2 ^6 W. w! h# @ 4 X `/ _3 W* M" ~) u STM32Cube_FW_F4_V1.12.0\Middlewares\ST\STM32_USB_Device_Library\Class7 I0 e" H; T n9 B. r MSC.7z 3 o& e* Y/ `; b; {! p& W 总结: M# \7 R# ]0 e. o+ Q 由于驱动本身只支持LUN 为1,当使用双盘符时,在usb device 端除了需要对LUN0 和LUN1 分开进行处理(读,写),还需要考虑一些全局变量,虽然在BOT 协议里,大部分值都是从PC 端,也就是HOST 端传下来的,但是会有一些全局变量并非如此,特别在两个LUN 的block size 不一致的时候,需要特别小心处理!
STM32ç³»åMCU模æåç符Uççåºç¨.pdf
(210.48 KB, 下载次数: 187)
|
| 已收藏,点赞! |
| 感谢分享 |
| 谢谢分享 |
| 谢谢分享! |
无刷直流电机控制应用+基于STM8S系列单片机---电子书
MCSDK FOC应用详解
STM32F10xxx 正交编码器接口应用笔记 及源代码
基于STM32定时器ETR信号的应用示例
《无刷直流电机控制应用 基于STM8S系列单片机》
STM32定时器触发SPI逐字收发之应用示例
【银杏科技ARM+FPGA双核心应用】STM32H7系列10——ADC
【银杏科技ARM+FPGA双核心应用】STM32H7系列57——MDK_FLM
【STM32图书分享之九】—《STM32F 32位ARM微控制器应用设计与实践》
STM32 USB的程序,包含固件、驱动和测试用的应用程序
微信公众号
手机版