物联网创客指南:EFM32 MCU设计的最佳实践和除错技巧(五)

Lee_的头像
Lee_ 发布于:周五, 04/07/2017 - 15:35 ,关键词:

本系列设计指南的第五篇文章将教您如何像Pro一样构建源代码。在Simplicity Studio中构建代码是很简便的,因为安装程序会为您设置所有内容,您可以在安装程序完成后几分钟内开始调试项目。但不要过分依赖构建工具。这些工具不能代替你完成所有工作,而且您可能对这些工具感到失望。把C语言转换为二进制,然后写到你的MCU这一过程背后有许多步骤。

1 不要忘记复制或连接emlib文件

当您从头开始创建一个新项目并开始使用em_cmu.h或em_emu.h等emib库时,您将需要在新项目的emlib目录中复制或连接这些头文件的实现文件。Simplicity Studio自动链接到所有标准emlib库的头文件(.h文件),但不链接到实现文件。因此,您可以访问包含这些库文件的Simplicity Studio安装文件夹,并将其复制到emlib目录中,或使用Simplicity Studio的project Properties连接到这些文件。

复制或连接实现文件有不同的好处和代价。如果将实现文件复制到项目中,则项目将保留一个库文件的实现的私有副本,该文件不会随着Simplicity Studio版本的更新而改变。但是,头文件将随着Simplicity Studio版本的更新而改变。这可能会在库文件的声明和实现之间产生一些不匹配。如果连接到实现文件,您的库文件将随着Simplicity Studio版本的更新而改变,这可能会对您的软件产生不利影响。最适合您的解决方案是将头文件和实现文件复制到项目中,并删除头文件的链接。

请注意,如果您忘记添加库的实现文件的链接或副本,则仅在头文件中实现的某些功能仍然可以正常工作,而.c文件中实现的功能有时会在构建输出中给出不明显的错误。

2 从上到下解决问题

无论何时构建代码,编译器将向Simplicity Studio中的构建输出控制台窗口发送大量信息。窗口滚动,如果它发现错误,您的构建控制台将停在它发现的最后一个错误处。你不应该调试最后一个错误。调试编译器找到的第一个问题。在构建过程中稍后发生的警告和/或错误可能是由第一个错误引起的,如果您尝试解决由根问题引起的后续问题,您将会逐步解决错误。您还可以使用Simplicity Studio构建控制台底部的“Problems”选项卡。

3 不要忽略警告

默认状态下,编译器在构建过程中忽略警告。如果您的代码生成错误,构建将失败,但如果它仅生成警告,则构建将成功,然后可以使用该程序来写入MCU。您可能甚至不会注意到在构建控制台窗口上的警告。你必须向后并寻找任何具有淡黄色背景的行。确保您明白警告在告诉您什么。一些警告,如未使用的变量警告,您可以安全地忽略。但是,如果您想使用对计算很重要的变量,则警告将帮助您从逻辑上不正确的解决方案中拯救出来。如果您解决了所有的警告,则在构建过程开始时,您将看不到带任何色彩的背景。

为了在调试期间监视功能的输出,有时候会留下未使用的变量警告,这不是问题。这种情况下,您可以使用C编译器属性指令告诉编译器,未使用的变量是有意的,如以下代码:

uint32_t__attribute__((unused)) foo = some_function_with_return_value_to_inspect() ;

或者,您可以在整个代码中创建一个预处理器指令:
#defineUNUSED __attribute__((unused))
void some_function()
{
intUNUSED foo = some_function_with_return_value_to_inspect();
}

还有一件事情,你可以去除功能中未使用的参数。有时,您不需要在预定义的函数中使用给您的所有功能,如在中断处理程序或其他系统定义的回调函数中。通过在自定义实现中声明函数参数为void,您将告诉编译器您不打算在实现中使用这些参数。

void some_function(int foo)
{
(void) foo;
}

请注意,如果您碰巧错过在构建窗口的某处的警告,则会将该文件标记为已构建,并且在该模块发生更改之前不会重新构建,因此直到再次进行更改您将看不到警告。这可能会导致在不相关的代码被修改时,在后来的版本中出现问题。您可以随时通过从Project Clean...菜单选项清除构建环境,然后重新运行构建工具来强制重建所有文件。

您可以将编译器配置为将警告视为错误,如果您志在清理所有警告。将此选项设置为:

Project > Properties > C/C++ Build Settings >Warnings > Warnings asErrors (-Werror)

4 解释构建输出大小报告

当您构建项目时,一堆文本在构建输出控制台上滚动。完成后,如果构建成功,在显示“Build Succeeded”之前的最后一件事是运行大小工具:

arm-none-eabi-size"energy_profile_only.axf"
textdata bss dec hex filename
1188104 32 1324 52c energy_profile_only.axf

