本帖最后由 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盘不成功!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
SD卡底层驱动有问题,FATFS操作会出问题。但没有出现问题。
地址溢出,发现了,改成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) 函数里。
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 不会溢出。
一周热门 更多>