【经验】物联网创客指南:MCU设计的最佳实践和除错技巧(三)
在本节中,SiliconLabs将分享在软件开发方面的经验教训。关键词extern,static和volatile都是什么?你应该在你的代码中使用递归还是malloc()?
1)查找硬件设备的现有软件示例
开发任何嵌入式解决方案的第一步是找到可以使您的任务更简单的示例。您在自定义解决方案中找到的特定部分的软件示例将帮助您以另一种方式“查看”设备,并帮助您重新解释设备规格,即使这些示例是针对其他计算机架构或软件语言的。
2)编译器的代码
没有完美的计算机软件语言。所有语言都有自己的优势和弱点。用于EFM32家族的Simplicity Studio中使用的软件语言是C。C语言有着很长的历史,它被广泛信任,并且在嵌入式设计上表现良好,但是其语法及特性很难掌握。当你在C中编码时,你实际上是为编译器和其他构建工具编写指令。记住这一点。C语言是“接近金属”的语言,因为您的代码在人类可读格式下编写的代码,汇编代码和二进制映像的构建过程的结果之间仅有几个步骤。
C代码具有严格的类型,要求某些变量匹配得足够好以执行安全赋值。这是为了保护你不要做愚蠢的事情,比如变量(即指针)的地址和变量的内容。但是经常在嵌入式开发中,您需要能够将纯数字转换为地址,以便指定寄存器地址。这需要你熟悉类型转换,以告诉编译器你真的知道你在做什么。
3)使用描述性变量和函数名称
你可以做的最好的事情是确保你的代码设计得很好,使用描述性的变量和函数名。在C代码中没有与长名称关联的运行性能损失。当构建工具将C代码转换为二进制机器码时,将删除所有标识符。请考虑在FAT文件系统(FF)库中找到的以下代码段:
上面的代码有一些注释,这当然有帮助,是一件非常好的事情,但是很难通过查看变量,函数,枚举和预处理符号知道这个代码的确切原因。考虑使用以下代码作为替代:
是的,代码有点宽,难以键入,但Simplicity Studio提供代码完成与CTRL +空格键的快捷键,你可以随时剪切和粘贴。代码可读性会增强,需要更少的寻找变量名。我们可以通过查看第二个例子来说明,这段代码旨在查看目标目录,并在找到目标目录中的已删除(先前已填充但现在可用)或零(从未填充)短文件名条目时中断。描述性名称允许您像读一段故事似得阅读代码,在你阅读时告诉你目的。
4)严肃的对待注释
一个好的软件开发人员在几个关键的地方给代码添加了很多注释。注释,如长变量名,不影响到运行时可执行二进制文件的文件大小,只是在那里,以帮助阅读文档的代码。解决方案中每个文件的顶部应说明该文件的目的,并且在每个函数的顶部应有较长的注释,说明函数的用途以及描述输入和输出。除了这些关键的地方,应该在逐行的基础上使用注释,无论代码的意图清不清楚。使用描述性变量名称可以帮助解释代码的目的,并减少必要的注释,使得那里的注释更突出。相信我,一年后你不会记得当初写代码的目的,所以要重视注释了!
5)使用emlib库
对于EFM32程序员,emlib库是你的朋友。接入EFM32外设时,尽可能的调用这些库。这些库经过良好测试,并有额外的代码来帮助寻找问题,而不仅仅是直接调整寄存器。
例如,以下代码使用emlib库:
TIMER_TopSet(TIMER3, 1000);
相同的事情可以通过预处理器定义寻址内存映射外设的寄存器来完成,定义TIMER3为0x40010C00。我们不使用这个地址,因为它很难被记住,但这是TIMER3映射在主内存中的地方。
TIMER3->TOP = 1000;
所有外设以完全相同的方式映射到内存地址,因此有时您会看到使用此指针表示法的示例,而不是emlib库函数。如果您将看到em_timer.h中的TIMER_TopSet函数定义,您将看到该函数与此示例完全相同,因此在这种情况下,库函数没有提供任何附加值。然而,使用emlib库,有时会得到比简单操作映射寄存器更多的功能。例如,CMU_ClockEnable函数在最终使用“bit band”命令确保寄存器位自动地设置之前,小心地代表您做出很多决定。尽可能频繁地使用这些库函数,以获得所有EFM32库设计师设计的便利性。
6)定义变量以避免堆栈和堆的问题
C的许多方面对于非专业的程序员来说并不明显,但在嵌入式设计中运行代码时变得很重要。对于初学者,所有本地声明的变量都在栈上。这些是您在函数或任何代码块中定义的变量。
堆栈是从“内存顶部”或物理RAM中最高可用地址开始的内存区域,然后向下计数,直到达到堆栈限制。如果您定义了太多的局部变量,或者您的代码通过使用递归或其他嵌套函数动态创建这些变量,那么您的堆栈空间会被占满。
全局变量是在模块级别的所有函数和其他代码块之外定义的变量。编译器自动为heap上的全局声明的变量分配内存,这是堆栈外的主内存池的一部分,如果您尝试分配太多的RAM,将会产生编译器错误。但是,在代码中使用malloc()命令可以动态地在运行时在堆中分配RAM。
在具有有限RAM的嵌入式处理器上使用recursion或malloc()命令是一个冒险的任务!你必须理解你的代码将需要多少递归尝试(或malloc()调用)以便解决问题,然后设计一个永远不会用尽堆栈空间的解决方案。
如果您在代码中定义所有变量并让编译器确定如何自动管理内存,您将遇到较少的超出堆栈或堆的问题。即使有这样的预防措施,如果你的代码几乎是可用的RAM大小,当你编译和构建你的代码,你将需要学习如何监视堆栈和堆的大小,这部分内容超出本节的范畴。
int foo; //Global variable, memory is on the heap
void some_function()
{
int bar; // Localvariable, memory is on the stack
}
7)全局静态变量和局部静态变量的差异
使用关键字“static”定义的变量表示不同范围的不同内容。在内部函数中,static关键字用在变量的前面,以记住它在函数调用之间的值。它具有一种“粘性”,你可以在函数的第一次调用时初始化它,然后让它保持其值,而不是每次函数执行时重新初始化非静态变量。在全局范围,所有变量都是“粘性”的,因为它们只在运行时开始时初始化一次,然后记住它们的值。但是,放置在全局变量前面的static关键字指示编译器该变量对于该模块是本地的,并且不被外部模块使用。对于同一个“static”关键字,这是一个完全不同的含义。
8)volatile和extern的含义及如何相互影响
只要变量和函数在模块中未声明为static,它们就可以在该模块外部使用,并在其他模块中使用。为了告诉编译器你打算在模块中使用相同的变量,你在一个模块中定义一个常规方法的变量,并在设计中所有其他模块的定义之前添加关键字“extern”。现在,您设计中的所有模块都可以访问同一个变量。但是,如果设计中的其他模块中的一个模块意图修改最初定义的位置之外的变量的值,则必须在该变量前面添加关键字“volatile”。这个volatile关键字告诉编译器该变量可以在模块之外更改,并阻止优化器删除似乎没有效果的语句。
此外,当使用Release版本和Debug版本时,使用volatile非常重要。当优化设置增加时,编译器将主动尝试压缩不必要的代码。这意味着您需要防止编译器这样做,通过使用volatile关键字可以改变当前范围之外的任何变量。
在下一节中,我们将继续介绍软件路径的最佳实践,了解内联函数,如何使用闪存,配置锁以及如何解决缓冲区溢
看到这里您是否又有项目灵感需实现,点击下面开发软件帮你忙。
- |
- +1 赞 0
- 收藏
- 评论 1
本网站所有内容禁止转载,否则追究法律责任!
相关推荐
【经验】32位MCU LEUART位周期抖动大,该如何解决?
Silicon Labs 32位MCU EFM32,当基于32.768kHz时钟使用LEUART(@9600bps)进行通讯的时候,发现存约1%误码,原因是什么?如何解决?
设计经验 发布时间 : 2019-09-06
【经验】如何使用32位超低功耗MCU外设反射系统功能?
外设反射系统(PRS)是 Silicon Labs EFM32系列MCU专有的外设互联总线,它允许不同的外设无需CPU干预即可直接相互通信。
设计经验 发布时间 : 2019-09-02
【经验】32位MCU的LDMA实现ADC至RAM的数据传输调试方法
Silicon Labs的EFM32PG/ EFM32JG系列32位MCU具有超低功耗、高性能、丰富的外设等特点,其 LDMA相比于series 0的DMA具有更多的传输方式,更适合应用于电池供电的产品。
设计经验 发布时间 : 2018-02-08
世界上最节能的微控制器EFM32之十大低功耗奥秘
Silicon Labs EFM32 32 位微控制器系列是世界上最为节能的微控制器,特别适用于低功耗和能源敏感型应用,包括能源、水表和燃气表、楼宇自动化、警报及安防和便携式医疗/健身器材。本文着重强调10个Silicon Labs32位MCU功耗低的因素。
新产品 发布时间 : 2016-07-11
全球超低功耗MCU的关键:灵活的能源管理单元
Silicon Labs EFM32小壁虎系列MCU,作为当今全球功耗最低功耗的MCU,EFM32成为电池供电等对低功耗要求较高场合的不二之选!
技术探讨 发布时间 : 2019-07-19
如何读取EFM32系列32位MCU的多通道AD扫描采样数据?
EFM32系列单片机ADC的数据保存寄存器有两个,一个是单通道模式的采样数据保存寄存器,一个是扫描模式的采样数据保存寄存器。如果使用多通道扫描采样,那么每个通道采样完成后会产生一个ADC扫描模式中断,用户需要在中断里面读取该通道的扫描采样数据以便存储下一个通道的采样数据。建议使用DMA读取方式,将DMA的触发源设置为ADC的扫描模式事件,这样就可以实现不用进入ADC中断以及MCU的参与即可完成ADC扫描采样数据的保存和读取。
技术问答 发布时间 : 2017-05-05
如何为Silicon Labs 32位低功耗MCU EFM32GG230F512实现基于RTC的软件无滴答日历?
在Silicon Labs 32位低功耗MCU EFM32GG230F512上实现软件方式的无滴答日历,可以通过使用日历标准C库 time.h, 在time.h中实现的timer()函数基于RTC计数值来计 算日历时间。
技术问答 发布时间 : 2017-10-10
Silicon Labs 32位低功耗MCU EFM32GG990芯片使用中,将OPAMP(运算放大器)组合成三运放差分放大器时可选的放大倍数为多少?
当将三个OPAMP组合成差分放大器时,差分放大器的增益是由OPA0和OPA1的组合增益所决定的,由于三运放差分电路的电阻网络对应的桥臂要对应成比例,所以只三种有 效的差分增益可供使用,它们分别为1/3、1和3,此时OPA0 RESSEL和OPA2 RESSEL的组合分别为0和4、1和1、4和0。
技术问答 发布时间 : 2017-10-10
Silicon Labs EFM32系列32位低功耗MCU Cortex系列微控制器采用的软件接口标准CMSIS有哪些特性?
嵌入式系统越来越复杂,开发和软件测试的工作量也显著增加,为了减少开发时间并且降低产品中存在的风险,软件重用已经越来越普遍。为了各种软件产品间的配合,ARM同各大 微控制器供应商、工具供应商和软件解决方案提供商一起开发了CMSIS,一个涵盖了大多数Cortex-M处理器和Cortex-M微控制器产品的软件框架。 CMSIS的设计目标和特性包括以下几点: 1、提高软件的可用性。 2、提高软件的兼容性。 3、独立的工具链特性。 4、开放性。 5、易用性。
技术问答 发布时间 : 2017-10-10
【应用】EFM32TG11低功耗32位MCU在超声波水表上的应用
Silicon Labs的32位MCU EFM32TG11,最高主频48MHz,37uA/MHz的全速运行功耗,1.3uA休眠EM2模式功耗,集成低功耗LCD驱动,最大128KB大容量Flash,32PIN到80PIN多种可选封装,将助力于超声波水表超低功耗,多功能,低成本设计。
应用方案 发布时间 : 2019-03-26
32位低功耗MCU EFM32系列内部的LFRCO是32K还是32.768K?
EFM32系列32位低功耗MCU内部的LFRCO为32K。
技术问答 发布时间 : 2017-10-10
Silicon Labs EFM32系列32位低功耗MCU的硬件设计时要关注什么?
1、对于Silicon Labs EFM32系列32位低功耗MCU的系统设计者,有几个值得关注的因素,包括如何为芯片提供鲁棒性的电源,如何连接外部调试接口以及如何设计外部时钟源。 2、电源: 尽管EFM32支持宽的电压范围并且消耗很小的平均电流,但是正确的去耦是极其重要的。对于高频暂态信号去耦电容能使得电源和MCU以及地之间的电流回路尽量 短。 3、调试接口及外部复位引脚 (RESETn): 除了可选的SWO(串行线输出), 调试接口包括SWCLK(时钟输入)和SWDIO(数据输入输出)线, 除此之外可 选的SWO(串行线输出)。在无需外部复位的情况下因为复位引脚(RESETn)具有内部上拉电阻所以可以不做连接。强行拉低RESETn引脚将对产生EFM32触发复 位。 4、外部时钟源: EFM32除了内部低频和高频RC振荡器模式外也支持不同的外部时钟源来产生低频以及高频时钟。可能的低频LF和高频HF域外部时钟源是外部振荡器(方 波或者正弦波)或者晶体/陶瓷谐振器。
技术问答 发布时间 : 2017-10-10
Silicon Labs EFM32系列32位低功耗MCU Cortex-M3内核嵌套向量终端控制器(NVIC)有哪些特性?
1、支持最多240个中断输入、不可屏蔽中断输入和多个系统异常。除了NMI外,每个中断都可以被单独使能或禁止。 2、中断和多个系统异常具有可编程的优先级。对于Cortex-M3/M4,优先级可以在运行时动态修改(注意,Cortex-M0/M0+不支持优先级的动态修改)。 3、嵌套中断/异常以及中断/异常按照优先级自动处理。 4、向量中断/异常。意味着处理器会自动取出中断/异常向量,无需软件确定产生的是哪个中断/异常。 5、向量表可以重定位在存储器中的多个区域。 6、低中断等待。对于具有零等待状态的存储器系统,中断等待仅为12个周期。 7、中断和多个异常可由软件触发。 8、多个优化用于降低不同异常上下文切换时的中断处理开销。 9、中断/异常屏蔽功能可以将所有的中断和异常(NMI除外)屏蔽掉,或者将中断/异常屏蔽为某个优先级之下。 为了支持这些特性,NVIC使用了多个可编程寄存器。这些寄存器经过了存储器映射,而CMSIS-Core则为大多数常见的中断控制任务提供了所需的寄存器定义和访问函数 (API),这些访问函数非常已于使用。
技术问答 发布时间 : 2017-10-10
EFM32系列低功耗32位MCU GPIO的最大翻转速度为多少?
Siliocn labs低功耗32位MCU EFM32 GPIO的最大翻转速度为系统时钟的1/6。例如,当主频为32MHz时,GPIO最大翻转速度大约为5.3MHz
技术问答 发布时间 : 2017-10-10
Silicon Labs 32位低功耗MCU EFM32G232F128系列微控制器GPIO的最大翻转速度为多少?
EFM32G232F128系列微控制器GPIO的最大翻转速度为系统时钟的1/6。例如,当主频为32MHz时,GPIO最大翻转速度大约为5.3MHz。
技术问答 发布时间 : 2017-10-10
电子商城
现货市场
登录 | 立即注册
提交评论