Using driver that share DMA streams

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

meatball
Posts: 32
Joined: Thu May 19, 2016 4:39 pm
Has thanked: 9 times
Been thanked: 2 times

Using driver that share DMA streams

Postby meatball » Tue Oct 10, 2017 11:18 pm

Hi, I'm using the F446RE Nucleo for an application.

After many hours of work, I have decided that using two HAL drivers that share a DMA stream on different channels is a bad idea. Is this common knowledge?

I thought there was this "arbiter" that according to the STM32F4 reference manual:

"An arbiter manages the 8 DMA stream requests based on their priority for each of the two AHB master ports (memory and peripheral ports) and launches the peripheral/memory access sequences."

Maybe I have this backwards? The DMA arbitrates between streams that are active, right? Can it arbitrate between different channels on the same stream? The priority is defined by the stream, yeah? So what sort of behavior should I expect for multiple channels requesting access on the same stream?

So, when I use spiSend() when the UARTD4 driver is active in the application, the thread will transfer one byte over SPI and then suspend indefinitely. Seems like a DMA failure, right?

SPI2_tx is on channel 0 of stream 4 on DMA1, and UART4_tx is on channel 4 of the same.

I've found that I simply cannot actively keep both drivers alive at the same time. I must shut one down to use the other. This makes use of SPI2 in one thread difficult to use when UART4 is used in another. The DMA has become some kind of shared resource, for which I cannot control exclusive access.

This seems like a bad thing.

1) Is this common knowledge, and I should look to use a different UART or SPI peripheral? Or is this a HAL limitation? ST limitation?

2) Is this just me not using the HAL correctly? Or am I expecting too much of this micro?

3) Other ways around this? I could have the two threads share use of a mutex to protect the DMA, and prevent both drivers from being used simultaneously, but I just don't want to. Mutexes and semaphores are bugs waiting to happen. I try to stick with synchronous and asynchronous messaging to protect data, and I can usually expect to keep my peripherals up and running the whole time. It seems like a waste of time to re-configure and then shutdown the peripheral every time I use it.

What do you all think? Do you have any suggestions for me?

Am I just being an idiot here? Am I missing something more obvious?

User avatar
Korken
Posts: 270
Joined: Wed Apr 02, 2014 4:09 pm
Location: Luleå, Sweden
Has thanked: 5 times
Been thanked: 6 times
Contact:

Re: Using driver that share DMA streams

Postby Korken » Wed Oct 11, 2017 7:37 am

This is a limitation of the DMA peripheral.

When you setup the DMA, you do it per Stream so (psuedo code):

Code: Select all

DMA1_Stream4->config = USE_CHANNEL_7 | SETTINGS;

This means that you can only set up one Channel at a time per Stream.

If you want to share DMA Streams, one driver may only use a stream at a time.
And sharing must be done through enabling / disabling conflicting drivers.
Or use DMA on one driver, and interrupts on another (if supported by the driver).

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Using driver that share DMA streams

Postby Giovanni » Wed Oct 11, 2017 8:46 am

Drivers can share DMAs even if it is not recommended.

You need to start/stop drivers at runtime, drivers sharing a DMA must never be started at the same time (an assertion is triggered, if assertions are enabled).

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 17 guests