C 全局在 ISR 中声明
C Global declared in ISR
我正在评估飞思卡尔的 Kinetis Design Studio 的 ARM 系列微控制器。我正在寻找 example 作为我第一个 "blink an LED" 项目的基础。当使用在我的主程序和 ISR(例如计数器)之间共享的变量时,我通常会在 main.c 中定义一个 volatile 全局变量,并在 ISR 中将其引用为 extern。他们的例子恰恰相反,他们也不使用 volatile 关键字。我从未见过这样做的。这有什么好处吗?顺便说一句,无论哪种方式,我的程序都可以正常工作。
我不知道codewarrior套件。但是,一般来说,volatile
告诉编译器变量在程序代码给出的正常控制流之外发生了变化。
从历史上看,嵌入式编译器对不使用 'volatile' and/or 相当宽容,实施了一些策略来支持不了解优化和 "forgot" volatile
的缺乏经验的程序员。然而,这将导致代码优化不佳,特别是对于 ARM 平台(对于 HC08&Co MCU 来说问题不大,无论如何都必须从内存中加载每个变量)。
虽然 CW 可能仍然那么宽容,但像 gcc 这样高度优化代码的编译器并不那么宽容并且优化得更加激进。例如,如果您忘记了 volatile
或此类编译器的障碍,您最终可能会得到一个空的主循环。
即使如果您的代码目前运行良好,一旦启用优化或更改次要(可能不相关)方面,这可能会改变。
一位长期嵌入式开发人员的忠告非常好:使用 volatile
。稀疏地使用它并经过深思熟虑(可以找到更多详细信息),但要使用它!
缺少 volatile
是一个错误(albeit a common one) that itself should be a quality warning. The choice of where to instantiate a global is arbitrary, but from a cohesion point of view, it makes sense to keep data that relates to the interrupt with the interrupt. That said, the use of the global data 本身就是质量和做法可疑的迹象。
一个更好的利用数据封装的模式是:
interrupt.c
...
volatile static int counter = 0 ;
void interruptHandler()
{
counter++ ;
}
int interruptCounter{ return counter } ;
...
interrupt.h
...
extern int interruptCounter() ;
...
main.c
#include "interrupt.h"
...
int icount = interruptCount() ;
...
我正在评估飞思卡尔的 Kinetis Design Studio 的 ARM 系列微控制器。我正在寻找 example 作为我第一个 "blink an LED" 项目的基础。当使用在我的主程序和 ISR(例如计数器)之间共享的变量时,我通常会在 main.c 中定义一个 volatile 全局变量,并在 ISR 中将其引用为 extern。他们的例子恰恰相反,他们也不使用 volatile 关键字。我从未见过这样做的。这有什么好处吗?顺便说一句,无论哪种方式,我的程序都可以正常工作。
我不知道codewarrior套件。但是,一般来说,volatile
告诉编译器变量在程序代码给出的正常控制流之外发生了变化。
从历史上看,嵌入式编译器对不使用 'volatile' and/or 相当宽容,实施了一些策略来支持不了解优化和 "forgot" volatile
的缺乏经验的程序员。然而,这将导致代码优化不佳,特别是对于 ARM 平台(对于 HC08&Co MCU 来说问题不大,无论如何都必须从内存中加载每个变量)。
虽然 CW 可能仍然那么宽容,但像 gcc 这样高度优化代码的编译器并不那么宽容并且优化得更加激进。例如,如果您忘记了 volatile
或此类编译器的障碍,您最终可能会得到一个空的主循环。
即使如果您的代码目前运行良好,一旦启用优化或更改次要(可能不相关)方面,这可能会改变。
一位长期嵌入式开发人员的忠告非常好:使用 volatile
。稀疏地使用它并经过深思熟虑(可以找到更多详细信息
缺少 volatile
是一个错误(albeit a common one) that itself should be a quality warning. The choice of where to instantiate a global is arbitrary, but from a cohesion point of view, it makes sense to keep data that relates to the interrupt with the interrupt. That said, the use of the global data 本身就是质量和做法可疑的迹象。
一个更好的利用数据封装的模式是:
interrupt.c
...
volatile static int counter = 0 ;
void interruptHandler()
{
counter++ ;
}
int interruptCounter{ return counter } ;
...
interrupt.h
...
extern int interruptCounter() ;
...
main.c
#include "interrupt.h"
...
int icount = interruptCount() ;
...