你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【实战经验】STM32系列MCU模拟双盘符U盘的应用

[复制链接]
zero99 发布时间:2017-4-5 17:27
STM32系列 MCU模拟双盘符 U盘的应用
( P$ O) _' |5 T$ `9 r4 M/ t! K
应用背景
2 e8 J8 v; W4 n/ U9 r& q* s客户使用STM32F429系列MCU,存储介质有两种,分别为SDIO连接TF-card,SPI Flash,目的是通过1个usb口连接到PC后,能够看到两个盘符,PC能够分别对TF-card和SPI Flash进行读写操作。. O$ q+ p6 P$ u& u; g

$ A, o8 n$ p1 ]( W3 q0 F4 `0 F9 l8 H& Q7 J' `$ m- A( c: r1 c5 U: s8 S
问题分析
" l1 l9 K' Q; F" ~) H2 d: N3 `抓包分析,出现STALL的情况; M8 L" B) G5 @# Q& E/ c
11.jpg 9 q: q, K! k) o: d
走读代码,发现函数
5 O; H( t' C& b, T8 fstatic 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 )
: O* }% j. m  B% l% p4 Z9 G+ ?! l. ?% |if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
7 B8 G2 [6 W* w3 _7 nif (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)  }  a. k3 l- }- O
这几处如果不成功,就会返回,使得端点STALL!
9 V: i% o1 P( x, H) I" k& d
8 m: }5 ~, \5 ?& v$ {$ Q7 i/ O, G解决方案
$ F4 c' ?3 S6 }9 r# x考虑到客户使用的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)
) o* m* r* \7 @# f: Y, I7 Y函数里面
% V) B) D- A9 a$ p/ Uif(((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)
* \2 X9 T1 d" Z, ]* O5 c+ Xif (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)8 p" ^) d* i1 q, f7 y& O
这几处如果不成功,就会返回,使得端点STALL!" t/ E2 o2 l- _2 v" R! K

6 ~6 J3 Y8 v) F  \6 [继续跟代码,发现是这两个全局变量导致问题的(由于2个盘设定不一,导致使用混乱错误) hmsc->scsi_blk_size
5 _8 ]7 s/ K2 I% ~8 T! Ehmsc->scsi_blk_nbr+ p/ o1 P- F+ x: G0 `4 F' J
所以在读写的时候,需要对这两个全局变量进行重新赋值,如:! ~% s' ^  D$ t3 [9 \
Switch (lun)
! q2 {. N# S0 {% |{3 o+ S. c2 k. T
     Lun 0: // TF-Card
5 q. q$ {) }+ ~8 o         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;
$ f, e7 R3 J- e! O) }. K7 l5 ~3 h% V6 s  O
        Lun 1: // SPI-Flash/ s! W! M% U& |( P3 a% @
            hmsc->scsi_blk_size = 1024 ;
' V( F; k+ L/ ?, k, n. z            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
附代码的使用 :
' u( f# t  N1 C: X/ ?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
12.png
6 H7 m* ^9 i' f+ @! yMSC_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

& d% ~3 G. l$ G" CMSC.7z
: ?8 b8 r. w+ Q4 o8 N7 N3 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 不一致的时候,需要特别小心处理!

# f( X; E/ n5 S2 L
! ^' d4 u5 E% m8 _6 y

; ?/ Q6 r) D/ m% p5 o. X5 A  E& G STM32系列MCU模拟双盘符U盘的应用.pdf (210.48 KB, 下载次数: 187)
赞 1 收藏 2 评论4 发布时间:2017-4-5 17:27

举报

4个回答
jinglixixi 回答时间:2017-4-5 18:09:45
已收藏,点赞!
arenas 回答时间:2017-4-6 09:40:57
感谢分享
jinshan2014 回答时间:2017-11-2 20:38:56
谢谢分享
pythonworld 回答时间:2017-11-3 07:24:40
谢谢分享!

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版