APP下载

编译器无关性编码在微控制器中的优势

2010-07-02SiliconLabs公司EvanSchulz

单片机与嵌入式系统应用 2010年2期
关键词:编译器源代码开发人员

Silicon Labs公司 Evan Schulz

嵌入式设计者通常要面对更短的设计周期、不断变化的需求和日益增长的工作负担所带来的问题。然而在嵌入式设计中,能够降低设计风险、节省时间和减少精力的编译器无关性编码却往往最易被忽略。对任何项目来说,为微控制器编写编译器无关性代码可以获得更大的灵活性。

工欲善其事,必先利其器

编译器无关,使得设计者能够基于他们的项目需求选择合适的编译器。通过对比不同的编译器,可以清楚地看出相同条件下不同工具链的性能差异。每个编译器都具有与其他编译器相区别的自身特性。有的编译器优化汇编功能,使生成的代码非常小;有的更专注于执行速度;也有的根本不进行任何优化。在微控制器选择过程中,如果应用程序代码的大小是最终的决定因素,那么代码大小的优化程度将是一个重要的参考。如果不考虑代码大小,那么许可证费用或许是一个问题。如今,8051编译器的价格范围从每个许可证数千美元到无需任何费用不等。通过创建一个编译器无关的项目,开发人员将有更大的灵活性,可以轻松地从一种工具链转移到另一种。

对于过度依赖特定工具链的开发人员来说,如果选择的特定编译器突然变得不可再用,那将成为一个负担。例如,如果开发人员仅使用特定编译器完成整个项目,那么一旦不能使用该工具链将对项目非常不利。然而在相同的示例中,如果开发人员以编译器无关的形式编写代码,在切换到一个新的工具链时,仅需要对一个头文件进行少量的修改。该代码可能需要一些小的修改以避免编译器错误或警告,但总体来说,切换编译器的付出是微不足道的。

编译器无关性编码的实现

使项目编译器无关非常简单,设计者只需添加一个头文件,其中包括为编译器相关的典型C语言进行的宏定义。

在一个头文件中说明编译器相关语法的不同之处,而不是针对特定编译器编写整个项目。这样,如果编码需要用于另一个工具链或选择的编译器无法使用时,开发人员的适应能力会更强。这种编程方法所带来的益处和便利,使得微控制器代码的开发过程更有效、更灵活。

立竿见影的益处是源代码可读性提高,调试时间显著缩短。采用这种编码方式后,定义的中断、指针和变量能够在一个位置修改,并传播到整个项目。此外,包含在头文件中的特定结构体和全局变量,有助于编译器对多字节数据存储(大端模式/小端模式)的处理。如果编写代码时没有考虑到存储模式的差异,可能会导致错误发生,而且这种错误很难被检查出来,因此应予以重视。

代码重用

除了在编译器之间切换的灵活和便利之外,编译器无关的代码比编译器相关的代码更具有可读性。这种可读性可以缩短调试时间,进而降低项目的整体成本。在一个应用中,不同工程师会在各自完成的项目中使用相同的源代码,这要求源代码能适用于多种工具链。这种情况下,开发人员应详细说明项目中测试通过的工具,以及如何将不同工具链集成到生成项目中。这种灵活性提高了工程师之间代码重用的能力。

如何做到

在源代码中使用宏定义而非编译器相关的语法,是使项目实现编译器无关的基础。

为了支持不同的工具链,项目中仅需的额外文件是一个包含宏定义的头文件。此文件包含一系列if条件语句,if语句中的参数是编译器名称。编译器名称一旦被选用,整个项目将使用该编译器相关的宏定义。因此,若要修改源代码中的多行代码,仅需修改宏定义文件中的一行代码。

试图将一个新的工具链集成到一个项目时,宏定义非常有用。例如,如果在宏定义文件中编写了不正确的中断定义,则开发人员仅需更改一个特定的宏定义,而无需更改源代码中的每一个中断服务程序定义。为了把新的编译器集成到项目中,开发人员需要在宏定义文件中添加一个新段,该段中包括if语句及宏定义列表。在这里,开发人员可以使用编译器相关的语法编写每个宏定义,该语法可以在编译器相关文档中找到。经过对宏定义文件的少量修改,新的工具链将可以与项目兼容。

使用宏定义头文件与使用微处理器相关的头文件的目的是相同的,都是为特殊功能寄存器、地址和位定义而服务的。宏定义头文件是一个被包含的头文件,旨在使代码的开发更加容易。每个编译器有自己特定的语法用于下列项目:

◆中断

◆中断原型

◆寄存器区

◆存储段定义

◆存储段中的定位变量

◆指向存储段的指针

◆空操作(NOP)

◆特殊功能寄存器声明

◆特殊功能寄存器位声明

如果上述任何一项使用了编译器相关的语法,都将使项目不再具有编译器无关性。当切换工具链时,其他潜在的问题包括:多字节存储模式差异、通用指针、寻址和变量的默认值。在大端模式中,编译器保存多字节数据中的最高字节值到最低存储地址;在小端模式中,编译器保存多字节数据中的最低字节值到最低存储地址。如果源代码中有对多字节数的任何操作,要特别注意这一主要差异。

图1 端模式

通用指针格式也可能有所不同。在3字节指针中,某些编译器可能使用最低字节保存存储目标的段地址,其余2个字节保存段内地址。而另一些编译器可能使用最高字节存储目标的段地址,其余 2个字节用来保存段内地址。初始化一个位于特定存储区的变量,也可能导致潜在的问题,因为并非所有的编译器允许变量在定义时初始化。

编译器无关的宏定义头文件的例子和微控制器示例代码可从Silicon Labs官方网站下载:

https://www.silabs.com/products/mcu/Pages/Software-Downloads.aspx

示例代码和编译器无关的宏定义头文件都可以在Silicon Labs的集成开发环境(IDE)中打开。Compiler_defs.h包含以下8051工具链宏定义:SDCC,Raisonance,Keil,Tasking和IAR。存储段、中断、中断原型、寄存器区、定位变量和存储相关指针的宏定义都包含在此文件中。此头文件可用于任何Silicon Labs微控制器,也可用于包含特殊功能寄存器(sfr)、中断向量和可位寻址特殊功能寄存器(SFR)的设备相关的头文件中。当工具链集成到项目时,compiler_defs.h中的宏定义可以作为一个起点。

小 结

微控制器采用编译器无关性代码会带来许多益处和便利,任何开发人员都应考虑这一点。创建编译器无关的项目带给开发人员极大的灵活性。与编译器依赖相关的风险被降低,同时可以对编译器的性能进行测试和对比。改变头文件中的一行代码,即可应用到整个项目,既节省了调试时间,又提高了效率。

猜你喜欢

编译器源代码开发人员
基于TXL的源代码插桩技术研究
基于相异编译器的安全计算机平台交叉编译环境设计
Semtech发布LoRa Basics 以加速物联网应用
软件源代码非公知性司法鉴定方法探析
基于语法和语义结合的源代码精确搜索方法
Microchip为MPLAB XC系列专业版编译器推出低成本可续订包月许可证
揭秘龙湖产品“源代码”
后悔了?教你隐藏开发人员选项
通用NC代码编译器的设计与实现
三星SMI扩展Java论坛 开发人员可用母语