Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


FatFS disk_read() / disk_write() DMA STM32

Posted by Luke Peterson on May 24, 2012
I am using a STM32 Cortex-M3 and just recently got FatFS up and running with a SD card in SPI mode. I would like to modify the disk_read() and disk_write() functions to use DMA transfers. I understand how to use the DMA peripherals to transfer the data, and how to enable the DMA interrupts so they are triggered when the transfer is complete.

How should I ensure that the disk_read() / disk_write() functions don't try to trigger another DMA transfer when one is already taking place?

I have read the user manual and searched the forums and it seems like what I need to do is to use a binary semaphore (vSemaphoreCreateBinary()). Then in the beginning of the disk_read()/disk_write() functions, I would call xSemaphoreTake(). Once this returns, I can safely start a DMA transfer. Then, in the DMA interrupt, if the transfer is complete, I would call xSemaphoreGiveFromISR().

I was thinking that I would implement the DMA Interrupt directly in the diskio.c file (where disk_read()/disk_write() ) are implemented, and make the semaphore have file scope so that only disk_read()/disk_write() and the interrupt can touch the semaphore.

Does this seem reasonable? Is there a better/different approach?

The disk_read()/disk_write() functions are called from higher level FatFS functions such as f_read()/f_write(), which themselves would be called from various tasks in my project. Are there any requirements on the implementation of disk_read()/disk_write() to make sure this all works properly? I think they currently both access a variable that is at file scope (disk_status) in diskio.c, will this cause any issues?

Thank you,

RE: FatFS disk_read() / disk_write() DMA STM32

Posted by Nathan Wiebe on May 24, 2012
Using a non-mutex semaphore does leave you open to priority inversion. For example, if a low priority thread grabs the semaphore and is about to start the DMA transfer, a high priority thread could wake up and need the file system, meanwhile a long-running medium priority thread could block the low priority thread, halting the high-priority thread for an indefinite amount of time. Unfortunately (and I could be wrong), I don't think mutex's can be released from an ISR in FreeRTOS.

What you could do is use a mutex to wrap all in-thread access up to and including the DMA transfer initialization, and release it once the DMA transfer has started and the interrupt is now imminent. You would then also use a binary semaphore that you would take once inside the mutex, and it can be released from the ISR, thus waking up threads waiting on the DMA. This way the low-priority thread would priority inherit from any thread needing the file system until the DMA transfer is started and the sequence has been passed off to the interrupt.

I'm not familiar with FatFS, but if it isn't designed to be thread-safe, then you will want to scour the code for globals and statics, as well as use of non-synced resources like malloc/free and sometimes other compiler-specific clib stuff. Also keep in mind that you might want to do more than just sync the shared resources. You may want to also have a file-specific lock list/table to ensure that a given file isn't opened more than once for write access, read+write, etc.

RE: FatFS disk_read() / disk_write() DMA STM32

Posted by Luke Peterson on May 24, 2012
Thanks for the reply. I am pretty new to all this stuff but I think I understand what you mean about the priority inversion issue. While I don't anticipate having more than one task need to use the FatFS calls, it would be nice to know how to do this properly so that if/when I do have that need, I can safely do it.

If I understand the FreeRTOS documentation correctly, mutex's in FreeRTOS are just special kind of semaphore (created with xSemaphoreCreateMutex()), which have the same actual type as binary semaphore (xSemaphoreHandle). According to the documentation for xSemaphoreGiveFromISR(), all semaphore types except for recursive semaphores can be 'given' from ISR's with this function.

Does this imply that the situation you described which uses a mutex and a binary semaphore could effectively be simplified to just a mutex and acheive the same result?

RE: FatFS disk_read() / disk_write() DMA STM32

Posted by Richard on May 24, 2012
There is an example FatFS driver here:


It uses interrupt driven input and output. Task accessing the SPI port performs an operation then blocks on a semaphore to know when the operation is complete. The interrupt service routine simply gives the semaphore to indicate that it is safe for the next operation to commence. You are describing a system that works in exactly the same way, except the DMA is used to control the IO so you would use the DMA interrupt rather than the SPI interrupt.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists