嵌入式开发中那些编译器宏定义
前言
在嵌入式开发中,我们绕不过去交叉编译开发环境。在嵌入式Linux系统下,似乎我们只有GCC可选。但对于我们MCU的编译来说,如STM32,工具链(Tool Chain)可选就比较多了。我们常常使用的Keil MDK编译器,现在已经是ARM公司官方的编译工具了,还有现在对国内用户不是特别好的IAR,另外,还有现在开源与免授权费的GNU GCC编译工具,其占有率也逐渐上升。
今天不是给大家介绍这三大家的编译工具链,而说说在软件开发时,我们在程序上如何兼容这三个主流的编译工具链。
编译器宏定义
在软件编写上面如何区分不同的编译工具链?毕竟好多关键字还是不兼容的。答案就是通过编译器宏定义来区分。
我们首先引用一段core_cm3.h的内容:
#if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif #endif
上面这段代码是在头文件里面检查浮点数运算的预定义。我们可以看到针对不同的工具链,我们需要定义不同的标识符。
看上代码也不复杂,自然也没有啥难度!——只是代码的平铺嘛!下面我们来讲解各个编译器宏定义都是哪家专有的。
__CC_ARM,代表由ARM公司提供的编译器;
__ICCARM__,代表由IAR Systems提供的编译器;
__GNUC__,则代表由GNU项目提供的开源编译器;
总结
上面提到的这三大工具链全部支持Cortex-M系列处理器的编译开发,我们通过预处理宏来定义特定的关键字,也方便开发者能够更容易地在不同的编译环境中编写和维护代码。
不过,如果我定了使用Keil MDK来编写我的代码,我不会再兼容其它编译工具链的。