在咱们有关DSP的论坛、博客和一些互动活动中,网友常常会问一些有关“编程技巧”的问题。
关于编程技巧的界说,也没有一个一致的规范,例如完结一个很杂乱的多层嵌套的指针规划算是一种编程娴熟的表现吧;又或许用C/C++的高档特性做了很杂乱的功用,可是编译器不能彻底支撑,例如某种内存的动态重分配办法,这时对编译器特性的了解就显得很重要了。
接下来咱们就聊一聊DSP编程技巧里边有关编译技巧的一些问题,详细的分类包含编译器的选项、代码的优化、库文件的运用、代码完结规范、实时运转环境等等;了解了这些详细的问题,关于处理在编译和链接程序的时分常常遇到的让人摸不着头脑的正告和过错也是很有协助的;由于程序的语法过错很简略被编译器发现并定位到详细的代码中,而链接器输出的那些不可思议的正告是很难定位的,假设了解了编译流程中各个环节的效果地点,就有了对症下药的进口。编译器主要以TI的CCS编译器为例,方针器材为28系列,比较6000系列的,28系列的要略微简略一些。
首要要了解一下依据CCS开发的一个完好流程,避免“只见树木,不见森林”:
由于很少有文档把它们的详细汉语含义讲清楚,所以在此咱们要用浅显的言语描绘一下各个部分:
1. 在这个流程中,与咱们编程功率直接相关的便是C/C++编译器了(假设没有运用汇编直接编写的话),它的直接用处是将C/C++代码编译为针对DSP汇编指令集的汇编代码。
现在的C和C++言语规范有好几个版别,CCS的编译器现在支撑的版别包含:
C言语的C89和C99版其他ISO规范(C99部分支撑,主要是与C89相同的特性):浅显的讲便是咱们学过的C言语里常用的功用都是支撑的,除了一些多字节字符和一些极少数的特性等。不清楚的能够参阅Kernighan和Ritchie编写的C言语书本《The C Programming Language》第二版。
C++言语的2003版其他的ISO规范: 能够参阅Ellis和Stroustrup编写的经典书本《The Annotated C++ Reference Manual》。一起也支撑一部分的嵌入式C++特性。由于C++的特性很多,而许多并不适用于这样一种嵌入式的环境,所以不支撑的特性比较C要多一些。
2. 汇编器的效果是将汇编言语代码转化为机器言语(方针文件),这儿的汇编代码包含前面由C/C++生成的汇编代码和咱们直接编写的汇编代码。
3. 链接器是效果是把一切的库文件、方针文件等链接成为一个可履行的方针文件,其间包含程序的机器代码和数据,以及其他用来链接和加载该程序所需的信息(在TI DSP上是COFF格局,浅显地讲便是.out二进制文件),一起依据内存地址的分配对各方针文件进行重定位,并解析外部参阅,例如在一个源程序里引证另一个源程序中界说的变量就能够了解为外部参阅,假设一个方针文件引证了一个未界说的符号symbol,则链接器查找其他方针文件中界说的大局符号,找到匹配的符号修补指令。不然陈述一个过错;所以有时分编译一切程序完结在链接的时分会提示xxx symbol为界说,阐明对应的文件没有加到工程里边。 4. 归档器archiver:也能够叫压缩器,看一下咱们常用的压缩软件winrar的全称winrar archiver就不难了解了。
5. 实时支撑库:包含规范C和C++的运转支撑函数、编译器共用程序函数、浮点运算函数和C编译器支撑的I/O函数,
6. 十六进制转化程序:把编译、链接等进程生成的可履行文件,转化为十六进制文件,例如.HEX格局,然后能够烧写到EEPROM、FLASH等外部存储器之中。
7. 肯定列表器:读取方针文件并输出.abs文件,经过汇编.abs文件可发生含有肯定地址的列表文件,然后使得咱们不必手艺费时吃力地去创立列表文件。这原本不便是软件该做的工作吗:-D
8. 穿插引证列表:与3中外部参阅解析相关的,它用方针文件发生参照列表文件,可显现符号及其界说,以及符号地点的源文件。
9. C/C++命名复原东西:C/C++编译器会将程序中的变量名、函数名转化成内部称号,这个进程被称作Name Mangling,反进程被称作Name Demangling,即命名复原东西。内部称号包含了变量或函数的更多信息,例如编译器看到?g_var@@3HA,就知道这是:int g_var。详细的复原规矩一般是不开放给咱们用户的,只需编译器知道就行了。
10. 调试东西:例如咱们电脑上装的CCS软件,让咱们能够用断点、图形窗口等进行软件的调试。
此外,并没有清晰列在前面的流程中,可是隐含在流程中,或许咱们也有或许会用到的东西或许流程包含:
1. 优化东西:在编译时对代码进行优化的东西,能够依据咱们希望的优化等级,进行从不优化到直至CPU寄存器等级的优化。
2. 反编译器:能够对方针文件进行解码,显现对应的汇编言语。在CCS的调试形式下,咱们能够翻开disassembler窗口,然后单步运转,就能看到一条条的汇编指令是怎么履行的了。
3. 加载器:把可履行的二进制文件复制到DSP的内存中,并运转发动程序,使得程序从程序进口处开端运转,这个进口地址或许是地址0,也或许是带有一个偏移量的地址,这个详细的值咱们能够今后再详细评论。
4. 其它:弥补一下名词的界说,包含:
符号:在整个编译、链接的进程中都会运用到符号symbol的概念,简略地了解,符号便是指一些变量、函数姓名等。
库文件:多个方针文件的压缩包,包含了一切方针文件界说的大局符号的索引。在源程序中假设找不到某些符号的界说,链接器从测验从库里边提取出对应的方针文件,然后链接到可履行文件里。
或许你现已娴熟运用了CCS好多年,可是当某一天呈现一个与cl2000有关的过错的时分,突然间也摸不着头脑了;例如运用老版其他还不支撑C2000 FPU的CCS来编译28335的程序,cl2000就会提示你各种不支撑然后报错不运转了。Cl2000.exe是神马?
Cl2000.exe便是和咱们的程序编译密切相关的编译器了,运用的办法是:
cl2000 [编译器选项] [需求编译的文件] [–运转链接器 [链接器选项] 方针文件]]
运用办法看起来很杂乱,还好CCS现已帮咱们调用它了(或许说CCS便是一个结构,它完结的编译、调试、链接等功用简直都需求调用一些其他exe来履行,所以你或许领会过晋级了一些库文件、编辑器版别等,界面文件等却不需求进行任何的更改),这些语句会显现在工程的特点里边。当然假设你想亲身体会一把,也能够在ccs装置目录下面的toolscompilerc2000_6.1.5bin下面找到它,即cl2000.exe,然后用命令行的办法运转起来)。举个简略比如:
cl2000 -v28 symtab.c file.c seek.asm –run_linker –library=lnk.cmd
–output_file=myprogram.out 在上面的比如中,假设需求编译的文件,例如几个.c或许.asm找不到,CCS就会提示xxx.c或许xxx.asm找不到或许未界说了;或许你改了方针文件的姓名,例如改成了a.out,可是加载程序到DSP中的时分却依然运用更改前的b.out,天然有或许呈现意料之外的成果了:在曾经协助网友处理问题的时分,的确呈现过这样的情况。
理解了编译器的调用办法之后,咱们就更进一步,揭开编译器中五花八门选项的奥秘面纱,从此看到编译器提示的五花八门的正告和过错不再用发怵。
详细说来,编译器的选项有多大20个大类,超越一百个详细的选项。当然这些选项是有轻重之分的,有的是有必要用到的,例如支撑一下FPU等功用;有的则是不常触摸的,例如MISRA这样的轿车工业软件可靠性查看,只要在对软件进行规范化时才会用到。所以咱们首要看一下最常用的选项,例如处理器的选项,它们的含义在于界说了在编译程序时CPU的形式。弥补一点是,cl2000的协助里看到的选项都是很长的姓名,在CCS里边为了书写便利(由于选项框就那么点面积啊),一般用别号来替代;没有别号的则直接运用选项姓名。