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!