volatile keywordVolatile keyword previously used very little, but in the nRF51822 timer programming, encountered in the following section, combined with the program analysis of the role of volatile keyword.
#include "Nrf51.h" #include "nrf_gpio.h" #include "led.h" #include "time.h" #include <stdbool.h> #include <stdin
T.h>/** * @brief Function for timer initialization.
*/static volatile Nrf_timer_type * Timer_init (timer_t TIMER) {volatile nrf_timer_type * p_timer;
Begins with a MHz crystal oscillator.
nrf_clock->events_hfclkstarted = 0;
Nrf_clock->tasks_hfclkstart = 1;
Wait for the external oscillator to start while (nrf_clock->events_hfclkstarted = 0) {//Do nothing.
Switch (timer) {case timer0:p_timer = Nrf_timer0;
Break
Case Timer1:p_timer = Nrf_timer1;
Break
Case Timer2:p_timer = Nrf_timer2;
Break
Default:p_timer = 0;
Break
return p_timer; /** @brief Function for using the peripheral hardware timers to generate a event after requested number of Millisecon
Ds. * * @param [in] timer timerD for delay, values from @ref p_timer * @param [in] Number_of_ms number of milliseconds the timer would count.
* @note This function would power on the requested timer, wait until the delay, and then power off that timer. */void Nrf_timer_delay_ms (timer_t timer, uint_fast16_t volatile Number_of_ms) {volatile Nrf_timer_type * P_timer =
Timer_init (timer);
if (P_timer = = 0) {while (true) {//Does nothing. } P_timer->mode = Timer_mode_mode_timer; Set to timer mode P_timer->prescaler = 9;
Prescaler 9 produces 31250 Hz timer frequency => 1 tick = us. P_timer->bitmode = Timer_bitmode_bitmode_16bit;
Bit mode. P_timer->tasks_clear = 1;
Clear timer.
With the US ticks, we need to multiply by 31.25 to get milliseconds.
P_TIMER->CC[0] = Number_of_ms * 31; P_timer->cc[0] + = number_of_MS/4; P_timer->tasks_start = 1;
Start timer.
while (p_timer->events_compare[0] = = 0) {//Does nothing.
} P_timer->events_compare[0] = 0; P_timer->tasks_stop = 1;
Stop timer. }
/** @} */
Before you analyze the program, first introduce the volatile keyword. Here is based on the "C language Depth anatomy" of the understanding of the book to write. The meaning of volatile itself is variable and unstable. C language is often compiled to optimize the program, but some special address optimization may be counterproductive (here is only the theory of their own, has not been validated and encountered). Therefore, in the face of the variable declared by this keyword, the compiler will no longer optimize the code that accesses the variable, thus providing a stable access to the particular address. Here are two examples of volatile keyword comparisons.
int i=10;
int j=i; 1 statement
int k=i; 2 statements
At this point the compiler optimizes the code because the variable i is not assigned to the 1 statement and the 2 statement. That is, the value of I has not changed, so the compiler takes the value of I from memory and assigns it to J after 1 statements, which is not discarded, but continues to be assigned to K at the 2 statement. The compiler does not generate the assembly code to fetch the value of I from memory, thus increasing the efficiency. Another example:
volatile int i=10;
int j=i; 3 statement
int k=i; 4 statements
At this point, volatile told the compiler that I was likely to change at any time, and that every time I used it, I had to get the value of I out of memory, so the compiler generated assembly code would again read the data from the address of I and put it in K. If I is a register variable that represents a port data or multiple threads sharing data, it is prone to error, so volatile can guarantee stable access to special addresses.
Summarize:
volatile reminds the compiler that the variables defined later can change at any time, so the compiled program will read the data directly from the variable address each time it needs to store or read the variable. If there is no volatile keyword, the compiler may optimize read and save, may temporarily use the value in the register, if this variable is updated by another program, there will be inconsistencies.
In simple terms, is that the variable you define is always changing in the process, if you want this value to be handled correctly, you need to read the value from memory every time, so there will be no error, volatile keyword is this role. Generally speaking, the volatile keyword is used in several places as follows: 1, the variable which is modified in the Interrupt Service program for other program detection needs to add volatile; 2, the symbol that share among tasks in multi-task environment should add volatile; 3, Memory-mapped hardware registers are usually volatile, so each read and write to it may have different meanings.
Having learned so much about volatile keywords and usage, now to analyze the nRF51822 timer program. In nRF51822, the volatile modifier is used to modify Nrf_timer_type *p_timer the pointer variable of the function, which means that the pointer variable is changeable, and the compiler no longer optimizes when accessing the variable, Instead, read the data directly from the variable address. Here, the program is analyzed according to the running process. When the main function calls the function Nrf_timer_delay_ms (Timer0,timer_delay_ms) (Timer_delay_ms to the macro definition in the header file, 1000UL), the program enters the child function. In this sense the parametric number_of_ms with the volatile modifier is useless, because Timer_delay_ms originally defines a variable for a macro and does not change in the interrupt program or in other cases mentioned above. P_timer this pointer variable is decorated with the volatile modifier, perhaps to avoid other possible conditions to make it change, but the overall feeling is not necessary. be validated after deletion.
Static keywordFirst, let's say the three obvious effects of the static keyword: 1. In the function body, a variable declared as static maintains its value unchanged during the invocation of the function (the variable is stored in the static variable) 2, within the module (but outside the function), A variable declared as static can be accessed by functions used within the module, but not by other functions outside the module, which is a local global variable. 3. Within the module, a function declared as static can only be used by other functions within this module. That is, the function is limited to the local scope of the module in which it is declared.
extern keyword