What is the use of __IO & static keywords in C?

I was checking out some code written for STM32F microcontroller and I found these keywords used before initializing a variable. I would like to know what is the significance of using this "__IO" & "static" keywords?

The line of code was given like that:

static __IO uint32_t sysTickCounter; 
9

1 Answer

__IO / volatile

__IO is not a C keyword. __IO is a macro for volatile - defined in STM32 standard peripheral library header files. E.g., in core_cm4.h (might be in a CMSIS sub-folder), you will find

#define __IO volatile

(If you use gcc's -E option to use only the pre-processor stage, you can see the macro's expansion.)

The volatile keyword, in turn, is often applied to a variable to prevent the compiler from 'optimizing it out'. This is useful in embedded systems - where a variable might be used within an interrupt - and compiler optimizations could cause problems.

Short example ...

int main(void) { int ms = 0; ms++; while (1); return 0;
}

Here is the generated assembly (using sdcc compiler for PIC12f629 target). As you can see, the ms variable has been 'optimized out'.

_main:
; 2 exit points
_00113_DS_:
; .line 18; "main.c" while (1) GOTO _00113_DS_ RETURN
; exit point of _main

If, on the other hand, we declare the variable as volatile ...

volatile int ms = 0;
ms++;
// etc.

the relevant instructions are preserved:

_main:
; 2 exit points
; .line 16; "main.c" volatile int ms = 0; CLRF _main_ms_1_5 CLRF (_main_ms_1_5 + 1)
; .line 19; "main.c" ms++; INCF _main_ms_1_5,F BTFSC STATUS,2 INCF (_main_ms_1_5 + 1),F
_00113_DS_:
; .line 21; "main.c" while (1) GOTO _00113_DS_ RETURN
; exit point of _main

static

The effect of the static keyword depends on the scope in which the variable is declared.

  • file scope - the variable's scope is limited to the current compilation unit (usually a file plus its #included header files).
  • block scope (e.g. within a function) - The variable is preserved in memory for the duration of the program. (For a function, this means that the value of the variable is preserved between subsequent calls to the function.)

Notes

  • As vlk pointed out in a comment, another important use of volatile is for accessing peripheral registers (although you would use a pointer in that case).
14

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like