创建可靠的嵌入式系统的7个技巧

尽管有许多嵌入式工程师的希望和梦想,但可靠的代码并不是偶然发生的。这是一个艰苦的过程,需要开发人员维护和管理系统的每个细节。当“成功”验证应用程序时,通常会松一口气,但这仅仅是因为该软件在受控条件下在那一刻正确运行,并不意味着它将在明天或一年后。

从可靠的开发周期到严格的实施和系统检查,有大量技术可以创建可靠的嵌入式系统。整个图书馆很容易装满关于可靠软件设计的书籍,但是容易实施的七个技巧可以确保系统更可靠地执行并捕获意外行为,这很长的路要走。

提示1–用已知值填充ROM

至少就其微控制器随着时间的推移如何忠实地运行其代码而言,软件开发人员往往是一个非常乐观的团队。微控制器跳出应用程序空间并执行代码的想法似乎很少见。但是,发生这种情况的机会无非就是缓冲区溢出或错误指针移开引用。它可以并且确实发生!系统的行为将不确定,因为默认情况下内存可能在空间中所有0xFF都存在,或者由于通常未写入内存区域,所以值可能已经衰减,只有上帝知道。

有一个简洁的链接程序或IDE技巧可以用来帮助从此类事件中识别并恢复系统。技巧是使用FILL命令以已知的位模式填充未使用的ROM。有许多不同的组合可以用来填充未使用的内存,但是如果要构建一个更可靠的系统,显而易见的选择是将ISR故障处理程序放置在该位置。如果出现问题,并且处理器开始在程序空间之外执行代码,那么ISR将触发,从而在决定采取正确的措施之前将提供存储处理器,寄存器和系统状态的机会。

有关如何使用FILL的其他信息以及使用FILL的替代策略,请参见“使用FILL改善代码完整性”。 这里.

提示2 –检查应用程序CRC

嵌入式工程师可以使用的出色工具之一是,我们的IDE和工具链可以自动生成应用程序或内存空间校验和,可以从中验证应用程序。有趣的是,在许多情况下,仅在将程序代码加载到设备时才使用它!如果内存中存在CRC或校验和,则在启动时(甚至对于长时间运行的系统定期验证)应用程序是否完好是确保不会发生意外情况的好方法。现在,已编程的应用程序发生更改的机会很小,但是考虑到每年出货的数十亿微控制器以及可能的恶劣操作环境,被损坏的应用程序的可能性就不会为零。但是,更有可能的是系统中的错误可能导致扇区中的闪存写入或闪存擦除,从而导致应用程序损坏。

提示#3 –在启动时执行RAM检查

验证启动时内部或外部RAM是否没有问题是确保硬件正常运行的好方法。有许多不同的方法可用于执行RAM检查,但是通常要做的是写入已知的模式,允许其停顿一小段时间然后再读回。结果应该是读取的内容与写入的内容匹配。显然,最常见的结果是,一切都按预期进行,但是如果不是,这将为系统提供一个极好的机会,以告知系统存在硬件问题!

事实是,在大多数情况下,RAM检查会通过,这是我们想要的,但是为了构建更可靠,更强大的系统,确保系统硬件正常运行很重要。毕竟,硬件确实会失败!值得庆幸的是,软件永远不会失败,它只会执行编写的代码,不管对还是错。 Michael Barr于2000年编写了一个memtest C模块,可以在考虑进行RAM测试时节省工程师的时间。可以找到用于下载模块的Embedded.com链接 这里.

提示4 –使用堆栈监视器

对于许多嵌入式开发人员而言,堆栈似乎是相当神秘的力量。奇怪的事情开始发生,当工程师最终陷入困境时,他们开始认为可能堆栈中正在发生某些事情。结果是盲目的调整和堆栈大小,位置等的调整。通常,该错误与堆栈无关,但是如何真正确定呢?毕竟,有多少工程师执行最坏情况的堆栈大小分析?

堆栈的大小在编译时静态分配,但以动态方式使用。随着代码执行变量,返回地址和其他信息被存储在应用程序所需的堆栈中。这导致堆栈在其分配的内存中增长;但是,这种增长可能会超出编译时的大小限制,从而导致堆栈损坏隔壁内存区域中的任何内容。

确保堆栈行为正常的一种方法是将堆栈监视器实现为系统健康状况代码的一部分(有多少工程师这样做?)。堆栈监视器使用已知的位模式在堆栈和“其他”存储区域之间创建缓冲区。然后将不断监视此模式的任何更改。如果位模式发生变化,则说明堆栈已增长得太远,即将使系统陷入黑暗的深渊!然后,监视器可以记录事件的发生,系统状态以及以后可用于诊断问题的任何其他有用数据。

堆栈监视器在大多数实施内存保护单元(MPU)的RTOS或微控制器系统中并不罕见。令人恐惧的是,这些功能通常是默认关闭的或开发人员可以关闭的功能。快速浏览互联网可以发现建议关闭RTOS中的堆栈监视器以节省56字节的闪存空间!花点时间思考一下这些问题!

