我正在为Arm M/R系列寻找RTOS(在C++中开发)?有人能为ARM Cortex-M或R系列推荐好的RTOS吗?非常感谢。
要得到任何值的答案,都需要有人对所有答案进行客观评估,而这是不可能的。
受欢迎程度和适合程度不一定是一回事。您应该选择具有应用程序所需功能、可与开发工具配合使用、许可模式和成本符合您需求和预算的RTOS。
您使用的工具链是一个明确的考虑因素——内核感知调试和启动项目都有助于成功的开发。某些调试器/RTOS组合甚至可以允许线程级断点和调试。
Keil的MDK-ARM包括一个简单的RTOS,具有基于优先级的抢占式调度和进程间通信,以及一系列中间件,如文件系统,以及TCP/IP、CAN和USB堆栈,无需额外成本(除非您想要源代码)。
IAR提供与许多RTOS产品的集成,以便与EWB一起使用。他们的ARM EWB页面列出了具有内置和供应商插件支持的RTOS。
就我个人而言,我使用过Keil RTX,但改用Segger embOS,因为当时RTX在Cortex-M上还不够成熟,给我带来了一些问题。然而,RTX的上下文切换时间比embOS快。值得注意的是,IAR的EWB与embOS集成,因此如果您尚未投资工具链,这可能是更简单的途径。我还在Cortex M上评估了FreeRTOS(与OpenRTOS相同,但具有不同的许可和支持模型),但发现其API不如embOS复杂和完整,上下文切换时间明显较慢。
embOS具有与RTX类似的中间件支持,但需要额外的成本。然而,我成功地挂接了另一个开源文件系统和处理器供应商提供的USB堆栈,在embOS和RTX中都没有任何问题,因此中间件支持可能在所有情况下都不是关键的。
其他选项包括Micro C/OS-II。它再次以额外的成本支持中间件。它的调度程序比大多数其他调度程序稍微原始一点,要求每个线程都有不同的优先级,并且这不支持循环/时间片调度,这通常对非实时后台任务有用。它在很大程度上是通过详细描述内核实现的相关书籍而流行的。较新的Micro C/OS-III克服了调度程序的限制。
另一方面,eCos是一个完整的RTOS解决方案,具有高端功能,适用于许多您可能选择Linux但需要实时支持和小占地面积的应用程序。
关键是,您可能会认为RTOS支持先发制人的调度和IPC,并且具有合理的性能水平(尽管我提到了不同的上下文切换时间,但在STM32F1xx上,72MHz时的范围在5到15us之间)。因此,我会关注成熟度(RTOS可用于您的目标多长时间-您甚至可以查看发行说明,以了解它达到成熟的速度有多快,以及可能存在的问题)、工具集成、API是否适合您的需求、预期的软件架构、,中间件支持从供应商或第三方和许可中消失了(你能负担得起吗,你能以你想要的方式合法部署它吗?)。
关于使用C++,大多数RTOS都提供了C API(甚至是用C++编写的eCos)。这并不是一个真正的问题,因为C代码在二进制级别上可以与C++互操作,但是您可以有效地利用C++的功能,使RTOS的选择不那么关键。我所做的是定义一个C++RTOS类库,它提供了一个通用的API来提供所需的设施;例如,我有cTask
、cMutex
、cInterrupt
、cTimer
、cSemaphore
等类。应用程序代码被写入这个API,并且类库实现用于任何数量的RTOS。通过这种方式,应用程序代码可以在对许多目标和RTOS几乎没有改变或没有改变的情况下进行移植,因为类库充当抽象层。我已经成功地为Windriver VxWorks、Segger embOS、Keil RTX甚至Linux和Windows实现了这个类库,用于模拟和原型设计。
一些供应商确实为其RTOS提供了C++包装,例如Accelerated Technology的Neucleus C++for Neucleus RTOS,但这并不一定提供在不更改应用程序代码的情况下更改RTOS所需的抽象。
在RTOS中进行C++开发时需要注意的一点是,大多数RTOS库都是在main()
中初始化的,而C++在调用main()之前调用静态全局对象的构造函数。在RTOS初始化之前,一些RTOS调用通常是无效的,这可能会导致问题,尤其是因为RTOS之间的调用不同。一种解决方案是修改C运行时启动代码,以便RTOS初始化在静态构造函数和main()
之前调用,但在建立基本的C运行时环境之后调用。另一种解决方案是简单地避免静态对象中的RTOS调用。