2025-04-16 8:02 PM
I am using the DMA in a few places. I am wondering should these variables be volatile. As it is, the compiler has no idea when the data will be read from or written into these variables. When that is the case, shouldn't you make the variable volatile? I don't think I have seen them as volatile in the example code however. Am I missing something here?
2025-04-17 1:43 AM
Which "variables", exactly, are you referring to?
As you say, variables which get written-to beyond the compiler's view should be qualified as volatile.
But variables used to control the DMA, or only read-by the DMA - maybe not...
Perhaps provide a concrete example?
2025-04-17 2:29 AM
It depends, I would say.
The buffers itself don't need it, since the (direct) access by DMA is not evaluated by the compiler. It is just triggered by hardware.
When having DMA, I use to configure a TC interrupt, where I set a flag for another routine.
This flag, which is basically a stand-in for the DMA buffer, must be volatile to not be optimized out.
I don't know what Cube code does in this regard, I don't use it.
2025-04-17 3:27 AM
That access to the buffer is the issue. For example, the compiler or MCU can see when you put data into the buffer but has no idea if or when or where that data is coming out. And vice versa when the data flow is in the opposite direction.
2025-04-17 3:42 AM
> The buffers itself don't need it, since the (direct) access by DMA is not evaluated by the compiler. It is just triggered by hardware.
I beg to differ. It's the data in the buffers which are "evaluated" (written or read, for M2P or P2M transfers respectively) by the processor thus compiler (unless the DMA transfers directly from peripheral to peripheral, which IMO is exceedingly rare). If the compiler does not see the program to consume elsewhere data written to the buffer (for M2P) or that there is no other part in the program which writes data to the buffer (for P2M), then the compiler can simply omit the write to/read from the buffer.
> This flag
What flag? There's no link just an underscore.
JW
2025-04-17 3:44 AM
So mark that as volatile.
I don't think compilers tend to cache entire buffers - but qualifying it as volatile shouldn't hurt...
As buffers tend to be accessed via pointers, you'd have to careful about where you put the 'volatile' keyword(s):
volatile char* vpch; // pointer to a volatile char
char* volatile pchv; // volatile pointer to a char
volatile char* volatile vpchv; // volatile pointer to a volatile char
2025-04-17 4:23 AM
>> This flag
> What flag? There's no link just an underscore.
The "flag" variable I use from within the interrupt routine.
Not to be confused with a flag bit in some peripheral register.
I talked about the case when the compiler only sees the buffer values consumed, but not the initial write access (which happens by DMA). I use this method relatively often for asynchronously processing input data. And I never had to mark the DMA buffer as "volatile" to work properly.
2025-04-17 4:28 AM
> I don't think compilers tend to cache entire buffers - ...
Although I'd like to note I did not consider data caches of F7 and H cores in my remarks.
Another aspect to possibly consider.
2025-04-17 5:35 AM - edited 2025-04-17 5:38 AM
To be pedantic the compiler isn't caching. It's just delaying reads and writes. The MCU will do multilevel caching. Both are potential problems. Everything for me is working now but it needs to be right. You never know when conditions are correct to enable some new optimization on any given compiler execution. And it doesn't need to do it to the whole buffer. Just one byte will cause a fail.
2025-04-17 5:37 AM - edited 2025-04-17 6:49 AM
@Carl_G wrote:To be pedantic the compiler isn't caching.
You're right - that was poor terminology on my part.
PS:
Or was it?
A commonly-given example is where a piece of code makes multiple reads of a variable:
Instead of actually reading from memory each time, the compiler might optimise by reading once into a register, and using that.
Which is, surely, a form of "caching" ?
But, indeed, distinct from hardware caching.