Hello,
In the demos of the MIMXRT1010 all global variables seem to be preceded by the 'volatile' keyword. And sometimes also the 'static' keyword.
Why is that?
These are global variables, not hard ware registers. And MIMXRT1010 has only one core (demos are written for one core anyway), so no problem if the value stays in cache.
So why are these keywords needed?
I ask this because I like to understand the code. But also when I put these keywords before some of my own global variables (that are structures) and I use a pointer to them, I get warnings like:
../source/sai_interrupt.c:245:27: warning: passing argument 1 of 'xs_biquad_init_LP' discards 'volatile' qualifier from pointer target type [-Wdiscarded-qualifiers]
I could try to solve this, but if 'volatile' is not really needed I also could just skip it.
已解决! 转到解答。
Hi @simmania ,
If "static" is used for global variables, it doesn't mean make the variables "static" or immutable. , the use of "static" is mainly to restrict their scope, making global variables visible only within the file in which they are defined.
BR
mayliu
Hi @simmania ,
Thank you so much for your interest in our products and for using our community.
Question: In the demos of the MIMXRT1010 all global variables seem to be preceded by the 'volatile' keyword. And sometimes also the 'static' keyword. Why is that? These are global variables, not hard ware registers. And MIMXRT1010 has only one core (demos are written for one core anyway), so no problem if the value stays in cache. So why are these keywords needed?
Answer: Please see the explain these two 'volatile' and 'static' keyword
1: "static" keyword: It is used for limiting the scope and maintaining the variable value.
2: "volatile" keyword: Even though the MIMXRT1010 has only one Arm Cortex®-M7 Core, It is still need use "volatile" keyword.
a: The global variables may be changed in interrupt ISR. In this case, "volatile" keyword is needed.
b: As you said these are not hardware registers, but it still need "volatile" keyword, because global variables may be used as an indirect means of interacting with hardware, for example, through memory-mapped I/O ,and so on.
c: If you use FREERTOS or other RTOS , global variables shared with multi tasks, In this case, "volatile" keyword is needed.
Question: I ask this because I like to understand the code. But also when I put these keywords before some of my own global variables (that are structures) and I use a pointer to them, I get warnings.
Answer: It might be because pointer operations do not compatible with the semantic definition of keyword volatile.
Wish it helps you.
If you still have question about it, please kindly let me know.
Best Regards
mayliu
Thanks for the answer.
You say 'static' is used to maintain their value. But the static keyword is used on global variables that are read and written. They are not static at all. That is why it confuses me so much. So what do you main by maintain their value?
You also say that 'volatile' is needed because variables may be changed in interrupt routines or other processes in a RTOS. I do not understand this. What is wrong with changing a variable in some other piece of code. If it is on the same core, using the same cache, what is wrong with that?
Hi @simmania,
'static' for data and functions means that it has 'internal linkage'. So it tells the linker that the static symbol is only part of that compilation unit and cannot be accessed (or linked) from the outside world.
Think about 'static' used to limit the scope for the linking phase.
I recommend that you might have a look at the following article on that subject: https://mcuoneclipse.com/2022/01/01/spilling-the-beans-storage-class-and-linkage-in-c-including-stat...
I hope this helps,
Erich
Hi @simmania ,
Thanks for your update.
1: Regarding the "static" keyword, my previous explanation maybe some misleading.
If "static" is used for global variables, it doesn't mean make the variables "static" or immutable. , the use of "static" is mainly to restrict their scope, making global variables visible only within the file in which they are defined.
If "static" is declared within a function, which retain their value between function calls instead of being reinitialized each time the function is called.
2: Regarding the "volatile" keyword, my reply is that in an RTOS system, even if a variable is accessed on the same core and using the same cache, there is no guarantee that its access will be atomic or free from race conditions.
It is because the compiler and processor maybe optimized your code, resulted in variable reads and writes are not occurring directly in memory but instead using register caching or other optimization techniques. If a other task, ISR changed the variable between when the code reads its value and when it accesses it again, the code may obtain an outdated value.
Using the keyword "volatile" tells the compiler do not to optimize such variables ,and always read their values directly from memory, make sure that the code can correctly obtain the latest state of the variables.
Wish it helps you.
If you still have question about it, please kindly let me know.
Best Regards
mayliu
Hi @mayliu1
Respectfully, I have to disagree 100% with your answer to point 2.
I recommend to have a read at https://mcuoneclipse.com/2021/10/12/spilling-the-beans-volatile-qualifier/ or check the C/C++ language definition for volatile.
'volatile' is appropriate for hardware registers with side effects, as a workaround for compiler bugs, or as a qualifier for assembly code (but not needed there if the compiler is handling it correctly). It 'might' be used in a 'documentation like manner', but never to make code 'work'. If 'volatile' for non-hardware registers is used, this is a sign for bad or wrong code.
If you are using 'volatile' for synchronization (e.g. the FreeRTOS case mentioned) or anything other than hardware registers with side effects, this is clearly wrong. You have to use proper synchronization primitives or correctly using critical sections.
I hope this helps and clarifies this,
Erich
Hi @ErichStyger ,
Thank you so much for your interest in our products and for using our community.
I have read your suggest link, I find this article is based on "atomic".
As I said before, there is no guarantee that its access will be atomic or free from race conditions. It is because the compiler and processor maybe optimized your code, resulted in variable reads and writes not occurring directly in memory but instead using register caching or other optimization techniques.
Wish you a nice day!
BR
mayliu
Hi BR,
'atomic' is a key aspect assessing if something can be reentrant or not. My point is that 'volatile' is a different concept and does not help you in any way with reentrancy or synchronization.
Or in other words: using volatile for anything else than hardware registers is wrong and a programmer error (with few exceptions outlined in the article).
I hope this clarifies it.
Erich
Hi @ErichStyger ,
Thanks for your update information.
I want clarify my point 2 about Keyword "volatile".
I mean the next situation.
For example :// Assuming this is the memory-mapped address of the ADC result register
#define ADC_RESULT_REGISTER ((volatile uint16_t*)0x4XXXXXXX)
//Address is based on your MCU type
// global variable "usadc_result" used to store the ADC result
volatile uint16_t usadc_result;
// This function is used to read the ADC result
uint16_t read_adc_result()
{
// Directly read the value from the ADC result register to a global variable
usadc_result = *ADC_RESULT_REGISTER;
return usadc_result;
}
Wish it helps you.
If you still have question about it, please kindly let me know.
Best Regards
mayliu
Hi @mayliu1 ,
yes, this is a correct usage of volatile:
#define ADC_RESULT_REGISTER ((volatile uint16_t*)0x4XXXXXXX)
Because you are referring here to a hardware register with possible side effects.
But this volatile is wrong and needs to be deleted:
volatile uint16_t usadc_result;
Volatile is not justified here. Moreover, a global variable is not needed in your example, as you have implemented a getter for the ADC result.
I hope that makes it clear.
Hi @simmania ,
If "static" is used for global variables, it doesn't mean make the variables "static" or immutable. , the use of "static" is mainly to restrict their scope, making global variables visible only within the file in which they are defined.
BR
mayliu