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

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

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

! l: x0 ^/ M5 ?应用背景" y3 t6 j4 ?' W: j! F
客户使用STM32F429系列MCU,存储介质有两种,分别为SDIO连接TF-card,SPI Flash,目的是通过1个usb口连接到PC后,能够看到两个盘符,PC能够分别对TF-card和SPI Flash进行读写操作。
  E. A6 L( `8 l9 a1 z: H, e0 x! L
% W) ~- f' ^* c3 q1 _$ ^
0 ^0 `+ y) F5 ~. o: ?) [6 s, X0 ^5 m( v  _问题分析0 P2 i; ]7 W$ K6 j* A! y1 N4 j
抓包分析,出现STALL的情况  m0 {- c+ u. H4 C" w& Y4 {
11.jpg
7 E2 Z& E# q% E) K5 k4 Z走读代码,发现函数' ?6 J2 h8 x3 Y# f9 u
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
8 D: ]& u& @% [( V9 U/ k( Z% b7 B; r: h函数里面
( }# i7 e( s) J7 xif(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
6 |4 T$ P7 B( `8 nif( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
: h1 B0 a: e# k3 Mif (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
/ M% k$ @1 f9 b* v这几处如果不成功,就会返回,使得端点STALL!
& Z) H1 K7 b5 T" F+ u& ^' I& d( _: w. I
解决方案
) E! O5 R& v6 T0 D( N6 n考虑到客户使用的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)+ n. j' y# |5 W4 K
函数里面
! G* Z8 Y. G  _+ j  Vif(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
- J, ~) d. D0 s* g8 w  Vif( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
/ u8 A. r% ~' Eif (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
5 \" j3 i" O9 u4 b% Q这几处如果不成功,就会返回,使得端点STALL!. M9 `( L: {! {

5 y5 T6 p% W; L% K) b  H4 j. @" G继续跟代码,发现是这两个全局变量导致问题的(由于2个盘设定不一,导致使用混乱错误) hmsc->scsi_blk_size5 n# r, D) `" j$ C
hmsc->scsi_blk_nbr
/ {+ h3 f/ w+ C, O" m% s( R! V所以在读写的时候,需要对这两个全局变量进行重新赋值,如:1 a/ ^( P& [, R7 |0 t5 g
Switch (lun), y' {# {, Z1 F* g
{
3 ^7 z/ S# j5 k  F5 J# P9 |     Lun 0: // TF-Card
: w, a% c' T2 U+ w8 @$ Y         hmsc->scsi_blk_size = 512 ;; W8 `$ a9 {1 z# J7 H
         hmsc->scsi_blk_nbr = tf-card_SIZE / 512 -1 ;& r/ L7 j& l9 h4 J& K7 o! g6 c0 K4 E

, b2 f+ a1 s- L: A5 v        Break;
2 N: |5 x: `: M, ?6 H9 i; e' I
0 s# V7 |- G2 y! D3 \        Lun 1: // SPI-Flash
! j8 O# ]8 \2 G* c            hmsc->scsi_blk_size = 1024 ;8 P  J8 C4 \% l5 H/ O+ W) _9 [9 n
            hmsc->scsi_blk_nbr = 64 - 1; // use 64k RAM to simulate RAM-disk3 z' p* {5 y, ^: d. }) k4 h' I

0 w9 |+ H) K7 j1 D+ D/ t            Break;% N6 Y; A9 x4 g! R
        Default:
: ]- m0 }/ v( j2 o            Break;
3 p1 B' k, i* A: N5 M* o! Y. R}
  R! `' z% S: F% \
# @* g: g8 Z% M" P7 G: c0 o附代码的使用 :
7 b" Q! ?  n7 F7 ~2 D# E& ]! @- U. e$ A8 k: l
STM32Cube_FW_F4_V1.12.0\Projects\STM324x9I_EVAL\Applications\USB_Device+ R/ A; W6 w/ ~) ?+ \1 I7 Y
12.png 1 K' g" y  M9 z) `1 V
MSC_2storage_test.7z
" D: H; t$ }, b! ]/ C8 b  G9 t5 ]  Q0 l7 J4 E$ ]$ s- a
STM32Cube_FW_F4_V1.12.0\Middlewares\ST\STM32_USB_Device_Library\Class0 Q2 r& Q: b' l+ P' o: S

* x8 z0 t' H& u; b4 \. w' MMSC.7z" F- u; N( M, ^# c" m

6 l! W" T. o# r6 M总结
) Q9 V7 {# j- C* Y: Z1 w由于驱动本身只支持LUN 为1,当使用双盘符时,在usb device 端除了需要对LUN0 和LUN1 分开进行处理(读,写),还需要考虑一些全局变量,虽然在BOT 协议里,大部分值都是从PC 端,也就是HOST 端传下来的,但是会有一些全局变量并非如此,特别在两个LUN 的block size 不一致的时候,需要特别小心处理!

. u5 \+ [* I( A7 x, ]8 |. y$ |. \4 V5 l. a
' p* Q, y& d* g9 I4 V4 u$ k0 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 手机版