|

楼主 |
发表于 2025-2-25 16:48:54
|
显示全部楼层
好吧,看起来是ST的库没有处理仔细,下面注释这行是库里原始的代码,判断<0,则出错,但是read回调返回的数值都是>=0的,这导致下面的
SCSI_SenseCode函数无法执行
if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data,hmsc->scsi_blk_addr,(len / hmsc->scsi_blk_size)) < 0)
修改为如下,读取的时候,返回失败,然后sdmmc去读取,存入缓冲区,下次MSC再读取的时候,就把缓冲区的数据返回给host
if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data,hmsc->scsi_blk_addr,(len / hmsc->scsi_blk_size)) != USBD_OK)
{
SCSI_SenseCode(pdev, lun, NOT_READY, 0x04);
return -1;
}
实测host会反复请求同一个扇区,直到达到重试次数后不再请求,这样第一次请求某扇区时,我返回USB_FAIL,并启动EMMC+DMA去读,CPU此时可以去干别的事(USB中断也完成了--因为已经返回了设备繁忙的标志),等读取完毕,DMA中断,表示数据读取完成,当HOST再次请求同一个扇区的时候,将先前读取的数据返回,并返回USBD_OK,理论上即可实现不阻塞读写数据,但这样可能会损失一点点读写性能,问题不大。。剩下的我再写个代码测试我这想法是否可行就可以了。
返回USBD_FAIL后,日志记录HOST会反复请求同一个扇区:
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
00> USBD_read:p=0x24000010,sec=0,num=1
|
|