成为一名正式的嵌入式开发工程师。 这是一个艰苦的过程,需要开发人员维护和管理系统的每一个比特和字节。 开发高可靠性嵌入式系统的技术有很多,从规范的开发周期到严格的执行和系统检查。 今天我就给大家介绍7个简单易操作又持久的小技巧。 他们将在确保系统更可靠地运行并捕获异常行为方面做出很大的努力。
技巧 1 - 用已知值填充 ROM
软件开发人员往往是一群非常乐观的人,他们只希望他们的代码能够长期忠实地运行,仅此而已。 微控制器跳出应用程序空间并在非预期的代码空间中执行的情况似乎很少见。 然而,发生这种情况的可能性并不比缓冲区溢出或坏指针丢失其引用的可能性低。 它确实发生了! 发生这种情况后的系统行为将是未定义的,因为内存空间默认都是0xFF,或者因为该内存区域通常不被写入,所以里面的值可能只有上帝知道。
然而,有相当完整的链接器或 IDE 技术可用于帮助识别此类事件并从中恢复系统。 诀窍是使用 FILL 命令用已知的位模式填充未使用的 ROM。 为了填充未使用的内存,可以使用许多不同的可能组合,但如果您想构建更可靠的系统,最明显的选择是将 ISR 故障处理程序放置在这些位置。 如果系统出现问题并且处理器开始执行程序空间之外的代码,则会触发 ISR,并提供在决定纠正操作之前存储处理器、寄存器和系统状态的机会。
提示 2 – 检查应用程序的 CRC
对于嵌入式工程师来说一个很大的好处是,我们的IDE和工具链可以自动生成一个应用程序或内存空间校验和(Checksum),根据这个校验和来验证应用程序是否完好。 有趣的是,在许多情况下,校验和仅在将程序代码加载到设备上时使用。
但是,如果 CRC 或校验和保存在内存中,则验证应用程序在启动时是否仍然完好无损(或者对于长时间运行的系统甚至定期验证)是确保不会发生意外情况的绝佳方法。 现在,已编程的应用程序发生更改的可能性很小,但考虑到每年出货的数十亿个微控制器以及潜在的恶劣工作环境,应用程序崩溃的可能性并非为零。 更有可能的是,系统中的缺陷可能会导致扇区发生闪存写入或闪存擦除,从而损害应用程序的完整性。
技巧 3 – 在启动时执行 RAM 检查
为了构建更加可靠、坚固的系统,确保系统硬件正常工作非常重要。 毕竟,硬件可能会出现故障。 (幸运的是,软件永远不会失败,它只是执行代码告诉它执行的操作,无论这是正确还是错误)。 验证启动时 RAM 内部或外部没有问题是确保硬件按预期运行的好方法。
执行 RAM 检查有许多不同的方法,但常见的方法是写入已知模式,然后等待一小段时间再将其读回。 结果应该是读到的就是写到的。 事实上,在大多数情况下,RAM 检查都会通过,这正是我们想要的。 然而,检查不通过的可能性很小,这为系统标记硬件问题提供了绝佳的机会。
技巧 4 – 使用堆栈监视器
对于许多嵌入式开发人员来说,堆栈似乎是一种相当神秘的力量。 当奇怪的事情开始发生时,工程师们终于被难住了,并开始思考,也许堆栈中发生了一些事情。 其结果是盲目地调整堆栈的大小和位置等。但是该错误通常与堆栈无关嵌入式系统软件教程,但如何能够如此确定呢? 毕竟,有多少工程师实际上执行过最坏情况堆栈大小分析?
堆栈大小在编译时静态分配,但堆栈以动态方式使用。 当代码执行时,变量、返回地址和应用程序所需的其他信息连续存储在堆栈中。 这种机制导致堆栈在其分配的内存中不断增长。 然而,这种增长有时会超出编译时确定的容量限制,导致堆栈损坏相邻内存区域中的数据。
绝对确保堆栈正常工作的一种方法是实现堆栈监视器作为系统“健康”代码的一部分(有多少工程师这样做?)。 堆栈监视器在堆栈和“其他”内存区域之间创建一个缓冲区,并填充已知的位模式。 然后监视器持续监视模式是否有任何变化。 如果位模式发生变化,则意味着堆栈已经变得太大,即将将系统推入黑暗地狱! 此时,监视器可以记录事件的发生、系统状态以及任何其他有用的数据,以供以后用于问题诊断。
大多数实时操作系统 (RTOS) 或实现内存保护单元 (MPU) 的微控制器系统中都提供堆栈监视器。 可怕的是,这些功能默认是关闭的,或者经常被开发者故意关闭。 网上一搜,很多人建议关闭实时操作系统中的堆栈监视器,以节省56字节的flash空间等,这是得不偿失的!
技巧 5 - 使用 MPU
过去,很难在小型、廉价的微控制器中找到内存保护单元 (MPU),但这种情况正在开始改变。 现在从高端到低端的微控制器都有MPU,这些MPU为嵌入式软件开发人员提供了大幅提高其固件鲁棒性的机会。
MPU 越来越多地与操作系统耦合,以创建分离处理的内存空间,或者任务可以执行其代码而不必担心被踩踏。 如果确实发生情况嵌入式系统软件教程,将取消不受控制的处理并实施其他保护措施。 请留意带有此组件的微控制器,如果有,请利用此功能。
技巧 6 – 建立强大的看门狗系统
您经常会发现的最流行的看门狗实现之一是启用看门狗的位置(这是一个好的开始),但也可以使用周期性计时器来清除看门狗; 定时器的启用与程序中发生的任何事情完全隔离。 使用看门狗的目的是帮助确保如果发生错误,看门狗不会被清除,即当工作暂停时,系统将被迫执行硬件复位以便恢复。 使用独立于系统活动的定时器,即使系统出现故障,看门狗也可以保持清零状态。
嵌入式开发人员需要仔细考虑和设计如何将应用程序任务集成到看门狗系统中。 例如,一种技术可能允许每个运行一段时间的任务指示它已成功完成其任务。 在这种情况下,看门狗不会被清除并被强制复位。 还有更先进的技术,例如使用外部看门狗处理器,可用于监视主处理器的执行情况,反之亦然。 对于一个可靠的系统来说,建立一个强大的看门狗系统非常重要。
技巧 7 - 避免易失性内存分配
不习惯在资源受限环境中工作的工程师可能会倾向于使用其编程语言的功能,以允许他们使用易失性内存分配。 毕竟,这是计算器系统中经常使用的技术,仅在必要时才分配内存。 例如,在用C语言开发时,工程师可能倾向于使用malloc在堆上分配空间。 将执行一个操作,一旦完成,就可以使用free来返回分配的内存,以便可以使用堆。
在资源受限的系统上,这可能是一场灾难! 使用易失性内存分配的问题之一是错误或不正确的技术可能导致内存泄漏或内存碎片。 如果出现这些问题,大多数嵌入式系统没有资源或知识来监视堆或正确处理它。 当他们这样做时,如果应用程序请求空间但所请求的空间不可用,会发生什么?
使用易失性内存分配带来的问题非常复杂,处理得当可以说是一场噩梦! 另一种方法是直接以静态的方式简化内存的分配。 例如,无需通过 malloc 请求此大小的内存缓冲区,只需在程序中创建一个 256 字节长的缓冲区即可。 在应用程序的整个生命周期中都会维护分配的内存,而无需担心堆或内存碎片问题。
综上所述
以上嵌入式开发教程可以让开发技术人员对嵌入式系统有更好的想法。 所有这些技术都是设计人员能够开发更可靠的嵌入式系统的秘诀。
特别推荐