这个工具是给你一个关于你刚刚建立的代码需要的闪存和RAM的报告。这里是什么这些东西的意义:

文本:
EFM32闪存保留,用于编程指令和常量的字节。中断矢量表也被包括在该存储中。
数据:
由初始化数据的值被用于在预留的EFM32闪存中的字节数。这些都是会被分配到程序启动或函数调用的普通变量的值。
BSS:
程序启动时RAM保留的字节数,是程序所需的全局变量的总和,在堆顶部结束。
Dec:
文本+数据+ BSS的总和。这个数字有没有实际意义。

如果您尝试构建一个具有比您的特定EFM32部分可用内存更多的RAM的文件,那么您甚至不会访问构建报告。你会得到一个相当直接的编译器错误。例如:
int really_big_array[10000];
void some_function()
{
really_big_array[0] = 0;
}
int main(void)
{
/* Chip errata */
CHIP_Init();

some_function();
}

结果:
c:/...bin/ld.exe:some_program.axf section `.bss' will not fit in region `RAM'
c:/...bin/ld.exe:region RAM overflowed with stack
c:/...bin/ld.exe:region `RAM' overflowed by 7368bytes

请记住,这是在程序开始运行时分配的内存。程序启动后使用的内存量将根据调用的函数和动态分配的内存而改变。

5 对项目属性中的构建过程进行更改

项目属性菜单选项有许多设置可以控制您的构建。这个工具避免了复杂的命令行操纵,并将所有设置存储在项目目录中的.project和.cproject文件中。在Project> Properties > C/C++ Build Settings菜单中配置构建过程的最重要的方面。在这里,可以选择整体构建,无论您正在构建能够调试或准备发布的项目。然后,Memory Layout, C Compiler,Assembler, 和Linker tools都可以单独控制,这使您具有相同的功能和灵活性,就像您已经从命令行运行这些工具一样。

调试版本允许您单步执行并检查变量和内存的内容,但对于性能或代码大小来说不是最佳的。选项树上的顶级节点是Debug Settings,它允许您控制调试级别。

发布版本针对更好的性能和代码大小优化,可以在GNU ARM C编译器 Optimizations菜单中的相同Settings区域内控制优化级别。您可以看到,选择“Release vs. Debug”将优化级别从Most(-O3)更改为None(-O0)。

Settings菜单中的Memory Layout菜单项可让您将程序以闪存和RAM的形式放在您指定的地址上。如果您的需要很复杂,您可以使用自定义链接描述文件,或者只需点击Override default flash options或Override default RAM options的选项。通过覆盖默认的闪存选项的原点,您可以将多个程序写入同一个 EFM32芯片而不擦除其他。这是引导程序的配置方式。

引导加载程序通常从地址0开始,并且大小受限(使用LENGTH参数),以便使构建工具警告您的引导程序是否变得太大,无法适应分配的空间。然后,您的应用程序(Simplicity Studio中完全不同的项目)以高于引导加载程序的地址启动。这样,通过JTAG从Simplicity Studio加载您的应用程序代码不会擦除引导加载程序。请注意,为了使您的应用程序代码以零以外的地址运行,引导加载程序必须使用应用程序的地址正确加载程序计数器,以便应用程序可以从复位运行。有关引导加载程序的更多详细信息,请参见第16章。

6 在构建文件中进一步调查构建工具输入和输出

当您的构建过程完成并且成功构建,Simplicity Studio将构建过程的输出文件放置在项目中的两个目录之一中。这些目录称为GNU ARM v4.8.3 - Debug或GNA ARMv4.8.3 - Release,具体取决于您的构建是否是调试或

这些目录是构建过程的工作文件夹,不应直接修改 - 它们将被覆盖在每个构建中,因此可以从版本控制系统中排除。这些目录包含用作某些构建工具和某些工具的输出的输入的文件。但是,您可以检查构建过程的结果,以查看哪些工具正在执行。详细描述这些文件超出了本章的范围,但下表提供了一个总结。

makefile和* .mk文件:
根据Project Properties的设置,用于配置编译器的脚本或“make”工具,由Simplicity Studio自动生成。

.ld
基于Project Properties的设置,Simplicity Studio代表您生成的链接描述文件。链接在编译器之后运行。

.map
链接工具的输出。该文件包含有关内存中构建工具放置您的功能和数据的信息。

.axf
对象代码加调试器信息。该文件由Simplicity Studio调试器使用,可以在设备上实时调试软件

.hex
您构建的机器代码的ASCII文本表示

.bin
机器码二进制图像。这是在编程期间最终将转换为Flash的文件以及用于引导加载程序的源文件。

在下一节中,我们将介绍最后一步,在EFM32上调试软件。

围观 460