STM32F205 MSC虚拟U盘的奇怪问题:无法识别TF卡

2019-12-30 19:23发布

本帖最后由 mon51 于 2017-3-6 13:27 编辑

   原来用W25Q64+STM32F205 做过MSC虚拟U盘操作很好。现在要添加一个SD卡,使用了STM32_USB-Host-Device_Lib_V2.1.0库。但是发现:第二个虚拟U盘(SD卡)使用512M的卡测试没有问题,交到用户手上后,使用8G的TF卡发现虚拟的U盘无法格式化,可以枚举成功,但不认识U盘,一直提示没有插卡。经过追踪测试发现:
1:用4G的TF卡格式化时,选用每一个扇区512字节,可以认识虚拟U盘。但在win7,win10下默认格式化是4096字节,则无法识别。此时TF卡的物理第一个扇区只有一个MBR的跳转扇区数。
此时PC机无法根据跳转扇区数去查找到逻辑第一个扇区。追踪数据:PC机反复发出读一个物理扇区的指令,STM32F205也将512个字节发回给PC机,但无响应。是PC机端驱动有问题?
2:查看USBD_MSC_SCSI.c 文件发现:块地址的变量定义有问题:uint32_t  SCSI_blk_addr;但程序中却有: SCSI_blk_addr *= SCSI_blk_size; 当用4G以上的卡这样计算必定会溢出。
但是改成:uint64_t  SCSI_blk_addr; 结果也一样,PC机无法继续执行。因此问题不在这里。
3:用W25Q64和小容量的SD,一切正常说明程序没有问题,但为何用4G以上的卡就出问题?
4:系统中有FATFS,无论什么TF(1G,4G,8G,16G)均可以认识,并可以读写数据,说明TF也没有问题。用f_mkfs (1,1,512)格式化后的TF可以虚拟成U盘,用f_mkfs (1,1,4096)格式化的TF,虚拟U盘不成功!

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
niechao15
1楼-- · 2019-12-30 22:38
我记得好像超过4G的sd卡是高密度的,驱动好像不一样吧
lusson
2楼-- · 2019-12-31 00:36
 精彩回答 2  元偷偷看……
mon51
3楼-- · 2019-12-31 03:56
niechao15 发表于 2017-3-6 14:58
我记得好像超过4G的sd卡是高密度的,驱动好像不一样吧

SD卡底层驱动有问题,FATFS操作会出问题。但没有出现问题。
mon51
4楼-- · 2019-12-31 09:23
本帖最后由 mon51 于 2017-3-6 22:33 编辑
lusson 发表于 2017-3-6 15:43
http://www.amobbs.com/thread-5639215-1-1.html
我4楼中也发现有溢出的问题,我估计你多半是地址溢出的问 ...


地址溢出,发现了,改成64位地址也一样,实际上只有寻址超过4G才会出问题。
我现在SD卡是用SPI驱动,是传入扇区地址,不是字节地址:
int8_t STORAGE_Read (uint8_t lun,
                 uint8_t *buf,
                 uint32_t blk_addr,                       
                 uint16_t blk_len){
        int8_t res=0;
        if(lun==SD_K){
                if(blk_len==1){  
                                res = MSD0_ReadSingleBlock(blk_addr , buf );
                        }else{  
                                res = MSD0_ReadMultiBlock(blk_addr ,buf ,blk_len);
                        }
                        if(res) res = -1;
        }
        if(lun==W25_K){
                res = W25QXX_Read_Sector(blk_addr,buf,blk_len);
        }
采用32位地址不会溢出。
int8_t STORAGE_Write (uint8_t lun,
                  uint8_t *buf,
                  uint32_t blk_addr,
                  uint16_t blk_len){
        int8_t res=0;
       
        if(lun==SD_K){
                if(blk_len==1){   
                        res = MSD0_WriteSingleBlock( blk_addr , buf);
                }else{  
                        res = MSD0_WriteMultiBlock( blk_addr , buf , blk_len );
                }                                                
         if(res ) res = -1;
        }
        if(lun==W25_K){
                W25QXX_Erase_Sector(blk_addr,blk_len);
                res = W25QXX_Write_Sector(blk_addr,buf,blk_len);
        }
出问题是:
    MSC_BOT_State = BOT_DATA_IN;
    SCSI_blk_addr *= SCSI_blk_size;
    SCSI_blk_len  *= SCSI_blk_size;
它在:static int8_t SCSI_Read10(uint8_t lun , uint8_t *params) 函数里。


mon51
5楼-- · 2019-12-31 13:11
本帖最后由 mon51 于 2017-3-6 22:42 编辑

int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_size){
        if(lun==SD_K){
                if(MSD_JB_SD_insert()) return -1;
                        //SD_JB_ctrl_Power();
                        //MSD0_Init();
                        //MSD0_GetCardInfo(&SD0_CardInfo);
                        *block_num         = SD0_CardInfo.Capacity / SD0_CardInfo.BlockSize;
                        *block_size         = SD0_CardInfo.BlockSize;
        }
        if(lun==W25_K){
                *block_num =W25QXX_MAX_SECTORS; //FATFS_Get_DISK_Sectors();
                *block_size =  4096;  
        }

读取容量时,*block_num 不会溢出。
myxiaonia
6楼-- · 2019-12-31 17:59
你这是从机吗?其实mdk目录下面有一些相关的例子,包括u盘和sd这些,还有从机可以用103系列的

一周热门 更多>