我经常从嵌入式开发人员那里听到两种拒绝使用RTOS的借口:
RTOS内存占用太大
RTOS开销太大
这些借口在以前可能有一些价值,但今天它们没有任何分量。典型的RTOS对CPU的负载不到4%,需要不到16 KB的闪存空间和不到4 KB的RAM。在大多数情况下,性能和内存问题与开发人员如何使用RTOS以及他们在如何正确使用和配置RTOS方面的知识差距有关。下面是开发人员可以遵循的七个技巧,以优化他们的RTOS应用程序内存使用。
技巧1 – 对每项任务进行最坏情况堆栈分析
最大的内存浪费之一是为任务堆栈分配的内存。默认情况下,大多数 RTOS 将分配一千字节来保存任务堆栈,其中包含诸如局部变量、数据结构和函数调用返回地址等内容。默认大小的问题在于,不熟悉使用 RTOS 的开发人员通常不会检查每个任务并正确调整堆栈的大小。一个只闪烁几个 LED 并且什么都不做的任务通常会有 1 千字节的堆栈,即使 64 字节就足够了。未能检查每个任务并正确调整堆栈大小可能会导致使用的 RAM 远远超过应用程序实际所需的 RAM。
技巧2 – 避免过度使用堆栈
由于每个任务都有一个堆栈,因此任务堆栈成为运行应用程序所需的 RAM 的巨大贡献者。当嵌入式开发人员设计和实现他们的任务时,他们应该尽量减少堆栈的使用。这可以通过以下方式完成:
• 避免递归函数
• 最大限度减少函数调用
• 避免大型本地数据结构
开发人员不仅需要编写代码,还需要仔细考虑每个变量、数据结构和函数调用对内存和性能的影响。避免过度使用堆栈使用将允许开发人员缩小堆栈大小并节省 RAM 使用。
技巧3 – 使用内存块池
开发人员在开发基于 RTOS 的应用程序时经常会遇到的一个大问题是他们需要动态分配内存。动态内存分配的问题在于,内存通常是从一个行为类似于字节池的堆中分配的。堆和字节池有许多缺点,例如:
• 它们会破碎
• 内存分配是不确定的
另一方面,块池来自固定块,不仅可以确定地分配,而且不会碎片。对于需要动态分配内存的开发人员来说,块池是比堆或字节池更好的选择。
技巧4 – 最小化 RTOS 对象
RTOS 可以帮助嵌入式开发人员将他们的应用程序分解为可重用的半独立程序,这些程序使用信号量、互斥体和消息队列等 RTOS 对象来通信和同步任务执行。每个RTOS对象都有一个使用少量内存的控制块。在资源非常有限的应用程序中,或者如果开发人员过度使用这些资源,则可以使用比实际需要更多的内存。出于这个原因,开发人员应该仔细设计他们的 RTOS 应用程序,尽量减少RTOS对象的使用。
技巧5 – 考虑使用事件标志而不是信号量
RTOS 的功能可能因一个 RTOS 而异,但在作者使用的几种不同的 RTOS 中,使用事件标志而不是信号量可能会导致占用空间略小。信号量不仅包含一个控制块,还包含一些基本代码来执行信号量操作,比如发送和接收信号量。通常,此代码往往比事件标志更慢并且使用更多内存。事件标志实际上只不过是一个内存位置,其中内存位置中的每一位都代表一个事件,例如按下按钮或刚刚对温度传感器进行采样。
技巧6 – 最小化任务优先级
实时操作系统允许嵌入式开发人员设置任务可以设置的优先级。例如,许多系统的默认值是 0 到 31。在某些情况下,默认值的范围可以从 0 到 128 甚至 0 到 1024。一般来说,一般来说,任务优先级越低,性能越好,内存使用越少。开发人员应尽量将优先级设置保持在 0 到 31 之间,除非有充分的理由进行其他设置。
技巧7 – 优化 RTOS 配置文件
RTOS 通常有一个配置文件,允许开发人员微调 RTOS 行为。配置文件允许开发人员设置功能,例如默认堆栈大小、可用的优先级数量以及构建中将包含哪些同步对象。在许多情况下,修改配置文件可以为开发人员提供更小的 RTOS 占用空间,甚至根据可用的配置选项提高性能。确保检查 RTOS 配置文件并了解每个可用选项。
结论
如果使用不当,RTOS 会导致应用程序所需的内存占用膨胀到无法使用的水平。在许多情况下,高内存使用是由于开发人员使用 RTOS 的方式造成的,而不是 RTOS 本身的指示。在这篇文章中,我们研究了嵌入式开发人员可以遵循的几个技巧,以帮助最小化他们自己的 RTOS 应用程序占用空间。