|
1、单独使用FatFs操作eMMC能够成功(IDMA也能够成功)
2、单独使用USB擦偶作eMMC也能够成功(IDMA也能够成功)
3、同时使用USB和FatFs操作会失败,读取eMMC失败
4、使用FreeRTOS信号量互斥后依然会失败
读取eMMC的代码如下:
DRESULT USER_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
/* USER CODE BEGIN READ */
DRESULT res = RES_ERROR;
BYTE *addr = buff;
uint32_t addrValue = (uint32_t)addr;
osEvent event;
uint32_t timer;
uint8_t IsDMASpace;
if(addrValue > (0x24000000UL + 1024*512) || addrValue < 0x24000000UL) /* 非 DMA地址区间 */
{
if(BSP_MMC_ReadBlocks_DMA((uint32_t*)scratch, (uint32_t)sector, count) == MMC_OK)
{
res = RES_OK;
IsDMASpace = 0;
}
else
{
res = RES_ERROR;
}
}
else
{
if(BSP_MMC_ReadBlocks_DMA((uint32_t*)buff,(uint32_t) (sector),count) == MMC_OK)
{
res = RES_OK;
IsDMASpace = 1;
}
else
{
res = RES_ERROR;
}
}
if(res == RES_OK)
{
res = RES_ERROR;
timer = osKernelSysTick() + SD_TIMEOUT;
while(timer > osKernelSysTick())
{
event = osMessageGet(SDQueueIDRead, SD_TIMEOUT);
if (event.status == osEventMessage && event.value.v == READ_CPLT_MSG)
{
timer = osKernelSysTick() + SD_TIMEOUT;
while(timer > osKernelSysTick())
{
if(BSP_MMC_GetCardState() == MMC_TRANSFER_OK)
{
res = RES_OK;
if(IsDMASpace)
{
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
uint32_t alignedAddr;
/*
the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
adjust the address and the D-Cache size to invalidate accordingly.
*/
alignedAddr = (uint32_t)buff & ~0x1F;
SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
#endif
break;
}
else
{
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
uint32_t alignedAddr;
/*
*
* invalidate the scratch buffer before the next read to get the actual data instead of the cached one
*/
alignedAddr = (uint32_t)scratch & ~0x1F;
SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)scratch - alignedAddr));
#endif
memcpy(buff, scratch, count*BLOCKSIZE);
break;
}
}
}
break;
}
}
}
return res;
/* USER CODE END READ */
}
FatFs操作时的互斥代码如下:
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
xSemaphoreTake(MMCReadMutex, portMAX_DELAY);
res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
xSemaphoreGive(MMCReadMutex);
return res;
}
USB操作eMMC的代码如下:
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
int8_t ret = USBD_FAIL;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
BaseType_t status = xSemaphoreTakeFromISR(MMCReadMutex, &xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken==pdTRUE)
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
if(status !=pdTRUE)
return (USBD_FAIL);
if(USER_read(lun,buf,blk_addr,blk_len) == RES_OK)
{
ret = USBD_OK;
}
else
{
ret = USBD_FAIL;
}
xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(MMCReadMutex, &xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken==pdTRUE)
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
return ret;
/* USER CODE END 6 */
}
请问有朋友做过文件系统和USB模拟U盘的互斥吗?
|
|