AnsweredAssumed Answered

CubeMX SD_status with FreeRTOS not reentrant

Question asked by Rick Sladkey on Mar 10, 2018

The follow code snippet is generated in sd_diskio.c by CubeMX (4.24.0) when using FreeRTOS (STM32Cube_FW_F7_V1.9.0):


  * @brief  Gets Disk Status
  * @param  lun : not used
  * @retval DSTATUS: Operation status

DSTATUS SD_status(BYTE lun)
  return SD_CheckStatus(lun);


and SD_status is passed to FatFs as the disk_status function. Internally FatFs uses a semaphore to prevent reentrant filesystem API calls to the same drive, but the disk_status function is called BEFORE the lock is acquired. As a result, when FatFs is used with FreeRTOS with the SD card as the disk subsystem, the SD_status function may easily be called by one task while another task is the middle of a FatFs API call and actively performing a disk operation.


The upshot is that SD_status must be reentrant, but calls to the SD_CheckStatus function have to be serialized and so SD_status may wrongly return STA_NOINIT because an I/O operation is in progress. In other words, it's fine that SD disk operation is in progress; the disk_status function just wants to know if the SD card is "ok".


The workaround is to modify SD_status in the preceding user block as follows:


// Workaround for non-thread-safe version of SD_status implemented below.
// FatFs calls SD_status (via disk_status if ff.c) BEFORE it locks the
// file pointer. As a result, SD_status must be reentrant. For our purposes,
// FatFs only checks for STA_NOINIT and this cannot change after successful
// initialization unless the media is removed.
// See:

DSTATUS SD_status(BYTE lun)
  return Stat;

#define SD_status SD_status_not_thread_safe