__IO 和 C 中的 static 关键字有什么用?
What is the use of __IO & static keywords in C?
我正在检查为 STM32F 微控制器编写的一些代码,我发现在初始化变量之前使用了这些关键字。我想知道使用这个“__IO” & “static”关键字有什么意义?
代码行是这样给出的:
static __IO uint32_t sysTickCounter;
__IO
/ volatile
__IO
不是 C 关键字。 __IO
是volatile
的一个宏——定义在STM32标准外设库头文件中。例如,在 core_cm4.h
中(可能在 CMSIS
子文件夹中),您会发现
#define __IO volatile
(如果你使用gcc
的-E
选项只使用预处理器阶段,你可以看到宏的扩展。)
volatile
关键字通常应用于变量以防止编译器 'optimizing it out'。这在嵌入式系统中很有用 - 其中可能会在中断中使用变量 - 编译器优化可能会导致问题。
简短示例...
int main(void) {
int ms = 0;
ms++;
while (1);
return 0;
}
这是生成的程序集(针对 PIC12f629 目标使用 sdcc
编译器)。如您所见,ms
变量已 'optimized out'.
_main:
; 2 exit points
_00113_DS_:
; .line 18; "main.c" while (1)
GOTO _00113_DS_
RETURN
; exit point of _main
另一方面,如果我们将变量声明为 volatile
...
volatile int ms = 0;
ms++;
// etc.
保留相关说明:
_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
static
关键字的效果取决于声明变量的范围。
- 文件范围 - 变量的范围限于当前编译单元(通常是一个文件及其
#include
d 个头文件)。
- block scope(例如,在一个函数中)——变量在程序运行期间保存在内存中。 (对于一个函数,这意味着变量的值在函数的后续调用之间被保留。)
备注
- 正如 vlk 在评论中指出的那样,
volatile
的另一个重要用途是访问外围寄存器(尽管在这种情况下您会使用指针)。
我正在检查为 STM32F 微控制器编写的一些代码,我发现在初始化变量之前使用了这些关键字。我想知道使用这个“__IO” & “static”关键字有什么意义?
代码行是这样给出的:
static __IO uint32_t sysTickCounter;
__IO
/ volatile
__IO
不是 C 关键字。 __IO
是volatile
的一个宏——定义在STM32标准外设库头文件中。例如,在 core_cm4.h
中(可能在 CMSIS
子文件夹中),您会发现
#define __IO volatile
(如果你使用gcc
的-E
选项只使用预处理器阶段,你可以看到宏的扩展。)
volatile
关键字通常应用于变量以防止编译器 'optimizing it out'。这在嵌入式系统中很有用 - 其中可能会在中断中使用变量 - 编译器优化可能会导致问题。
简短示例...
int main(void) {
int ms = 0;
ms++;
while (1);
return 0;
}
这是生成的程序集(针对 PIC12f629 目标使用 sdcc
编译器)。如您所见,ms
变量已 'optimized out'.
_main:
; 2 exit points
_00113_DS_:
; .line 18; "main.c" while (1)
GOTO _00113_DS_
RETURN
; exit point of _main
另一方面,如果我们将变量声明为 volatile
...
volatile int ms = 0;
ms++;
// etc.
保留相关说明:
_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
static
关键字的效果取决于声明变量的范围。
- 文件范围 - 变量的范围限于当前编译单元(通常是一个文件及其
#include
d 个头文件)。 - block scope(例如,在一个函数中)——变量在程序运行期间保存在内存中。 (对于一个函数,这意味着变量的值在函数的后续调用之间被保留。)
备注
- 正如 vlk 在评论中指出的那样,
volatile
的另一个重要用途是访问外围寄存器(尽管在这种情况下您会使用指针)。