MDK-ARMarmcc编译器――预定义宏(精)

合集下载

常见ARM编译器简介

常见ARM编译器简介

常见ARM编译器简介ARM应用软件的开发工具根据功能的不同,分别有编译软件、汇编软件、链接软件、调试软件、嵌入式实时操作系统、函数库、评估板、JTAG仿真器、在线仿真器等,目前世界上约有四十多家公司提供以上不同类别的产品。

用户选用ARM处理器开发嵌入式系统时,选择合适的开发工具可以加快开发进度,节省开发成本。

因此一套含有编辑软件、编译软件、汇编软件、链接软件、调试软件、工程管理及函数库的集成开发环境(IDE)一般来说是必不可少的,至于嵌入式实时操作系统、评估板等其他开发工具则可以根据应用软件规模和开发计划选用。

使用集成开发环境开发基于ARM的应用软件,包括编辑、编译、汇编、链接等工作全部在PC机上即可完成,调试工作则需要配合其他的模块或产品方可完成。

(一)SDTARM SDT的英文全称是ARM Software Development Kit,是ARM公司(为方便用户在ARM芯片上进行应用软件开发而推出的一整套集成开发工具。

ARM SDT经过ARM公司逐年的维护和更新,目前的最新版本是2.5.2,但从版本2.5.1开始,ARM公司宣布推出一套新的集成开发工具ARM ADS1.0,取ARM SDT而代之,今后将不会再看到ARM SDT的新版本。

ARM SDT由于价格适中,同时经过长期的推广和普及,目前拥有最广泛的ARM软件开发用户群体,也被相当多的ARM公司的第三方开发工具合作伙伴集成在自己的产品中,比如美国EPI公司的JEENI仿真器。

ARM SDT(以下关于ARM SDT的描述均是以版本 2.50为对象)可在Windows95、98、NT以及Solaris2.5/2.6、HP-UX10上运行,支持最高到ARM9(含ARM9)的所有ARM处理器芯片的开发,包括StrongARM。

ARM SDT包括一套完整的应用软件开发工具:*armcc ARM的C编译器,具有优化功能,兼容于ANSI C。

*tcc THUMB的C编译器,同样具有优化功能,兼容于ANSI C。

编译器预定义的宏(可以用来区分使用的是哪种编译器)

编译器预定义的宏(可以用来区分使用的是哪种编译器)

一、介绍预定义宏"_MSC_VER"1、_MSC_VER是微软C/C++编译器——cl.exe编译代码时预定义的一个宏。

需要针对cl编写代码时,可以使用该宏进行条件编译。

2、_MSC_VER的值表示cl的版本。

需要针对cl特定版本编写代码时,也可以使用该宏进行条件编译。

3、_MSC_VER的类型是"int",具体版本号定义如下:MS VC++ 9.0 _MSC_VER = 1500MS VC++ 8.0 _MSC_VER = 1400MS VC++ 7.1 _MSC_VER = 1310MS VC++ 7.0 _MSC_VER = 1300MS VC++ 6.0 _MSC_VER = 1200MS VC++ 5.0 _MSC_VER = 1100其中MS VC++ 9.0就是Visual C++ 2008,MS VC++ 8.0就是Visual C++ 2005。

二、介绍预定义宏“__GNUC__”1、__GNUC__ 是gcc编译器编译代码时预定义的一个宏。

需要针对gcc编写代码时,可以使用该宏进行条件编译。

2、__GNUC__ 的值表示gcc的版本。

需要针对gcc特定版本编写代码时,也可以使用该宏进行条件编译。

3、__GNUC__ 的类型是“int”三、预定义宏"__MINGW32__"1、MinGW编译器四、symbian sdk预定义宏:symbian平台,定义"__SYMBIAN32_"3rd MR版及之前的那个3rd版本,定义"__SERIES60_30__"3rd FP1版,定义"__SERIES60_31__"3rd FP2版,定义"__SERIES60_32__"另外,还有一个"__SERIES60_3x__"。

若不需区分具体是哪一个3rd版,则用之。

gcc中预定义的宏__GNUC__

gcc中预定义的宏__GNUC__

gcc中预定义的宏__GNUC__今天在看Linux系统编程这本书的代码的时候看到了__GNUC__,不太清楚这个宏所以去查了⼀下,以此记录。

GNU C预定义了⼀系列的宏,这些宏都是以双下划线开始的,这⾥只讲⼀下__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__,其他GNU C的预定义宏可以到这⾥查看:__GNUC__ 、__GNUC_MINOR__ 、__GNUC_PATCHLEVEL__分别代表gcc的主版本号,次版本号,修正版本号。

这⾥引⽤⼀下上⾯的官⽅说明:__GNUC____GNUC_MINOR____GNUC_PATCHLEVEL__These macros are defined by all GNU compilers that use the C preprocessor: C, C++, Objective-C and Fortran. Their values are the major version, minor version, and patch level of the compiler, as integer constants. For example, GCC 3.2.1 will define __GNUC__ to3, __GNUC_MINOR__ to 2, and __GNUC_PATCHLEVEL__ to 1. These macros are also defined if you invoke the preprocessor directly.__GNUC_PATCHLEVEL__ is new to GCC 3.0; it is also present in the widely-used development snapshots leading up to 3.0 (which identify themselves as GCC 2.96 or 2.97, depending on which snapshot you have).If all you need to know is whether or not your program is being compiled by GCC, or a non-GCC compiler that claims to accept the GNU C dialects, you can simply test __GNUC__. If you need to write code which depends on a specific version, you must be more careful. Each time the minor version is increased, the patch level is reset to zero; each time the major version is increased (which happens rarely), the minor version and patch level are reset. If you wish to use the predefined macros directly in the conditional, you will need to write it like this:/* Test for GCC > 3.2.0 */#if __GNUC__ > 3 || \(__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \(__GNUC_MINOR__ == 2 && \__GNUC_PATCHLEVEL__ > 0))Another approach is to use the predefined macros to calculate a single number, then compare that against a threshold:#define GCC_VERSION (__GNUC__ * 10000 \+ __GNUC_MINOR__ * 100 \+ __GNUC_PATCHLEVEL__).../* Test for GCC > 3.2.0 */#if GCC_VERSION > 30200Many people find this form easier to understand.上⾯这⼀⼤段英语实际是在讲:注意,__GNUC_PATCHLEVEL__是从gcc 3.0以后才有的,在这之前的gcc是没有预定义这个宏的。

KEIL C51 MDK-ARM安装破解配置教程(2016-01-01更新)

KEIL C51  MDK-ARM安装破解配置教程(2016-01-01更新)

本次教程的安装环境是windows 10 X64,虽然win10下keil也能正常使用,但还是推荐大家在win7下使用keil(某些硬件没有驱动或者在win10下安装驱动十分麻烦(这里主要指一些PCI/PCIE串口卡)第一步:下载好C51和MDK-ARM的最新版本,下载通用注册机:第二步:安装C51到非系统分区(如果是全新安装则不会有下面的updateinstallation,下面的BACKUP OLD FILES是询问你在升级C51时是否备份旧版本的C51文件)这里要求你填入个人信息,随便写便可点finfish后会弹出一网页,这里告诉了你这个版本更新了什么内容第三步安装MDK-ARM到非系统分区:注意第一个CORE必须要和C51在同一个位置。

接下来会解压一系列的包安装keil的驱动最后点击finfish后,会弹出一个网页和一个窗口,网页是告诉你这个版本的更新日志,下面这个窗口则是让你安装你对应设备的PACK包的如何安装PACK包(每个人都不一样,有的人不用安装(MDK里面带的有),有的人用的偏门型号的开发板则需要安装,为了保险起见都在这里搜索一下。

具体要看你使用什么CPU 的开发版,下载对应的包安装即可。

这里以TI的LM3S9B96为例):在左上角的搜索框内输入型号,等待右下角跑到100%,对应的包就出来了。

然后安装PACK(一般装右边第一个就行,有特殊用途的可以装下面的)漫长的等待后,安装PACK包(这个下载速度不是一般的慢)这里直接安装就行,安装完后需要重新启动keil。

然后你就能在创建project里看到你的设备了:注:嫌这玩意下载太慢的,点击左边的蓝色字符,会自动进入对应CPU的keil网页:找到右下角的Device Family Pack下载安装即可。

安装PACK完成之后右键桌面的keil图标,兼容性—在管理员权限上打勾:然后右键我的电脑——属性——找到左上角的高级系统设置:点环境变量找到系统变量中的TEMP和TMP项,编辑,将其改为D:\TEMP和D:\TMP这样可以防止权限问题导致各种无法编译,无法写入文件的错误产生。

第四章MDK-ARM软件入门

第四章MDK-ARM软件入门

小结
本章详细介绍了STM32最常用的编程软件MDK-ARM的使 用过程。通过本章的学习应能独立完成工程的建立、编译 、软件仿真和下载。另外,应掌握本章所提及的程序命名 规则及编程技巧,使编制的程序更加规范及美观。
4.2新建MDK工程
3.5.0\3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\ DeviceSupport\ST\STM32F10x\startup\arm的全部文件拷贝到STM32Template\CMSIS\startup(需先在CMSIS新建好startup文件夹)文件 夹下。我们把startup_stm32f10x_hd.s添加到我们的工程中。(高密 度芯片STM32F103ZET6的系统启动文件,程序开始的地方) 3.5.0\3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\ CoreSupport文件目录中的core_cm3.c和core_cm3.h也拷贝到STM32Template\CMSIS文件夹下。 (内核访问层的头文件和源文件) 3.5.0\3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\ DeviceSupport\ST\STM32F10x文件目录中的stm32f10x.h(寄存器定 义封装)、system_stm32f10x.c、system_stm32f10x.h拷贝到STM32Template\CMSIS文件夹下。 (设备驱动支持文件,属于外设访问 层的头文件和源文件)
创建一个工程并配置工程
选择工具栏Project->New μVision Project…新建我们的工 程文件,我们将新建的工程文件保存在桌面的STM32Template\USER文件夹下(先在电脑桌面上新建一 STM32-Template文件夹,在STM32-Template里面新建一 个USER文件夹),文件名取为STM32-DEMO,名字可 以随便取,点击保存。最终效果如下图所示。

关于在ARM中(MDK下)C与汇编混合编程的问题

关于在ARM中(MDK下)C与汇编混合编程的问题
{
loopLDRBr2,[r0],#1//R0保存第一个参数
STRBr2,[r1],#1//R1保存第二个参数
CMPr2,#0
BNEloop
BLXlr//返回指令须要手动加入
}
intmain(void)
{
constchar*a=“Helloworld!”;
charb[20];
my_strcpy(a,b);
关于在ARM中(MDK下)C与汇编混合编程的问题
于:bbs.21ic/icview-156494-1-1.html([微控制器/MCU]小窍门:Cortex-M3
在MDK C语言中嵌入汇编语言的方法)
==================================
==========================
如果须要访问C程式中的变量,可以使用_cpp关键字,编译器如LDRr0,=__cpp(&some_variable)
LDRr1,=__cpp(some_function)
BL__cpp(some_function)
MOVr0,#__cpp(some_constant_expr)
**********************************
***************************
在传统的ARM处理器中(ARM7/ARM9),如果要在C程式中嵌入汇编,可以有
两种方法:
一、内联汇编的方式方法如下:intPCBsheji(inti)
{
intr0;
__asm
{
ADDr0,i,1
EORi,r0,i
}
returni;
}
在汇编语句可以直接做用C语言中的变量.编译器会对这些代码进一步优化,

实验二 ARM开发工具MDK开发环境的熟悉

实验二 ARM开发工具MDK开发环境的熟悉

实验二 ARM开发工具MDK开发环境的熟悉一、实验目的:1、掌握MDK建立工程、设置工程的方法;2、掌握MDK编译工程、链接工程的方法;3、掌握MDK仿真调试的方法;二、实验内容1、参考本次实验的实验步骤,完成本次实验,以及实验步骤中的几个思考题2、参考教材117页有关MDK工具的配置回答以下几个问题(1)MDK提供的两种调试模式(2)如何在工程中打开存储单元观察窗口(3)如何在工程中设置断点三、实验原理:Keil公司(该公司已被ARM公司收购!!)开发的ARM开发工具MDK(Microcontroller Development Kit),是用来开发基于ARM核的系列微控制器的嵌入式应用程序。

它适合不同层次的开发者使用,包括专业的应用程序开发工程师和嵌入式软件开发的入门者。

MDK包含了工业标准的Keil C编译器、宏汇编器、调试器、实时内核等组件,支持所有基于ARM的设备,能帮助工程师按照计划完成项目。

注意:下面所描述的s3c2410 GPIO口的工作原理大家能看懂多少就懂多少,本次实验课的重点不是GPIO工作原理,重点在MDK开发环境的熟悉!!嵌入式系统在控制领域的应用非常广泛,嵌入式芯片是通过外部管脚来和所控制的设备进行通信的。

嵌入式芯片S3C2410和外部设备最简单的通信方式就是通过GPIO(通用IO 管脚)来通信的。

S3C2410通过读写与GPIO相关联的一组寄存器以实现读写GPIO管脚电平信号(大家可以回想以下在单片机中是怎么通过P0端口寄存器来控制P0.0------P0.7八个管脚的?)。

当然,S3C2410的GPIO的操作比51单片机要些许复杂一点。

本实验的电路图如下:图中的GPF4表示这个管脚是与S3C2410的通用端口F组的第4根管脚,其余类推。

实验相关寄存器说明(以后一定要学会看下面的几个表格):GPFCON――端口配置寄存器。

GPFCON为通用端口F组的管脚工作状态配置寄存器。

keil arm编译手册

keil arm编译手册

Keil MDK(Microcontroller Development Kit)是一套用于嵌入式系统开发的工具,其中包括编译器、调试器、模拟器等。

以下是关于Keil MDK ARM编译的一些基本步骤。

请注意,具体步骤可能会根据你的项目和硬件平台而有所不同。

Keil MDK ARM 编译手册基本步骤:创建新工程:打开Keil MDK,选择"Project" -> "New µVision Project"。

在弹出的对话框中,选择工程的存储位置和工程名称,然后点击"Save"。

选择目标设备:在弹出的"Device" 对话框中,选择你的目标微控制器或处理器型号,然后点击"OK"。

添加源文件:在"Project" 窗口中,右键点击"Source Group 1",选择"Add New Item to Group 'Source Group 1'",然后添加你的源代码文件。

配置编译选项:在"Project" 窗口中,右键点击你的工程,选择"Options for Target 'Target 1'"。

在弹出的对话框中,配置"C/C++"、"Miscellaneous" 和其他选项,例如选择编译器、调试器、优化选项等。

设置链接脚本(可选):在"Options for Target 'Target 1'" 对话框中的"Linker" 选项卡中,你可以设置链接脚本,以指定程序的内存布局。

编写源代码:打开添加的源代码文件,编写你的程序代码。

构建项目:点击工具栏上的"Build" 按钮或者使用快捷键(通常是F7)进行编译。

keil 宏条件语句

keil 宏条件语句

keil 宏条件语句Keil宏条件语句是一种用于在嵌入式系统开发中控制代码编译和执行的重要工具。

它可以根据不同的条件,在编译时决定是否包含或排除某些代码块,从而实现不同条件下的代码选择和优化。

下面是关于Keil宏条件语句的一些常见应用场景和示例:1. 根据芯片型号选择不同的驱动库:在嵌入式系统开发中,不同的芯片型号可能需要使用不同的外设驱动库。

可以使用Keil宏条件语句根据芯片型号选择不同的驱动库。

示例代码如下:```c#ifdef STM32F103#include "stm32f103_drivers.h"#elif defined(STM32F407)#include "stm32f407_drivers.h"#else#error "Unsupported chip!"#endif```2. 根据编译器版本选择不同的编译选项:不同版本的编译器可能对代码的优化和警告处理有所不同。

可以使用Keil宏条件语句根据编译器版本选择不同的编译选项。

示例代码如下:```c#if (__CC_ARM && (__ARMCC_VERSION >= 6010050))#pragma O2#pragma diag_suppress=Pa039#elif (__GNUC__ && (__GNUC__ >= 7))#pragma GCC optimize("O2")#pragma GCC diagnostic ignored "-Wmisleading-indentation"#else#error "Unsupported compiler version!"#endif```3. 根据编译器平台选择不同的标准库:不同的编译器平台可能提供不同的标准库,可以使用Keil宏条件语句根据编译器平台选择不同的标准库。

armcc语法

armcc语法

armcc语法
ARM C编译器的语法规则包括以下方面:
1.符号:程序中用到的各种变量和函数都要用符号(包括变量名、函数名等)来表示。

2.注释:在程序中,注释是一种非常重要的语法元素,它用来对程序进行说明和解释。

3.变量:在程序中,变量是一种非常重要的数据存储单元,它用来存储程序中需要处理的数据。

4.运算符:在程序中,运算符是一种非常重要的语法元素,它用来对变量进行各种运算操作。

5.语句:在程序中,语句是一种非常重要的语法元素,它用来表示程序中的各种操作。

6.函数:在程序中,函数是一种非常重要的语法元素,它用来将程序中的一段代码封装成一个独立的模块,以便于重复使用。

以上是ARM C编译器的一些基本语法规则,当然还有很多其他的规则和细节需要掌握。

MDK5 宏定义CC_ARM

MDK5 宏定义CC_ARM

MDK5 宏定义CC_ARM#if defined (__CC_ARM)这是Keil MDK 里用来识别编译器的宏.__CC_ARM 为Keil 里带的编译器如果定义了(__CC_ARM)启用对匿名结构和联合的支持__CC_ARM1Always set to 1 for the ARM compiler, even when you specify the --thumb option.1.#if defined ( __GNUC__ ) || defined ( __clang__ )2.#ifndef __weak3.#define __weak __attribute__((weak))4.#endif /* __weak */5.#ifndef __packed6.#define __packed __attribute__((__packed__))7.#endif /* __packed */8.#endif /* __GNUC__ */9.10./* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */11.#if defined (__GNUC__) || defined (__clang__) /* GNU Compiler */12.#ifndef __ALIGN_END13.#define __ALIGN_END __attribute__ ((aligned (4)))14.#endif /* __ALIGN_END */15.#ifndef __ALIGN_BEGIN16.#define __ALIGN_BEGIN17.#endif /* __ALIGN_BEGIN */18.#else19.#ifndef __ALIGN_END20.#define __ALIGN_END21.#endif /* __ALIGN_END */22.#ifndef __ALIGN_BEGIN23.#if defined (__CC_ARM) /* ARM Compiler */24.#define __ALIGN_BEGIN __align(4)25.#elif defined (__ICCARM__) /* IAR Compiler */26.#define __ALIGN_BEGIN27.#endif /* __CC_ARM */28.#endif /* __ALIGN_BEGIN */29.#endif /* __GNUC__ */30.31.32./**33. * @brief __RAM_FUNC definition34. */35.#if defined ( __CC_ARM )36./* ARM Compiler37. ------------38. RAM functions are defined using the toolchain options.39. Functions that are executed in RAM should reside in a separate sourcemodule.40. Using the 'Options for File' dialog you can simply change the 'Code /Const'41. area of a module to a memory space in physical RAM.42. Available memory areas are declared in the 'Target' tab of the 'Options for Target'43. dialog.44.*/45.#define __RAM_FUNC HAL_StatusTypeDef46.47.#elif defined ( __ICCARM__ )48./* ICCARM Compiler49. ---------------50. RAM functions are defined using a specific toolchain keyword "__ramfunc".51.*/52.#define __RAM_FUNC __ramfunc HAL_StatusTypeDef53.54.#elif defined ( __GNUC__ ) || defined ( __clang__ )55./* GNU Compiler56. ------------57. RAM functions are defined using a specific toolchain attribute58. "__attribute__((section(".RamFunc")))".59.*/60.#define __RAM_FUNC HAL_StatusTypeDef __attribute__((section(".RamFunc")))61.62.#endif63.64./**65. * @brief __NOINLINE definition66. */67.#if defined ( __CC_ARM ) || defined ( __GNUC__ ) || defined ( __clang__ )68./* ARM & GNUCompiler69. ----------------70.*/71.#define __NOINLINE __attribute__ ( (noinline) )72.73.#elif defined ( __ICCARM__ )74./* ICCARM Compiler75. ---------------76.*/77.#define __NOINLINE _Pragma("optimize = no_inline")78.79.#endif80.81.#ifdef __cplusplus82.}83.#endif/* ARM Compiler------------RAM functions are defined using the toolchain options.Functions that are executed in RAM should reside in a separate source module.Using the 'Options for File' dialog you can simply change the 'Code / Const' area of a module to a memory space in physical RAM.Available memory areas are declared in the 'Target' tab of the 'Options for Target' dialog./ * ARM编译器- - - - - - - - - - - -使用工具链选项定义RAM函数。

第4章 Keil MDK ARM集成开发环境4H

第4章 Keil MDK ARM集成开发环境4H
第五页,共一百二十二页。
Keil MDK-ARM简介(jiǎn jiè)
在ARM公司的网站()注册、下载(xià zǎi)最新的Keil MDK-ARM开 发工具软件, MDK-Lite版:受限制的32K编译、链接、部分模 块功能。
第六页,共一百二十二页。
Keil MDK-ARM简介(jiǎn jiè)
Breakpoint 对话框,可在此对话框中定义程序执行停止的条件; Code Coverage 窗口统计了程序中被执行部分及未被执行部分的执行信息; Disassembly Window 可以反汇编方式来查看及测试程序; Logic Analyzer 窗口可以以图形的方式来显示变量及外设寄存器值的变化;
文件
第三十一页,共一百二十二页。
“Project”菜单(cài - dān)
改变目标、组、文件(wénjiàn)的工具选项: 设置(shèzhì)表单文

第三十二页,共一百二十二页。
“Project”菜单(cài - dān)
改变(gǎibiàn)目标、组、文件的工具选 项:
设置(shèzhì)用户自定
改变目标、组、文件(wénjiàn)的工具选 项:
配置(pèizhì)
目标板
第二十九页,共一百二十二页。
“Project”菜单(cài - dān)
改变(gǎibiàn)目标、组、文件的工具 选项:
目标
(mùbiāo)处
理器
第三十页,共一百二十二页。
“Project”菜单(cài - dān)
改变目标(mùbiāo)、组、文件的工具选项: 设置输出(shūchū)
它包含众多示例、项目模板和中间件库,具有广泛的 TCP/IP 软件 堆栈、Flash 文件系统、USB 主机和设备堆栈、CAN 访问以及舒适 的图形用户界面解决方案。

mdk及ewarm使用简介

mdk及ewarm使用简介

第1节Keil MDK介绍File Save ROMSTM32微处理器基于ARM核,所以很多基于ARM嵌入式开发环境都可用于STM32开发平台。

开发工具都可用于STM32开发。

选择合适的开发环境可以加快开发进度,节省开发成本。

本章将先对STM32常用的开发工具Keil MDK和IAR EWARM进行简单介绍,然后结合STM32_SK仿真评估板和STM32F103C的开发板讲解STM32片上资源使用,最后给出一个基于STM32的数据采集器的应用实例。

5.1 Keil MDK介绍Keil是德国知名软件公司Keil(现已并入ARM 公司)开发的微控制器软件开发平台,是目前ARM内核单片机开发的主流工具。

Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器在内的完整开发方案,通过一个集成开发环境(uVision)将这些功能组合在一起。

uVision当前最高版本是uVision3,它的界面和常用的微软VC++的界面相似,界面友好,易学易用,在调试程序,软件仿真方面也有很强大的功能。

因此很多开发ARM应用的工程师,都对它十分喜欢。

5.1.1 开发过程及集成开发环境简介1. Keil的软件开发周期使用Keil来开发嵌入式软件,开发周期和其他的平台软件开发周期是差不多的,大致有以下几个步骤:1. 创建一个工程,选择一块目标芯片,并且做一些必要的工程配置。

2. 编写C或者汇编源文件。

3. 编译应用程序。

4. 修改源程序中的错误。

5. 联机调试。

下面这种结构图完整描述了Keil开发软件的整个过程。

2. uVision3 集成开发环境uVision3 IDE是一款集编辑,编译和项目管理于一身的基于窗口的软件开发环境。

uVision3集成了C语言编译器,宏编译,链接/定位,以及HEX文件产生器。

uVision3具有如下特性:ν功能齐全的源代码编辑器,用于配置开发工具的设备库,ν用于创建工程和维护工程的项目管理器,νν所有的工具配置都采用对话框进行,集成了源码级的仿真调试器,包括高速CPU和外设模拟器,ν用于往Flashν ROM下载应用程序的Flash编程工具,ν完备的开发工具帮助文档,设备数据表和用户使用向导。

keil 多target 条件编译

keil 多target 条件编译

keil 多target 条件编译1.如果定义了宏MY_LED,并且值为1,则编译这段代码。

(If macro MY_LED is defined and its value is 1, compile this code.)2.如果TARGET是MCU1,则编译这段代码。

(If TARGET is MCU1, compile this code.)3.如果目标芯片为STM32F4,则执行该分支。

(If the target chip is STM32F4, execute this branch.)4.当TARGET等于ARM7时,编译这个函数。

(Compile this function when TARGET equals ARM7.)5.如果需要编译ARM指令,定义宏ARM_INSTRUCTION。

(Define macro ARM_INSTRUCTION if ARM instruction compilation is needed.)6.如果选择的目标系统为LPC1768,则打开LPC1768宏。

(If the selected target system is LPC1768, open the LPC1768 macro.)7.当前处理器为Cortex-M3时,编译该段代码。

(Compile this code when the current processor is Cortex-M3.)8.如果目标芯片为STM32F103RB,则执行代码块。

(Execute this code block if the target chip isSTM32F103RB.)9.如果选择的目标为PIC18F4520,则进行编译。

(Compile if the selected target is PIC18F4520.)10.在ARMCortexM系列中,定义ARMCortexM宏以进行编译。

关于MDK,keil和ARM的区别和联系(ok)

关于MDK,keil和ARM的区别和联系(ok)

MDK简介MDK即RealView MDK(Microcontroller Development kit),是ARM 公司目前最新推出的针对各种嵌入式处理器的软件开发工具。

RealView MDK 集成了业内最领先的技术,包括uVision4 集成开发环境与RealView 编译器。

支持ARM7、ARM9 和最新的Cortex-M3/M1/M0 核处理器,自动配置启动代码,集成Flash 烧写模块,强大的Simulation 设备模拟,性能分析等功能,与ARM 之前的工具包ADS 等相比,RealView 编译器的最新版本可将性能改善超过20%。

Keil公司开发的ARM开发工具MDK,是用来开发基于ARM核的系列微控制器的嵌入式应用程序。

它适合不同层次的开发者使用,包括专业的应用程序开发工程师和嵌入式软件开发的入门者。

MDK包含了工业标准的Keil C编译器、宏汇编器、调试器、实时内核等组件,支持所有基于ARM的设备,能帮助工程师按照计划完成项目。

功能特点完美支持Cortex-M、Cortex-R4、ARM7谡ARM9系列器件。

业行领先的ARM C/C++编译工具链IDE集成开发环境,调试器和仿真环境确定的Keil RTX ,小封装实时操作系统(带源码)TCP/IP网络套件提供多种的协议和各种应用提供带标准驱动类的USB 设备和USB 主机栈为带图形用户接口的嵌入式系统提供了完善的GUI库支持ULINKpro可实时分析运行中的应用程序,且能记录Cortex-M指令的每一次执行关于程序运行的完整代码覆盖率信息执行分析工具和性能分析器可使程序得到最优化大量的项目例程帮助你快速熟悉MDK-ARM强大的内置特征符合CMSIS (Cortex微控制器软件接口标准)ARM编译工具ARM编译工具链(之前被称为ARM RealView编译工具)包含:ARM C/C++ 编译器(armcc)MicrolibARM Macro汇编器(armasm)ARM链接器(armLink)ARM工具(Librarian and FromELF)基于以上专门针对ARM架构的微控制器编译器,工程师可以使用C或者C++编写应用程序。

Keil修改ARM编译器及配置方法

Keil修改ARM编译器及配置方法

Keil修改ARM编译器及配置方法(Keil)MDK自V5.36 版本之后,默认就不带(Arm)Com (pi)ler V5版本编译器。

如果需要使用V5 版本编译器,就需要自己(下载)并安装。

注意:这里说的是V6版本编译器,不是Keil V6集成开发环境。

Arm Compiler V6 和V5兼容性不好,有很多地方都需要注意。

这里简单分享几点注意事项。

Keil修改ARM编译器及配置很多小伙伴可能还不知道怎么修改Keil MDK编译器,这里可以参看我之前分享的文章:手把手教你修改Keil MDK的ARM编译器因为ARM编译器下载需要注册,可能会因为各种原因下载失败,这里可以参看文章:折腾Keil 编译器的经历这里再说下配置,Keil MDK 配置(AC)6编译:配置优化选项:优化选项描述AC6默认,默认值为-O0。

这种情况下,代码不做优化,适用于在线调试。

对于需要优化,但不是对速度和时间非常苛刻,通常建议使用-Os balanced。

对于存储容量小的(芯片),可以使用-Oz选项以获得最佳代码大小,此优化级别会降低调试体验。

对运行效率(时间)有要求的工程,可以使用-Ofast优化代码。

当然,如果使用armlink命令行,还有-Omin,-Omax等选项。

AC6编译器的优化选项(含命令选项很多),这里可以参看我之前的一篇文章:AC5 和AC6 优化选项重要内容和区别AC6的注意事项除了在Keil MDK中使用常规的优化选项之外,还有很多选项,在使用的时候需要注意。

比如:-Omin将自动启用armclang -flto选项,并且生成的目标文件不适合创建静态库。

使用-Omin、-Omax时,Arm 无法保证在所有代码情况下都能实现最佳的代码大小优化。

启用-ffp-mode=fast armclang选项执行的积极优化可能会违反严格遵守语言标准的规定。

keil 宏可变参数

keil 宏可变参数

keil 宏可变参数答:Keil(现为MDK-ARM)是一款广泛用于嵌入式系统开发的集成开发环境(IDE)。

Keil中的宏(Macros)是预处理器的一种功能,用于在编译前处理代码。

然而,Keil(或任何C/C++编译器)本身并不直接支持C或C++语言中的可变参数宏(Variable-length Macro Arguments)。

C和C++中的可变参数宏允许宏接受可变数量的参数。

这在Keil的宏中并不直接支持。

如果你想在Keil的宏中实现类似的功能,你可能需要使用其他技巧或方法。

例如,你可以使用...来表示宏参数,然后使用预处理器的其他功能(如##运算符)来处理这些参数。

但这并不是真正的可变参数宏,因为它要求你提前知道要传递给宏的参数数量。

在更现代的C++编程中,模板通常被用作实现可变参数功能的方式。

然而,这需要使用C++编译器,而不是Keil的C编译器。

如果你需要在Keil环境中使用可变参数宏,你可能需要考虑以下几种方法:1.手动处理:编写代码来手动处理可变数量的参数,而不是依赖宏。

2.固定数量的参数:如果你的需求允许,你可以限制传递给宏的参数数量为一个固定值。

3.第三方库或工具:查找是否有第三方库或工具提供了在Keil环境中使用可变参数宏的功能。

4.升级到支持C++的编译器:如果你主要使用C++编写代码,并且需要可变参数宏,考虑升级到支持C++的编译器,如GCC或Clang。

5.定制或扩展Keil的预处理器:如果你熟悉预处理器的细节,并且对汇编语言和链接器脚本有深入的了解,你可以尝试扩展Keil的预处理器以支持可变参数宏。

这需要深入了解编译器的内部工作原理,并且可能涉及到修改编译器的源代码。

C语言中的预编译宏定义

C语言中的预编译宏定义

C语言中的预编译宏定义C语言中的预编译宏定义导语:C初学者可能对预处理器没什么概念,这是情有可原,下面是C中的预编译宏定义,一起来学习下吧:(一) 预处理命令简介预处理命令由#(hash字符)开头, 它独占一行, #之前只能是空白符. 以#开头的语句就是预处理命令, 不以#开头的语句为C中的代码行. 常用的预处理命令如下:#define 定义一个预处理宏#undef 取消宏的定义#include 包含文件命令#include_next 与#include相似, 但它有着特殊的用途#if 编译预处理中的条件命令, 相当于C语法中的if语句#ifdef 判断某个宏是否被定义, 若已定义, 执行随后的语句#ifndef 与#ifdef相反, 判断某个宏是否未被定义#elif 若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif 之后的语句, 相当于C语法中的else-if#else 与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else 之后的语句, 相当于C语法中的else#endif #if, #ifdef, #ifndef这些条件命令的结束标志.defined 与#if, #elif配合使用, 判断某个宏是否被定义#line 标志该语句所在的行号# 将宏参数替代为以参数值为内容的字符窜常量## 将两个相邻的标记(token)连接为一个单独的标记#pragma 说明编译器信息#warning 显示编译警告信息#error 显示编译错误信息(二) 预处理的文法预处理并不分析整个源代码文件, 它只是将源代码分割成一些标记(token), 识别语句中哪些是C语句, 哪些是预处理语句. 预处理器能够识别C标记, 文件名, 空白符, 文件结尾标志.预处理语句格式: #command name(...) token(s)1, command预处理命令的名称, 它之前以#开头, #之后紧随预处理命令, 标准C允许#两边可以有空白符, 但比较老的编译器可能不允许这样. 若某行中只包含#(以及空白符), 那么在标准C中该行被理解为空白. 整个预处理语句之后只能有空白符或者注释, 不能有其它内容.2, name代表宏名称, 它可带参数. 参数可以是可变参数列表(C99).3, 语句中可以利用""来换行.e.g.# define ONE 1 /* ONE == 1 */等价于: #define ONE 1#define err(flag, msg) if(flag)printf(msg)等价于: #define err(flag, msg) if(flag) printf(msg)(三) 预处理命令详述1, #define#define命令定义一个宏:#define MACRO_NAME(args) tokens(opt)之后出现的MACRO_NAME将被替代为所定义的标记(tokens). 宏可带参数, 而后面的标记也是可选的.对象宏不带参数的宏被称为"对象宏(objectlike macro)"#define经常用来定义常量, 此时的宏名称一般为大写的字符串. 这样利于修改这些常量.e.g.#define MAX 100int a[MAX];#ifndef __FILE_H__#define __FILE_H__#include "file.h"#endif#define __FILE_H__ 中的宏就不带任何参数, 也不扩展为任何标记. 这经常用于包含头文件.要调用该宏, 只需在代码中指定宏名称, 该宏将被替代为它被定义的内容.函数宏带参数的宏也被称为"函数宏". 利用宏可以提高代码的运行效率: 子程序的调用需要压栈出栈, 这一过程如果过于频繁会耗费掉大量的CPU运算资源. 所以一些代码量小但运行频繁的代码如果采用带参数宏来实现会提高代码的运行效率.函数宏的参数是固定的情况函数宏的定义采用这样的方式: #define name( args ) tokens其中的args和tokens都是可选的. 它和对象宏定义上的区别在于宏名称之后不带括号.注意, name之后的左括号(必须紧跟name, 之间不能有空格, 否则这就定义了一个对象宏, 它将被替换为以(开始的字符串. 但在调用函数宏时, name与(之间可以有空格.e.g.#define mul(x,y) ((x)*(y))注意, 函数宏之后的参数要用括号括起来, 看看这个例子:e.g.#define mul(x,y) x*y"mul(1, 2+2);" 将被扩展为: 1*2 + 2同样, 整个标记串也应该用括号引用起来:e.g.#define mul(x,y) (x)*(y)sizeof mul(1,2.0) 将被扩展为 sizeof 1 * 2.0调用函数宏时候, 传递给它的参数可以是函数的返回值, 也可以是任何有意义的语句:e.g.mul (f(a,b), g(c,d));e.g.#define (stmt) stmt( a=1; b=2;) 相当于在代码中加入 a=1; b=2 .( a=1, b=2;) 就有问题了: 预处理器会提示出错: 函数宏的参数个数不匹配. 预处理器把","视为参数间的分隔符.((a=1, b=2;)) 可解决上述问题.在定义和调用函数宏时候, 要注意一些问题:1, 我们经常用{}来引用函数宏被定义的内容, 这就要注意调用这个函数宏时的";"问题.example_3.7:#define swap(x,y) { unsigned long _temp=x; x=y; y=_tmp}如果这样调用它: "swap(1,2);" 将被扩展为: { unsigned long _temp=1; 1=2; 2=_tmp};明显后面的;是多余的, 我们应该这样调用: swap(1,2)虽然这样的调用是正确的, 但它和C语法相悖, 可采用下面的方法来处理被{}括起来的内容:#define swap(x,y)do { unsigned long _temp=x; x=y; y=_tmp} while (0)swap(1,2); 将被替换为:do { unsigned long _temp=1; 1=2; 2=_tmp} while (0);在Linux内核源代码中对这种do-while(0)语句有这广泛的应用.2, 有的函数宏是无法用do-while(0)来实现的, 所以在调用时不能带上";", 最好在调用后添加注释说明.eg_3.8:#define incr(v, low, high)for ((v) = (low),; (v) <= (high); (v)++)只能以这样的形式被调用: incr(a, 1, 10) /* increase a form 1 to 10 */函数宏中的参数包括可变参数列表的情况C99标准中新增了可变参数列表的内容. 不光是函数, 函数宏中也可以使用可变参数列表.#define name(args, ...) tokens#define name(...) tokens"..."代表可变参数列表, 如果它不是仅有的'参数, 那么它只能出现在参数列表的最后. 调用这样的函数宏时, 传递给它的参数个数要不少于参数列表中参数的个数(多余的参数被丢弃).通过__VA_ARGS__来替换函数宏中的可变参数列表. 注意__VA_ARGS__只能用于函数宏中参数中包含有"..."的情况.e.g.#ifdef DEBUG#define my_printf(...) fprintf(stderr, __VA_ARGS__)#else#define my_printf(...) printf(__VA_ARGS__)#endiftokens中的__VA_ARGS__被替换为函数宏定义中的"..."可变参数列表.注意在使用#define时候的一些常见错误:#define MAX = 100#define MAX 100;=, ; 的使用要值得注意. 再就是调用函数宏是要注意, 不要多给出";".注意: 函数宏对参数类型是不敏感的, 你不必考虑将何种数据类型传递给宏. 那么, 如何构建对参数类型敏感的宏呢? 参考本章的第九部分, 关于"##"的介绍.关于定义宏的另外一些问题(1) 宏可以被多次定义, 前提是这些定义必须是相同的. 这里的"相同"要求先后定义中空白符出现的位置相同, 但具体的空白符类型或数量可不同, 比如原先的空格可替换为多个其他类型的空白符: 可为tab, 注释...e.g.#define NULL 0#define NULL /* null pointer */ 0上面的重定义是相同的, 但下面的重定义不同:#define fun(x) x+1#define fun(x) x + 1 或: #define fun(y) y+1如果多次定义时, 再次定义的宏内容是不同的, gcc会给出"NAME redefined"警告信息.应该避免重新定义函数宏, 不管是在预处理命令中还是C语句中, 最好对某个对象只有单一的定义. 在gcc中, 若宏出现了重定义, gcc会给出警告.(2) 在gcc中, 可在命令行中指定对象宏的定义:e.g.$ gcc -Wall -DMAX=100 -o tmp tmp.c相当于在tmp.c中添加" #define MAX 100".那么, 如果原先tmp.c中含有MAX宏的定义, 那么再在gcc调用命令中使用-DMAX, 会出现什么情况呢?---若-DMAX=1, 则正确编译.---若-DMAX的值被指定为不为1的值, 那么gcc会给出MAX宏被重定义的警告, MAX的值仍为1.注意: 若在调用gcc的命令行中不显示地给出对象宏的值, 那么gcc 赋予该宏默认值(1), 如: -DVAL == -DVAL=1(3) #define所定义的宏的作用域宏在定义之后才生效, 若宏定义被#undef取消, 则#undef之后该宏无效. 并且字符串中的宏不会被识别e.g.#define ONE 1sum = ONE + TWO /* sum = 1 + TWO */#define TWO 2sum = ONE + TWO /* sum = 1 + 2 */#undef ONEsum = ONE + TWO /* sum = ONE + 2 */char c[] = "TWO" /* c[] = "TWO", NOT "2"! */(4) 宏的替换可以是递归的, 所以可以嵌套定义宏.e.g.# define ONE NUMBER_1# define NUMBER_1 1int a = ONE /* a = 1 */2, #undef#undef用来取消宏定义, 它与#define对立:#undef name如够被取消的宏实际上没有被#define所定义, 针对它的#undef 并不会产生错误.当一个宏定义被取消后, 可以再度定义它.3, #if, #elif, #else, #endif#if, #elif, #else, #endif用于条件编译:#if 常量表达式1语句...#elif 常量表达式2语句...#elif 常量表达式3语句......#else语句...#endif#if和#else分别相当于C语句中的if, else. 它们根据常量表达式的值来判别是否执行后面的语句. #elif相当于C中的else-if. 使用这些条件编译命令可以方便地实现对源代码内容的控制.else之后不带常量表达式, 但若包含了常量表达式, gcc只是给出警告信息.使用它们可以提升代码的可移植性---针对不同的平台使用执行不同的语句. 也经常用于大段代码注释.e.g.#if 0{一大段代码;}#endif常量表达式可以是包含宏, 算术运算, 逻辑运算等等的合法C常量表达式, 如果常量表达式为一个未定义的宏, 那么它的值被视为0.#if MACRO_NON_DEFINED == #if 0在判断某个宏是否被定义时, 应当避免使用#if, 因为该宏的值可能就是被定义为0. 而应当使用下面介绍的#ifdef或#ifndef.注意: #if, #elif, #else之后的宏只能是对象宏. 如果name为名的宏未定义, 或者该宏是函数宏. 那么在gcc中使用"-Wundef"选项会显示宏未定义的警告信息.4, #ifdef, #ifndef, defined.#ifdef, #ifndef, defined用来测试某个宏是否被定义#ifdef name 或 #ifndef name它们经常用于避免头文件的重复引用:#ifndef __FILE_H__#define __FILE_H__#include "file.h"#endifdefined(name): 若宏被定义,则返回1, 否则返回0.它与#if, #elif, #else结合使用来判断宏是否被定义, 乍一看好像它显得多余, 因为已经有了#ifdef和#ifndef. defined用于在一条判断语句中声明多个判别条件:#if defined(VAX) && defined(UNIX) && !defined(DEBUG)和#if, #elif, #else不同, #indef, #ifndef, defined测试的宏可以是对象宏, 也可以是函数宏. 在gcc中使用"-Wundef"选项不会显示宏未定义的警告信息.5, #include , #include_next#include用于文件包含. 在#include 命令所在的行不能含有除注释和空白符之外的其他任何内容.#include "headfile"#include#include 预处理标记前面两种形式大家都很熟悉, "#include 预处理标记"中, 预处理标记会被预处理器进行替换, 替换的结果必须符合前两种形式中的某一种.实际上, 真正被添加的头文件并不一定就是#include中所指定的文件. #include"headfile"包含的头文件当然是同一个文件, 但#include 包包含的"系统头文件"可能是另外的文件. 但这不值得被注意. 感兴趣的话可以查看宏扩展后到底引入了哪些系统头文件.关于#include "headfile"和#include 的区别以及如何在gcc中包含头文件的详细信息, 参考本blog的GCC笔记.相对于#include, 我们对#include_next不太熟悉. #include_next 仅用于特殊的场合. 它被用于头文件中(#include既可用于头文件中, 又可用于.c文件中)来包含其他的头文件. 而且包含头文件的路径比较特殊: 从当前头文件所在目录之后的目录来搜索头文件.比如: 头文件的搜索路径一次为A,B,C,D,E. #include_next所在的当前头文件位于B目录, 那么#include_next使得预处理器从C,D,E目录来搜索#include_next所指定的头文件.可参考cpp手册进一步了解#include_next6, 预定义宏标准C中定义了一些对象宏, 这些宏的名称以"__"开头和结尾, 并且都是大写字符. 这些预定义宏可以被#undef, 也可以被重定义.下面列出一些标准C中常见的预定义对象宏(其中也包含gcc自己定义的一些预定义宏:__LINE__ 当前语句所在的行号, 以10进制整数标注.__FILE__ 当前源文件的文件名, 以字符串常量标注.__DATE__ 程序被编译的日期, 以"Mmm dd yyyy"格式的字符串标注.__TIME__ 程序被编译的时间, 以"hh:mm:ss"格式的字符串标注, 该时间由asctime返回.__STDC__ 如果当前编译器符合ISO标准, 那么该宏的值为1__STDC_VERSION__ 如果当前编译器符合C89, 那么它被定义为199409L, 如果符合C99, 那么被定义为199901L.我用gcc, 如果不指定-std=c99, 其他情况都给出__STDC_VERSION__未定义的错误信息, 咋回事呢?__STDC_HOSTED__ 如果当前系统是"本地系统(hosted)", 那么它被定义为1. 本地系统表示当前系统拥有完整的标准C库.gcc定义的预定义宏:__OPTMIZE__ 如果编译过程中使用了优化, 那么该宏被定义为1.__OPTMIZE_SIZE__ 同上, 但仅在优化是针对代码大小而非速度时才被定义为1.__VERSION__ 显示所用gcc的版本号.可参考"GCC the complete reference".要想看到gcc所定义的所有预定义宏, 可以运行: $ cpp -dM /dev/null7, #line#line用来修改__LINE__和__FILE__.e.g.printf("line: %d, file: %s ", __LINE__, __FILE__);#line 100 "haha"printf("line: %d, file: %s ", __LINE__, __FILE__);printf("line: %d, file: %s ", __LINE__, __FILE__);显示:line: 34, file: 1.cline: 100, file: hahaline: 101, file: haha8, #pragma, _Pragma#pragma用编译器用来添加新的预处理功能或者显示一些编译信息. #pragma的格式是各编译器特定的, gcc的如下:#pragma GCC name token(s)#pragma之后有两个部分: GCC和特定的pragma name. 下面分别介绍gcc中常用的.(1) #pragma GCC dependencydependency测试当前文件(既该语句所在的程序代码)与指定文件(既#pragma语句最后列出的文件)的时间戳. 如果指定文件比当前文件新, 则给出警告信息.e.g.在demo.c中给出这样一句:#pragma GCC dependency "temp-file"然后在demo.c所在的目录新建一个更新的文件: $ touch temp-file, 编译: $ gcc demo.c 会给出这样的警告信息: warning: current file is older than temp-file如果当前文件比指定的文件新, 则不给出任何警告信息.还可以在在#pragma中给添加自定义的警告信息.e.g.#pragma GCC dependency "temp-file" "demo.c needs to be updated!"1.c:27:38: warning: extra tokens at end of #pragma directive1.c:27:38: warning: current file is older than temp-file注意: 后面新增的警告信息要用""引用起来, 否则gcc将给出警告信息.(2) #pragma GCC poison token(s)若源代码中出现了#pragma中给出的token(s), 则编译时显示警告信息. 它一般用于在调用你不想使用的函数时候给出出错信息.e.g.#pragma GCC poison scanfscanf("%d", &a);warning: extra tokens at end of #pragma directiveerror: attempt to use poisoned "scanf"注意, 如果调用了poison中给出的标记, 那么编译器会给出的是出错信息. 关于第一条警告, 我还不知道怎么避免, 用""将token(s)引用起来也不行.(3) #pragma GCC system_header从#pragma GCC system_header直到文件结束之间的代码会被编译器视为系统头文件之中的代码. 系统头文件中的代码往往不能完全遵循C标准, 所以头文件之中的警告信息往往不显示. (除非用#warning显式指明).(这条#pragma语句还没发现用什么大的用处)由于#pragma不能用于宏扩展, 所以gcc还提供了_Pragma:e.g.#define PRAGMA_DEP #pragma GCC dependency "temp-file"由于预处理之进行一次宏扩展, 采用上面的方法会在编译时引发错误, 要将#pragma语句定义成一个宏扩展, 应该使用下面的_Pragma语句:#define PRAGMA_DEP _Pragma("GCC dependency "temp-file"")注意, ()中包含的""引用之前引该加上转义字符.9, #, ###和##用于对字符串的预处理操作, 所以他们也经常用于printf, puts之类的字符串显示函数中.#用于在宏扩展之后将tokens转换为以tokens为内容的字符串常量.e.g.#define TEST(a,b) printf( #a "<" #b "=%d ", (a)<(b));注意: #只针对紧随其后的token有效!##用于将它前后的两个token组合在一起转换成以这两个token 为内容的字符串常量. 注意##前后必须要有token.e.g.#define TYPE(type, n) type n之后调用:TYPE(int, a) = 1;TYPE(long, b) = 1999;将被替换为:int a = 1;long b = 1999;(10) #warning, #error#warning, #error分别用于在编译时显示警告和错误信息, 格式如下:#warning tokens#error tokense.g.#warning "some warning"注意, #error和#warning后的token要用""引用起来!(在gcc中, 如果给出了warning, 编译继续进行, 但若给出了error, 则编译停止. 若在命令行中指定了 -Werror, 即使只有警告信息, 也不编译.【C语言中的预编译宏定义】。

MDK-ARMarmcc编译器——pragma命令汇总

MDK-ARMarmcc编译器——pragma命令汇总

MDK-ARMarmcc编译器——pragma命令汇总Pragmas recognized by the compiler3.13 Pragmas recognized by the compilerThe compiler recognizes a number of pragmas, used to instruct the compiler to use particular features.The compiler recognizes the following pragmas:Pragmas for saving and restoring the pragma state#pragma pop#pragma pushPragmas controlling optimization goals#pragma Onum#pragma Ospace#pragma OtimePragmas controlling code generation#pragma arm#pragma thumb#pragma exceptions_unwind, #pragma no_exceptions_unwindPragmas controlling loop unrolling#pragma unroll [(n)]#pragma unroll_completelyPragmas controlling Precompiled Header (PCH) processing #pragma hdrstop#pragma no_pchPragmas controlling anonymous structures and unions#pragma anon_unions, #pragma no_anon_unionsPragmas controlling diagnostic messages#pragma diag_default tag[,tag,...]#pragma diag_error tag[,tag,...]#pragma diag_remark tag[,tag,...]#pragma diag_suppress tag[,tag,...]#pragma diag_warning tag[, tag, ...]Miscellaneous pragmas#pragma arm section [section_type_list]#pragma import(__use_full_stdio)#pragma inline, #pragma no_inline#pragma once#pragma pack(n)#pragma softfp_linkage, #pragma no_softfp_linkage#pragma import symbol_nameRelated reference9.72 #pragma anon_unions, #pragma no_anon_unions9.73 #pragma arm9.74 #pragma arm section [section_type_list]9.75 #pragma diag_default tag[,tag,...]9.76 #pragma diag_error tag[,tag,...]9.77 #pragma diag_remark tag[,tag,...]9.78 #pragma diag_suppress tag[,tag,...]9.79 #pragma diag_warning tag[, tag, ...]9.80 #pragma exceptions_unwind, #pragma no_exceptions_unwind 9.81 #pragma hdrstop9.82 #pragma import symbol_name9.83 #pragma import(__use_full_stdio)9.84 #pragma import(__use_smaller_memcpy)9.85 #pragma inline, #pragma no_inline9.86 #pragma no_pch9.87 #pragma Onum9.88 #pragma once9.89 #pragma Ospace9.90 #pragma Otime9.91 #pragma pack(n)9.92 #pragma pop9.93 #pragma push9.94 #pragma softfp_linkage, #pragma no_softfp_linkage9.95 #pragma thumb9.96 #pragma unroll [(n)]9.97 #pragma unroll_completely9.98 #pragma weak symbol, #pragma weak symbol1 = symbol2Copyright ? Keil, An ARM Company. All rights reserved.。

ccs的预宏定义

ccs的预宏定义

ccs的预宏定义CCS(Code Composer Studio)是德州仪器(Texas Instruments)公司开发的一款集成开发环境(IDE),用于嵌入式系统的软件开发。

在CCS中,预宏定义是一种非常重要的功能,它可以帮助开发者在编译过程中自动定义一些常用的宏,从而简化代码的编写和维护。

预宏定义是在编译过程中由编译器自动处理的一种宏定义。

在CCS 中,预宏定义可以通过在项目的属性设置中进行配置。

开发者可以根据自己的需求,定义一些常用的宏,然后在代码中使用这些宏,从而简化代码的编写。

预宏定义在CCS中有很多应用场景。

首先,它可以用来定义一些常量。

比如,我们可以定义一个名为"MAX_NUM"的宏,它的值为100。

然后,在代码中,我们可以使用这个宏来代替具体的数值。

这样,当我们需要修改最大数值时,只需要修改宏的定义,而不需要修改所有使用到这个数值的地方。

这大大提高了代码的可维护性。

其次,预宏定义还可以用来定义一些函数。

在CCS中,我们可以使用宏来定义一些简单的函数,比如计算两个数的和。

这样,我们就可以在代码中直接使用这个宏来代替函数调用,从而提高代码的执行效率。

另外,预宏定义还可以用来定义一些条件编译的宏。

在CCS中,我们可以使用宏来控制代码的编译过程。

比如,我们可以定义一个名为"DEBUG"的宏,然后在代码中使用条件编译语句来判断是否编译调试相关的代码。

这样,在发布版本时,我们只需要将宏的定义去掉,就可以去掉调试相关的代码,从而减小代码的体积。

除了上述应用场景,预宏定义还可以用来定义一些特定平台相关的宏。

在嵌入式系统开发中,不同的硬件平台可能有不同的寄存器地址、中断向量等。

通过预宏定义,我们可以根据不同的平台来定义不同的宏,从而实现代码的可移植性。

总之,CCS的预宏定义是一种非常有用的功能,它可以帮助开发者简化代码的编写和维护。

通过定义常量、函数、条件编译和平台相关的宏,我们可以在代码中使用这些宏来代替具体的数值、函数调用和条件判断,从而提高代码的可读性、可维护性和可移植性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Predefined macrosThis topic documents the predefined macros of the ARM compiler.lists the macro names predefined by the ARM compiler for C and C++. Where the value field is empty, the symbol is only defined. Table 28. Predefined macros Name__arm__Value When defined-Always defined for the ARM compiler, even when you specify the --thumb option. See also __ARMCC_VERSION.__ARMCC_VERSIONverAlways defined. It is a decimal number, and is guaranteed to increase between releases. The format is PVVbbbb where:⏹⏹⏹P is the major version VV is the minor version bbbb is the build number.NoteUse this macro to distinguish between ARM Compiler 4.1 or later, and other tools that define __arm__.__APCS_INTERWORK-When you specify the --apcs /interwork option or set the CPU architecture to ARMv5T or later.When you specify the --apcs /ropi option. When you specify the --apcs /rwpi option. When you specify the --apcs /fpic option. In C++ compiler mode, to specify that array new and delete are enabled.Always defined. Similar to __FILE__, but indicates the primary source file rather than the current one (that is, when the current file is an included file.If compiling for a big-endian target.In C++ compiler mode, to specify that bool is a keyword.In C++ compiler mode.__APCS_ROPI__APCS_RWPI__APCS_FPIC__ARRAY_OPERATORS__BASE_ FILE__----name__BIG_ENDIAN_BOOL__cplusplus---__CC_ARM1date ---Always set to 1 for the ARM compiler, even when you specify the --thumb option. Always defined.Always defined.In C++ mode when you specify the --using_std option.Always set to an integer value that represents the version number of the Edison Design Group (EDG front-end. For example, version 3.8 is represented as 308.The version number of the EDG front-end does not necessarily match the version number of the ARM compiler toolchain.__DATE____EDG____EDG_IMPLICIT_USING_STD__EDG_VERSION____EXCEPTIONS1-name ----In C++ mode when you specify the --exceptions option.When you specify the --signed_chars option (used by CHAR_MIN andCHAR_MAX. Always defined as a string literal.When you specify the --fpmode=fast option. When you specify the --fpmode=ieee_full or --fpmode=ieee_fixed options.When you specify the --fpmode=ieee_full option.When you specify the --fpmode=ieee_full, --fpmode=ieee_fixed, or --fpmode=ieee_no_fenv options.When you specify the --fpmode=ieee_full option.When you specify the --implicit_include option.Always set. It is the source line number of the line of code containing this macro.Contains the filename part of the value of __FILE__.When you explicitly or implicitly use the --multifile option. []Always set to 2 by default, unless you change the optimization level using the -Onum option.[a ]__FEATURE_SIGNED_CHAR__FILE____FP_FAST__FP_FENV_EXCEPTIONS__FP_FENV_ROUNDING__FP_IEEE__FP_INEXACT_EXCEPTION--num mod -num__IMPLICIT_INCLUDE__LINE____MODULE____MULTIFILE__OPTIMISE_LEVEL__OPTIMISE_SPACE__OPTIMISE_TIME__PLACEMENT_DELETE---When you specify the -Ospace option. When you specify the -Otime option.In C++ mode to specify that placement delete (that is, an operator delete corresponding to a placement operator new, to be called if the constructor throws an exception is enabled. This is only relevant when using exceptions.In C++ mode when RTTI is enabled.For sizeof(int, but available in preprocessor expressions.For sizeof(long, but available in preprocessor expressions.For sizeof(void *, but available in preprocessor expressions.If compiling to use the software floating-point calling standard and library. Set when you specify the --fpu=softvfp option for ARM or Thumb, or when you specify --fpu=softvfp+vfpv2 for Thumb. In all compiler modes.Standard version information.When you specify the --strict option. Support for signalling NaNs when you specify --fpmode=ieee_fixed or --fpmode=ieee_full. The number of the ARM base architectureof the target CPU irrespective of whether the compiler is compiling for ARM or Thumb. For possible values of __TARGET_ARCH_ARM inrelation to the ARM architecture versions, see .The number of the Thumb base architecture of the target CPU irrespective of whether the compiler is compiling for ARM or Thumb. The value is defined as zero if the target does not support Thumb. For possible values of__TARGET_ARCH_THUMB in relation to the ARM architecture versions, see .XX represents the target architecture and its value depends on the target architecture. For example, if you specify the compiler options --cpu=4T or --cpu=ARM7TDMI then__TARGET_ARCH_4T is defined.XX represents the target CPU. The value of XX__RTTI__sizeof_int-444-__sizeof_long__sizeof_ptr__SOFTFP____STDC____STDC_VERSION____STRICT_ANSI____SUPPORT_SNAN__----num__TARGET_ARCH_ARM__TARGET_ARCH_THUMBnum__TARGET_ARCH_XX-__TARGET_CPU_XX-is derived from the --cpu compiler option, or the default if none is specified. For example, if you specify the compiler option --cpu=ARM7TM then__TARGET_CPU_ARM7TM is defined and no other symbol starting with__TARGET_CPU_ is defined.If you specify the target architecture, then __TARGET_CPU_generic is defined.If the CPU name specified with --cpu is in lowercase, it is converted to uppercase. For example, --cpu=Cortex-R4 results in __TARGET_CPU_CORTEX_R4 being defined (rather than __TARGET_CPU_Cortex_R4. If the processor name contains hyphen (-characters, these are mapped to an underscore (_. For example, --cpu=ARM1136JF-S is mapped to __TARGET_CPU_ARM1136JF_S.__TARGET_FEATURE_DOUBLEWORD__TARGET_FEATURE_DSPMUL__T ARGET_FEATURE_MULTIPLY----ARMv5T and above.If the DSP-enhanced multiplier is available, for example ARMv5TE.If the target architecture supports the long multiply instructions MULL and MULAL .If the target architecture supports thehardware divide instruction (that is, ARMv7-M or ARMv7-R.If the target architecture supports Thumb, ARMv4T or later.One of the following is set to indicate the FPU usage:⏹⏹⏹__TARGET_FEATURE_DIVIDE__TARGET_FEATURE_THUMB__TARGET_FPU_xx--__TARGET_FPU_NONE __TARGET_FPU_VFP __TARGET_FPU_SOFTVFPIn addition, if compiling with one of the following --fpu options, the corresponding target name is set:⏹--fpu=softvfp+vfpv2,__TARGET_FPU_SOFTVFP_VFPV2 --fpu=softvfp+vfpv3,__TARGET_FPU_SOFTVFP_VFPV3⏹⏹--fpu=softvfp+vfpv3_fp16,__TARGET_FPU_SOFTVFP_VFPV3_FP16 --fpu=softvfp+vfpv3_d16,__TARGET_FPU_SOFTVFP_VFPV3_D16 --fpu=softvfp+vfpv3_d16_fp16,__TARGET_FPU_SOFTVFP_VFPV3_D16_FP16 --fpu=vfpv2,__TARGET_FPU_VFPV2 --fpu=vfpv3, __TARGET_FPU_VFPV3 --fpu=vfpv3_fp16,__TARGET_FPU_VFPV3_FP16 --fpu=vfpv3_d16,__TARGET_FPU_VFPV3_D16 --fpu=vfpv3_d16_fp16,__TARGET_FPU_VFPV3_D16_FP16 --fpu=vfpv4, __TARGET_FPU_VFPV4 --fpu=vfpv4_d16,__TARGET_FPU_VFPV4_D16⏹⏹⏹⏹⏹⏹⏹⏹⏹See for more information.__TARGET_PROFILE_R__TARGET_PROFILE_MWhen you specify the --cpu=7-R option. When you specify any of the following options:⏹⏹⏹--cpu=6-M --cpu=6S-M --cpu=7-M__thumb__-When the compiler is in Thumb state. That is, you have either specified the --thumb option on the command-line or #pragma thumb in your source code.Note⏹The compiler might generate some ARM code even if it is compiling for Thumb.__thumb and __thumb__ become defined or undefined when using #pragma thumb or#pragma arm, but do not change in cases where Thumb functions aregenerated as ARM code for other reasons⏹Compiler Reference Guide: Predefined macros Page 6 of 6 (for example, a function specified as __irq. __TIME__ _WCHAR_T [a] time - Always defined. In C++ mode, to specify that wchar_t is a keyword. ARM recommends that if you have source code reliant on the __OPTIMISE_LEVEL macro to determine whether or not --multifile is in effect,you change to using__MULTIFILE. Table 29 shows the possible values for__TARGET_ARCH_THUMB (see Table 28, and how these values relate to versions of the ARM architecture. Table 29. Thumb architecture versions in relation to ARM architecture versions ARM architecture __TARGET_ARCH_ARM__TARGET_ARCH_THUMB v4 v4T v5T, v5TE, v5TEJ v6, v6K, v6Z v6T2 v6-M, v6S-M v7-R v7-M, v7E-M 4 4 5 6 6 0 7 0 0 1 2 3 4 3 4 4 Built-in function name variables. Copyright © Keil, An ARM Company. All rights reserved.mk:@MSITStore:C:\Keil_v5\ARM\HLP\armccref.chm::/armccref_babjf... 2014-6-20。

相关文档
最新文档