Naasif
Naasif

Reputation: 535

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; 

Upvotes: 14

Views: 19965

Answers (1)

David Collins
David Collins

Reputation: 3032

__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).

Upvotes: 27

Related Questions