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

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

[复制链接]
zero99 发布时间:2017-4-5 17:27
STM32系列 MCU模拟双盘符 U盘的应用

9 c6 Y, z" O% C5 F5 X" z应用背景- `# m" W2 ]! X) ^; I! v+ J$ n" ?
客户使用STM32F429系列MCU,存储介质有两种,分别为SDIO连接TF-card,SPI Flash,目的是通过1个usb口连接到PC后,能够看到两个盘符,PC能够分别对TF-card和SPI Flash进行读写操作。2 N/ i# @" G$ W. [

4 L: U5 e2 I3 \
9 x+ d5 D/ J9 b, X, ]3 @( _  ?  H& P问题分析
" L) q* }4 _( u  M5 b: ~3 x抓包分析,出现STALL的情况( W3 b5 X- b. k( e- l  f4 ~6 d
11.jpg ; H$ F9 S* O7 T+ R8 Q
走读代码,发现函数" @% L7 y5 O# g) w% ]. t
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
& n: A- y& g% E( u0 r! S2 w3 p/ b函数里面, Z6 [. H; h4 u
if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )" X& {! D3 C7 s" C5 M
if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)0 w; U/ E! L7 `4 E
if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
& ?1 m  a6 l: Y* f5 q: A" L这几处如果不成功,就会返回,使得端点STALL!
7 _% O  _6 B6 {4 v- V
: R# e. Z- W, ], W* T解决方案
& c" W1 P6 h% M考虑到客户使用的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)" A; Q/ Z( S, W# y9 s4 ~8 Z6 L
函数里面
5 z# h+ Y" A9 s4 r4 Oif(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )& r) |" B, q) A) H' J; ~
if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
0 u5 f" D* l0 c1 L7 cif (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
- ~: a8 P) T1 j+ b5 K# E( c. ?这几处如果不成功,就会返回,使得端点STALL!
* ]5 i2 n8 L0 ^  D4 y7 ?5 T, T" S8 V/ s5 g/ y; m1 ~
继续跟代码,发现是这两个全局变量导致问题的(由于2个盘设定不一,导致使用混乱错误) hmsc->scsi_blk_size- k- X3 q* m- D9 o% `3 V$ n
hmsc->scsi_blk_nbr* a9 ?$ N8 I+ J% Q
所以在读写的时候,需要对这两个全局变量进行重新赋值,如:* J7 B7 B& Q9 \5 y# R, o) k* o( V
Switch (lun)
/ G, [* P" [6 z# S- W6 R2 U  p{8 z" I9 q4 j$ ?
     Lun 0: // TF-Card
9 R4 s: h" _# a! d" V& v$ Z         hmsc->scsi_blk_size = 512 ;/ k. T: Y- z: l
         hmsc->scsi_blk_nbr = tf-card_SIZE / 512 -1 ;. Z. u) l7 f- ^( r$ T

1 H+ H) d4 r" m8 z9 o6 X        Break;) Q5 B5 u* m% R

: w, ?& n  ~9 }3 L! s+ b3 N4 ^        Lun 1: // SPI-Flash) R( [3 p6 ?( a! V. a  Y
            hmsc->scsi_blk_size = 1024 ;
: L; [/ d/ Q) ~, e. A& x8 Y            hmsc->scsi_blk_nbr = 64 - 1; // use 64k RAM to simulate RAM-disk
1 N- L6 u* ^. T8 q( h# ~7 ~) [- ~0 c  g& ?/ d9 ?" P9 H
            Break;$ N- t  A( N, ^0 q! f
        Default:# r# b. P  R' V1 m0 ]
            Break;
" c" {, o3 ~( ?& H1 r" Q1 }! ?}
. z* G. C/ D: @5 q. r$ K& Q6 d3 ~
附代码的使用 :- o, ~3 n: C7 F7 U% _5 A

8 }8 |0 x& l( Y1 J4 `3 W5 G8 tSTM32Cube_FW_F4_V1.12.0\Projects\STM324x9I_EVAL\Applications\USB_Device) Z9 N% N2 a; U$ `* Y0 ]+ Y0 b
12.png ( U( D" }! j# D0 Q) D- A
MSC_2storage_test.7z
  x) y: W: l. a6 V. u- w" v) t* n, ]/ ^! h# t, q0 m
STM32Cube_FW_F4_V1.12.0\Middlewares\ST\STM32_USB_Device_Library\Class; C7 o  G: \, k# F/ F
2 F3 m, D8 M# |0 G: O
MSC.7z
, |* g/ M! \9 w$ [, n$ p6 n3 d, z4 r5 b  R# B
总结
( s& y& Q) n* {/ `- g; N由于驱动本身只支持LUN 为1,当使用双盘符时,在usb device 端除了需要对LUN0 和LUN1 分开进行处理(读,写),还需要考虑一些全局变量,虽然在BOT 协议里,大部分值都是从PC 端,也就是HOST 端传下来的,但是会有一些全局变量并非如此,特别在两个LUN 的block size 不一致的时候,需要特别小心处理!

) J7 O, k- z: Z( Q' a% `  G0 h2 N2 A  p. {
9 J4 h  u, G: V" X: g  B- `4 j
STM32系列MCU模拟双盘符U盘的应用.pdf (210.48 KB, 下载次数: 181)
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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版