STM32系列 MCU模拟双盘符 U盘的应用 应用背景 客户使用STM32F429系列MCU,存储介质有两种,分别为SDIO连接TF-card,SPI Flash,目的是通过1个usb口连接到PC后,能够看到两个盘符,PC能够分别对TF-card和SPI Flash进行读写操作。 , k7 j* {7 J, b 问题分析+ U( M) ?; s' @ 抓包分析,出现STALL的情况 走读代码,发现函数 static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)7 F. { K6 ?& k' x4 {# X% i 函数里面' s2 W5 E* t- J. f if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )& Z( _2 w1 p/ ^ @ if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)6 d3 j% ~: c. D9 y; }& ~! ~% F if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len) 这几处如果不成功,就会返回,使得端点STALL! 解决方案7 y* `; u. j# v* T w% I8 R 考虑到客户使用的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)% J. G* g" D+ R9 P* ~3 Y: C 函数里面 if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )1 _" Z4 w C9 m5 ~0 ^ if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)5 X0 s S- }0 c# z" ^8 A& d if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len) q8 S/ W4 L- }( Y% h0 ~7 ? 这几处如果不成功,就会返回,使得端点STALL!0 x! R0 u0 d$ a% T7 g$ y % ]( c7 a+ B( k4 T* d 继续跟代码,发现是这两个全局变量导致问题的(由于2个盘设定不一,导致使用混乱错误) hmsc->scsi_blk_size hmsc->scsi_blk_nbr 所以在读写的时候,需要对这两个全局变量进行重新赋值,如:; k+ D8 ^' z; _1 W& `, M) A Switch (lun) {( D" h( N. a6 g6 t4 A Lun 0: // TF-Card9 `$ W$ c6 X5 U$ s# [3 U4 R8 i hmsc->scsi_blk_size = 512 ;7 S- L2 b' q6 y# _. T* ]4 U hmsc->scsi_blk_nbr = tf-card_SIZE / 512 -1 ; " w0 |" m4 ?' Z% a! i4 O Break; ' D+ r: ^$ E% N6 R Lun 1: // SPI-Flash5 E! b& O3 U% v/ O' r+ k hmsc->scsi_blk_size = 1024 ; hmsc->scsi_blk_nbr = 64 - 1; // use 64k RAM to simulate RAM-disk ( q& P7 |0 {! g/ I7 Y, N; f Break; Default: Break; }# ^# _0 o3 g& C " V( s7 [+ k; a! f; M 附代码的使用 :! B/ D' F7 B2 v( {7 J9 W) N STM32Cube_FW_F4_V1.12.0\Projects\STM324x9I_EVAL\Applications\USB_Device MSC_2storage_test.7z I9 L! H& B& N1 ? STM32Cube_FW_F4_V1.12.0\Middlewares\ST\STM32_USB_Device_Library\Class% U# r( v" n8 R2 f MSC.7z! z* w3 b' I2 q 总结 由于驱动本身只支持LUN 为1,当使用双盘符时,在usb device 端除了需要对LUN0 和LUN1 分开进行处理(读,写),还需要考虑一些全局变量,虽然在BOT 协议里,大部分值都是从PC 端,也就是HOST 端传下来的,但是会有一些全局变量并非如此,特别在两个LUN 的block size 不一致的时候,需要特别小心处理!" B' }3 M U# m1 Q, B2 W. y1 s ( q1 Q/ G# H* f: v3 X6 M7 _. \ |
已收藏,点赞! |
感谢分享 |
谢谢分享 |
谢谢分享! |
【银杏科技ARM+FPGA双核心应用】STM32H7系列10——ADC
【银杏科技ARM+FPGA双核心应用】STM32H7系列57——MDK_FLM
【STM32图书分享之九】—《STM32F 32位ARM微控制器应用设计与实践》
无刷直流电机控制应用+基于STM8S系列单片机---电子书
STM32 USB的程序,包含固件、驱动和测试用的应用程序
工业以太网总线ETHERCAT驱动程序设计及应用(扫描版)
【实战经验】STM32 DFSDM测量温度应用
【实战经验】基于STM32 I2S的音频应用开发介绍
【中文文档】AN4112_使用STM32F05xx模拟比较器的六个应用案例
[连载]STM32F103ZET6 uCGUI3.90a控件应用教程(第五节 复选框和单选按钮)