提示5 –使用MPU

过去很少在小型且便宜的微控制器上找到存储保护单元,但是这种情况已经开始改变! MPU开始出现在微控制器的所有领域,这为嵌入式软件开发人员提供了大幅改善其固件鲁棒性的机会。

MPU通常已与操作系统相关联,以划分出内存空间,在其中单独的进程或任务可以执行其代码而不必担心被踩踏。万一发生某些事情,可以消除猖process的过程,或者可以执行其他保护措施。请密切注意具有此组件的微控制器,如果有的话,可以通过使用它来利用它!

提示6 –创建强大的看​​门狗系统

一直以来发现的最喜欢的看门狗实现是启用看门狗的地方(这是一个很好的开始),但是使用定期定时器清除看门狗的时间是与程序中发生的任何事情分开触发的。使用看门狗的目的是帮助确保如果出现问题,则不会清除看门狗,并且在给定的时间,系统将被强制执行硬件重置以恢复。

嵌入式开发人员需要仔细考虑和设计如何将应用程序任务集成到看门狗系统中。例如,一种技术可能是让应该在给定时间段内运行的每个任务标记一个标志,表明他们能够成功执行任务。在看门狗清除点,如果任务尚未完成,则表明存在问题,并且未清除看门狗,强制复位。然后是更高级的技术,例如使用外部监视程序处理器来监视主处理器的行为,反之亦然。

创建可靠的看门狗系统对于可靠的系统绝对至关重要。几段中介绍的技术太多,但是有关该主题的专门文章将很快发布。

提示#7 –避免动态内存分配

不习惯在资源受限的环境中工作的工程师可能会倾向于使用其编程语言的功能,这些功能将允许使用动态内存分配。毕竟,这是在仅在需要时才分配内存的计算机系统上常用的技术。例如,使用C语言进行开发时,可能会想使用malloc在堆上分配空间。执行一个操作,一旦完成使用free,将返回分配的内存以供在堆上使用。

在资源受限的系统上,这可能是一场灾难!使用动态内存分配的问题之一是,错误或不正确的技术可能导致内存泄漏或内存碎片。大多数嵌入式系统都没有资源或专有技术来监视堆,如果发生这种情况也无法正确处理。甚至更糟的是,如果应用程序请求空间但请求的空间不可用怎么办?

使用动态内存分配引起的问题可能很复杂,正确处理这些问题可能是一场噩梦!另一种方法是简单地静态分配内存。例如,与其通过malloc内存请求一个256字节长的缓冲区,不如在程序中创建大小为256的数组。该内存在应用程序的整个生命周期中始终保持分配状态,而无需担心堆或内存碎片问题。

结论

这些只是开发人员可以开始创建更可靠的嵌入式系统的几种方式。还有许多其他技术,例如使用良好的编码标准,监视位翻转,执行数组和指针边界检查以及使用断言等。要了解这些技术和其他技术的更多细节,请考虑注册我的每月《嵌入式字节数》通讯(位于这里),将涵盖很长的篇幅!

还有哪些其他技术可以用来构建更可靠的嵌入式系统?我期待听到您的想法!

2 thoughts 上 “创建可靠的嵌入式系统的7个技巧”

  1. 雅各布

    很好的建议在这里。其中一些是我独立发明的,用来使我的代码更可靠-其他绝对也很不错。

    我现在要做的是“启动前灌注所有RAM”。一些编译器/链接器工具可以执行此操作– but I’我看到它没有完成。此处的值是如果在C启动失败的情况下,如果在正确启动之前使用RAM,则避免了出现不一致结果的机会。’不能正确灌注所有东西。 。

    当我不做的时候’拥有一个RTOS并有一个虚拟后台任务,这是调用不同例程的永恒循环:记录解决该循环所需的最坏情况时间–这使我可以了解最坏情况下的延迟。即使使用RTOS,最好有一个虚拟的低优先级线程,该线程简单地记录最坏情况的时间(在初始化代码全部运行之后)来处理该线程所需的时间。

  2. 雅各布

    感谢您提供这些提示,我花了很多时间(但不是全部)将它们添加到工具栏中-

    我使用的两个:

    RAM监视器:我在各个地址上创建多个变量,并用已知值填充它们,即:0xAAAA,0x55​​55、0x55AA等。然后在主程序循环中检查它们,如果有损坏,我将系统重置为RAM不再可靠。

    库函数/外围定时器:我创建一个中断驱动的变量,该变量递减。在调用库函数或访问外围设备之前,我使用一个已知值启动该变量,该值高于完成该过程所需的时间。完成后,我将关闭计时器。如果它变为0,则说明存在问题,然后重置系统。

    拉里·阿夫特(Larry Affelt)

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *

该网站使用Akismet减少垃圾邮件。 了解如何处理您的评论数据.