Volatile的用法
编译器有一种技术叫数据流分析,分析程序中的变量在哪里赋值、哪里使用、哪里失效,分析结果可以用于常量合并,常量传播等优化。当它觉察到代码没有修改变量的值时,就可能在访问变量时提供上次访问的缓冲值,这能够提高程序的效率。 但这些优化可能会带来问题(特别是对硬件寄存器操作的程序中),这时需要用volatile关键词来禁止做这些优化。——告诉编译器:变量已经变化,不要用缓存值(变量可能会随时改变,不要对其优化,而是每次用的时候去读写该变量。)
使用volatile变量的场合 硬件寄存器通常要加volatile说明。
#define pFlashA_PortA_Dir (volatile unsigned char *)0x20270006 在中断服务程序中修改的供其它程序检测的变量需要加volatile。 例:中断服务程序常常通过改变一些全局变量来通知应用程序某个外部事件已经发生,这些全局变量不应该被优化。 多任务环境中各任务间共享的标志应该加volatile。
C/C++编译语言扩展
编译器支持对ISO/ANSI 标准的C语言和C++语言的扩展。 为了使C/C++扩展中附加关键字与ISO/ANSI 标准C/C++的关键字不冲突, C/C++扩展中附加关键字在形式上均以双下划线“__”打头。 标准C/C++关键字用一个下划线“_”打头,编译器扩展C/C++关键字用两个下划线“__” 打头; 标准库函数名用一个下划线“_”打头,编译器扩展的库函数(由编译器给出的内嵌函数)名用两个下划线“__” 打头。
内联函数关键字(inline)
inline关键字使声明为inline类型的函数代码内嵌到调用它的地方。inline是C++的标准特点,部分CPU将它作为C的扩展。使用该选项节省了调用函数的额外时间开销,因此提高了程序执行速度。 内联汇编语言关键字(asm)可在C/C++函数中内嵌DSP汇编语言指令。对程序中用C或C++不易或不能高效实现的地方可以用asm()结构利用汇编语言实现。
指定要放置数据的存储器位置的关键字(section)
section关键字使编译器在汇编器的交叉输出文件的.SECTION中放置目标或函数代码。可以用section()中的字符串参数命名.SECTION。如果对目标或函数声明没有指定section(),编译器会使用默认值。
例如: section(“buffer”) int in[1024]={ #include “sine.dat”};
指针受限关键字(restrict)
restrict关键字支持受限制的指针特性。restrict的使用局限于声明一个指针,并指明指针是访问它所指向内容的惟一途径。简单来说,restrict使指针不能使用别名,即两个不同受限指针不能指向同一个对象(指针不能有别名)。
系统库函数(内置函数)
编译器内置函数(Compiler Builtin Function),主要针对一些常用的操作,其实现大多与处理器硬件电路有关。 内置函数一般采用汇编语言编写,一旦用户调用此函数,编译器直接映射到相应的汇编代码中(会被编译器识别出来,使用固定的汇编语句来代替库函数的调用),运行效率很高。 有一些内置函数是系统管理函数,这些内置函数将系统管理的各项操作封装成函数,直接调用这些内置函数将能提高代码的可读性。 例如:ADI BF609 DSP获取系统时钟周期的函数示例如下
使用内联汇编程序,程序可读性差 | 使用ADI提供的内置函数,可读性好 |
unsigned int get_cycles(void) { unsigned int ret_val; asm(“%0=CYCLES;” : ”=d”.(ret_val)::); return ret_val; } |
#include <ccblkfn.h> #include <sysreg.h> unsigned int get_cycles(void) { return sys |