1Features
- Non-blocking sector read/write over SPI + DMA
- Callback on DMA completion via sd_async_poll()
- FatFs layered on top, verified against FAT32
- Async file API: writeFileAsync() / readFileAsync()
- Buffered log writer, appends only on full sectors
- Drops into RTOS or bare-metal projects unchanged
2Specifications
- Target MCU
- STM32F401
- Transport
- SPI + DMA
- File system
- FatFs / FAT32
- Toolchain
- STM32CubeIDE
- Language
- C
3Figure 1 — Board

4Description
This project implements fully non-blocking file operations on an STM32F401 using an SD card. The goal was to support a range of file read/write scenarios in a DMA-based asynchronous architecture, leaving the CPU free for other work.
Sector-level async I/O came first: read_sector_async() and write_sector_async() move single sectors over SPI + DMA, with sd_async_poll() firing callbacks on completion. FatFs was then layered on top and verified against FAT32 for the standard blocking calls — mount, open, read, write, rename and unlink.
On top of that sits an async file API — writeFileAsync() and readFileAsync() — and a log_writer module that buffers log lines and only triggers an append once a full sector is worth of data has accumulated. The result is real-time logging at minimal CPU cost.