[Techblog] Supporting high speed writing on SD card for Nuttx
Basic implementation
The official Youtube channel shows an example of simple usage of SD card on Nuttx.
The steps for menuconfig
can be summarized as:
System Type → STM32 Peripheral Support
, checkSDIO
System Type → SDIO Configuration
, checkEnable internal Pull-Ups
RTOS Features → Work queue support
, checkHigh priority (kernel) worker thread
RTOS Features → RTOS hooks
, checkCustom board late initialization
Device Drivers
, checkMMC/SD Driver Support
, inside which, checkEnable MMC/SD ioctl support
,MMC cards support
,MMC/SD card detect pin
,MMC/SD SDIO transfer support
, uncheckMMC/SD write protect pin
,MMC/SD SPI transfer support
.File Systems
, checkFAT file system
, checkFAT upper/lower names
,FAT long file names
Then the SD card can be mounted using mount -t vfat /dev/mmcsd0 /mnt/fs
.
I failed to mount the SD card in the first place, it turns out the card should be DOS
partition table, not GPT
with the configs shown above.
However
Everything worked perfectly untill I tried writting data with a bit high speed (100KB/s) to the SD card.
In order to increase the writting performance on a SD card, write chunk buffer is required. In short, you have to stack your data untill its size is large enough (chunk size) then write them to the SD card at once (using posix write/fwrite function). And the time comsumed by every write operation won't increase significantly as the chunk size
grows from 128 to 1024. Thus in general, larger chunk size would boost the write performance with SD card.
I was happy that I can get around 20KB/s to my Sandisk Class10 SD card with 512 chunk size (the same size of a single FAT block). However, as I further increased the chunk size to 4096, nothing was actually stored on the SD card. With investigation into the Nuttx code, I found the error arised at stm32_sdio.c
:
ERROR: Data block CRC failure, remaining: 0
The short story is that, single block is fine (less than 512 chunk size), however, multiple block write with one transfer fails with CRC check error.
It took almost 3 days before I was about to giveup the task, then the problem was solved. I compared my configurations carefully with PX4 flight controller's, as my pixhawk log perfectly with the same SD Card. It seems that, in addition to the Youtube SD card guide, some further configs need to be done:
To support multiple block write in a single transfer:
Device Drivers → MMC/SD Driver Support
, check Use D0 Busy to detect Write Complete
and SDIO block setup