使用keil5编译stm32,头文件core_cmFunc.h中,是预定义__CC_ARM,还是__GNUC__?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用keil5编译stm32,头文件core_cmFunc.h中,是预定义__CC_ARM,还是__GNUC__?相关的知识,希望对你有一定的参考价值。

如题,在core_cmFunc.h文件中,
#if defined ( __CC_ARM )
...
#elif defined ( __GNUC__ )
...
其中,__disable_irq();是定义在( __GNUC__ )下的,为什么用keil编译时,调用不会出现问题?

编译的时候,可能是那个地方定义了__CC_ARM, 预编译指令执行了#if defined ( __CC_ARM )下面的代码,没有执行#elif defined ( __GNUC__ )下面的代码;

#if ...
...
#elif ..
...
是条件预编译,只执行其中的一个分支追问

只执行一个分支是对的,问题是keil自带时armcc编译器,但是调用的是gcc下的函数。

追答

#if .. #elif是预编译指令,就是说在正式编译之前进行一遍,把没有用的分支代码忽略了,正式编译时,只编译__CC_ARM分支的代码,其它分支的代码没有参与编译,当然也不会出错

参考技术A 因为这个头文件将他们都包容了进来。

STM32-固件库

CMSIS标准及库层次关系

技术图片

库目录、文件简介

技术图片
技术图片
我们写 STM32F4 的工程,必须用到其中的四个文件: core_cm4.h、 core_cmFunc.h、corecmInstr.h、 core_cmSimd.h,其它的文件是属于其它内核的,还有几个文件是 DSP 函数
库使用的头文件。
core_cm4.c 文件有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异。里面包含了一些跟编译器相关的信息,如: “__CC_ARM ” (本书采用的 RVMDK、 KEIL),“GNUC ” (GNU 编译器)、“ICC Compiler” (IAR 编译器)。 这些不同的编译器对于C 嵌入汇编或内联函数关键字的语法不一样,这段代码统一使用“__ASM、 __INLINE”宏来定义,而在不同的编译器下,宏自动更改到相应的值,实现了差异屏蔽。在 core_cm4.c 文件中包含了stdint.h头文件,ANSI C 文件,是独立于处理器之外的,提供一些类型定义。这些新类型定义屏蔽了在不同芯片平台时,出现的诸如 int 的大小是 16 位,还是 32 位的差异。所以在我们以后的程序中,都将使用新类型如 uint8_t 、 uint16_t 等。
在 ST 标准库的函数中,一般会包含输入参数检查,即上述代码中的“assert_param”宏,当参数不符合要求时,会调用“assert_failed”函数,这个函数默认是空的。实际开发中使用断言时,先通过定义 USE_FULL_ASSERT 宏来使能断言,然后定义“assert_failed”函数,通常我们会让它调用 printf 函数输出错误说明。 使能断言后,程序运行时会检查函数的输入参数,当软件经过测试,可发布时, 会取消 USE_FULL_ASSERT宏来去掉断言功能, 使程序全速运行

库文件间的关系

技术图片

使用帮助文档

以上是关于使用keil5编译stm32,头文件core_cmFunc.h中,是预定义__CC_ARM,还是__GNUC__?的主要内容,如果未能解决你的问题,请参考以下文章

STM32的keil移植到IAR的问题。

Keil5包含头文件

如何使用keil5将stm32的hal库编译成lib文件——F1版本

Keil5 STM32 C++开发 ARM V6编译器的使用教程

"IRQn_Type" is undefined

最近刚入门stm32 我按原子教你玩stm32 用keil mdk5 直接用它给的文件创建工程,一直出错