A group friend asked a question in the group: In FreeRTOS, a high-priority task changed the value of a global variable, while a low-priority task was waiting in a loop for the value to change; why did the low-priority task not exit the loop and continue execution after the high-priority task changed the value?
Code in the high-priority task that modifies the global variable:
if(1000 <= Complete)
{
update_flag = 1;
printf("update_flag = [%d]\n", update_flag);
}
vTaskDelay(10);
Code in the low-priority task that checks the global variable:
while(!update_flag); // Check
Do you know why the while() in the low-priority task does not exit?
If you thought of the keyword volatile, then congratulations, you have truly understood this keyword.
Tell this friend to add volatile when defining the global variable. The problem is solved. All is well.
Clearly, to confirm our guess, we will analyze step by step.
First, check the project configuration to see if compiler optimization is enabled, as shown in the figure below:
This project has enabled level one optimization. This explains it; the compiler has optimization enabled, and the variable definition did not add the keyword volatile. These two factors combined lead to the problem.
After enabling optimization, the compiler assumes that no one will modify update_flag during the loop. Since update_flag is not modified, and its initial value is 0, then update_flag is a value that will not change, resulting in an infinite loop!
Clearly, the compiler does not know that the high-priority task will modify the value of update_flag.
So, in this case, the programmer needs to explicitly tell the compiler that update_flag is a value that can change, so do not attempt such optimizations. This is the role of the volatile keyword.
Note: volatile only affects the compile phase and has no effect on the runtime phase.
This friend said that if some code is added in the low-priority code, the execution result can be normal (the variable definition did not add volatile):
while(!update_flag)
{
printf("update_flag = [%d]\n", update_flag);
vTaskDelay(10);
}
Based on previous analysis, in this added code, the while() loop has other code reading this variable, so the compiled code will read its value from memory again.
Some friends may ask, should multiple tasks based on RTOS use mutexes to protect access to global variables?
To put it simply, if multiple tasks will modify the same global variable, then it is necessary to protect it with a mutex to prevent the variable’s value from becoming inconsistent. However, in this case, only one task modifies the variable while another task only reads it, so there is no issue of global variable value confusion.
Source: Learning Embedded Together
Due to recent changes in the WeChat public platform push rules, many readers have reported not seeing the updated articles in time. According to the latest rules, it is recommended to click on “Recommended Reading, Share, Favorite,” etc., to become a regular reader.
Recommended Reading:
-
Just now, another new energy vehicle company was applied for bankruptcy!
-
A certain company’s internship salary is only 300 yuan, causing it to trend!
-
Big move! Huawei established a new company with 870 million, suspected to enter a new field
Please click 【See】 to give the editor a thumbs up