This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SC Card Example Ported to RTOS returning error RES_ERROR from disk_write()

SDK: 15.2.0

FATfs Example Project: examples\peripheral\fatfs

RTOS Example Project: examples\peripheral\usbd_ble_uart_freertos

Hardware: nRF52840 DK

--------------------------------------------------

I started my current RTOS project using the BLE USBD UART example listed above and ported in the FATfs SD card drivers from the FATfs example listed above. I am simply trying to write a constant value to all sectors on my 8 GB SD card to test the integrity of the entire card. When doing so, I always receive the RES_ERROR return code from disk_write() at a random period of time after starting my test (Could be 10 minutes in or 30 minutes in). Once this occurs, I can no longer re-initialize, read, or write to it unless I power cycle the development board, which also removes and reapplies power to the SD card.

I have run the same test using only the FATfs example without any issues. Note that the barebones FATfs example doesn't include a SoftDevice or RTOS.

So my question is, has anyone successfully ported the FATfs SD card library and drivers from the Nordic example code to a RTOS environment and not had any issues? I realize that the library must be updated to be thread safe and re-entrant, but I am hoping something already exists that I can use before I have to dig into the depths of the FATfs libraries and block device libraries.

Here is the modified SD card example code that I use in both my RTOS project and the barebones FATfs example project:

// Array to map Disk IO return codes to strings
char const * diskio_err_str[] =
{
	"RES_OK",
	"RES_ERROR",
	"RES_WRPRT",
	"RES_NOTRDY",
	"RES_PARERR",
};

/**
 * @brief Function for demonstrating FAFTS usage.
 */
static void fatfs_example()
{
   static FATFS fs;
   static DIR dir;
   static FILINFO fno;
   static FIL file;

   uint32_t bytes_written;
   FRESULT ff_result;
   DSTATUS disk_state = STA_NOINIT;

   // Initialize FATFS disk I/O interface by providing the block device.
   static diskio_blkdev_t drives[] =
   {
         DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)
   };

   diskio_blockdev_register(drives, ARRAY_SIZE(drives));

   NRF_LOG_INFO("Initializing disk 0 (SDC)...");
   for (uint32_t retries = 3; retries && disk_state; --retries)
   {
     disk_state = disk_initialize(0);
   }
   if (disk_state)
   {
     NRF_LOG_INFO("Disk initialization failed.");
     return;
   }

   uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size;
   uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb;
   NRF_LOG_INFO("Capacity: %d MB", capacity);

   uint32_t numSectorsOnDisk = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count;
   static uint8_t buff[SDC_SECTOR_SIZE * 128];
    
    // Loop through all sectors
   for(uint32_t currentSector = 0; currentSector < numSectorsOnDisk; currentSector += 128)
   {
      DRESULT dresult = disk_write(0, buff, currentSector, 128);

      // Abort if any write fails
      if(dresult != RES_OK)
      {
         NRF_LOG_INFO("%s", diskio_err_str[dresult]);
         break;
      }

      if(!(currentSector % 16896))
      {
         NRF_LOG_INFO("Number of blocks remaining: %d", numSectorsOnDisk - currentSector);
      }
   }
}

 

Thanks!

Related