2019-08-01 03:42 AM
Hi All,
I think SD_write() and SD_read() in sd_diskio.c (see below) have the timer tick overflow bug. For 30 seconds prior to osKernelSysTick() overflowing (every ~49 days), the functions will incorrectly return RES_ERROR without entering the while loop.
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_ERROR;
osEvent event;
uint32_t timer;
if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
(uint32_t) (sector),
count) == MSD_OK)
{
/* Get the message from the queue */
event = osMessageGet(SDQueueID, SD_TIMEOUT);
if (event.status == osEventMessage)
{
if (event.value.v == WRITE_CPLT_MSG)
{
//////////////////////////////////////////
// BAD JUJU
//////////////////////////////////////////
timer = osKernelSysTick() + SD_TIMEOUT;
/* block until SDIO IP is ready or a timeout occur */
while(timer > osKernelSysTick())
{
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
{
res = RES_OK;
break;
}
}
}
}
}
return res;
}
#endif /* _USE_WRITE == 1 */
It can be fixed by doing this:
//////////////////////////////////////////
// GOOD JUJU
//////////////////////////////////////////
timer = osKernelSysTick();
/* block until SDIO IP is ready or a timeout occur */
while((osKernelSysTick() - timer) < SD_TIMEOUT)
{
}
I've only seen the bug in these 2 functions, so hopefully it's not a common occurrence. However, I think it would be wise to check all the other timeout functions.
Cheers,
David
2019-08-01 05:43 AM
>>so hopefully it's not a common occurrence.
You might hope, but I've been digging these types of logic errors out of the code for the best part of a decade.
The first HAL_Delay() implementation had this exact problem.