STM32系列 MCU模拟双盘符 U盘的应用 应用背景- `# 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. [ 问题分析 抓包分析,出现STALL的情况( W3 b5 X- b. k( e- l f4 ~6 d 走读代码,发现函数" @% L7 y5 O# g) w% ]. t static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params) 函数里面, 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) 这几处如果不成功,就会返回,使得端点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)" A; Q/ Z( S, W# y9 s4 ~8 Z6 L 函数里面 if(((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) if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len) 这几处如果不成功,就会返回,使得端点STALL! 7 ?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) {8 z" I9 q4 j$ ? Lun 0: // TF-Card 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 Break;) Q5 B5 u* m% R Lun 1: // SPI-Flash) R( [3 p6 ?( a! V. a Y hmsc->scsi_blk_size = 1024 ; hmsc->scsi_blk_nbr = 64 - 1; // use 64k RAM to simulate RAM-disk - ~0 c g& ?/ d9 ?" P9 H Break;$ N- t A( N, ^0 q! f Default:# r# b. P R' V1 m0 ] Break; } 5 q. r$ K& Q6 d3 ~ 附代码的使用 :- o, ~3 n: C7 F7 U% _5 A STM32Cube_FW_F4_V1.12.0\Projects\STM324x9I_EVAL\Applications\USB_Device) Z9 N% N2 a; U$ `* Y0 ]+ Y0 b MSC_2storage_test.7z " 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 6 n3 d, z4 r5 b R# B 总结 由于驱动本身只支持LUN 为1,当使用双盘符时,在usb device 端除了需要对LUN0 和LUN1 分开进行处理(读,写),还需要考虑一些全局变量,虽然在BOT 协议里,大部分值都是从PC 端,也就是HOST 端传下来的,但是会有一些全局变量并非如此,特别在两个LUN 的block size 不一致的时候,需要特别小心处理! ' a% ` G0 h2 N2 A p. { 9 J4 h u, G: V" X: g B- `4 j |
已收藏,点赞! |
感谢分享 |
谢谢分享 |
谢谢分享! |
【银杏科技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控件应用教程(第五节 复选框和单选按钮)