RTOS 设计已成为许多嵌入式应用的关键,RTOS 用于超过 50% 的嵌入式应用程序,并且随着如此多的设备开始连接并开始使用机器学习,这些数字只会增加。嵌入式开发人员在设计基于 RTOS 的应用程序时,有许多注意事项,在今天的文章中,我们探讨5个RTOS 设计最佳实践。

1. 数据决定设计

好的软件设计是由数据驱动的,换句话说,数据决定设计。大多数系统是事件生成数据的实时系统,反过来,这些数据必须以各种方式流经应用程序,进行处理,然后存储或输出。

在开始 RTOS 设计,甚至任何嵌入式应用程序设计时,首先要识别应用程序中的所有数据源。首先创建一个列表;接下来,在图表中绘制块并标记数据源;最后,将数据源映射到它们的最终目的地,标记数据如何转换、如何处理以及哪些应用程序区域使用数据。当完成时,任务、数据存储、同步机制等自然会从数据流中出来。

2. 使用 RMS 验证你的设计

RMS,最著名的是速率单调调度,是一种分析技术,设计人员可以使用它来测试他们关于系统中的任务是否可以成功调度的假设。RMS 存在多种模型,最基本的模型假设:

任务是周期性的

任务是独立的

使用抢占式调度

每个任务都有一个恒定的最坏情况执行时间

所有任务都同样重要

非周期性任务仅限于启动和故障恢复

乍一看,其中一些假设对于现实世界似乎非常不切实际,但是,大多数设计都可以使用它们进行分解和验证。(更复杂的模型改进了这些假设)。示例分析如下:

3. 任务分解从外向内开始

将应用程序分解为任务可能具有挑战性,嵌入式开发人员经常发现自己会提出以下问题:

我的任务太多了吗?

我没有足够的任务吗?

可以安排所有这些任务吗?

这些任务应该合并还是分开?

开始分解应用程序时,最好的方法是从外向内。首先查看硬件设备以及系统的输入和输出,查看数据和生成数据的速率,输入/输出和硬件及其数据流将有助于识别系统中的主要任务,例如,你最终可能会得到一个简单的图表,如下所示:

上图标识了五个主要任务,然后是一个可以进一步分解的应用程序块。

4. 使用 OSAL 解耦 RTOS

很多公司围绕他们的 RTOS 构建他们的整个应用程序,RTOS 应该是应用程序中的一个组件,而不是应用程序的基础。问题是开发人员无法控制 RTOS,如果 RTOS 发生更改,则应用程序无法免受这些更改的影响,如果 RTOS 突然不再可用或被某人购买,更改为不同的 RTOS 可能与重写大部分应用程序一样痛苦。

这里的最佳实践是使用操作系统抽象层 (OSAL)。它可以非常优雅地融入软件架构,如下图所示:

请注意,RTOS 只是应用程序堆栈中间的另一个组件。如果我们想换出新的 RTOS,我们需要做的就是将 OSAL 映射更改为新的 RTOS。应用程序将不知道发生了什么变化!

OSAL 本质上充当依赖屏障,并将使用通用操作系统调用。例如,每个 RTOS 都有一个信号量、互斥量等。OSAL 为常见的 RTOS 功能提供了通用 API。如果需要一些特定于操作系统的功能,这些功能不在像 CMSIS-RTOS2 这样的通用 OSAL 中,那么嵌入式开发人员应该为 OSAL 编写自己的扩展。这将继续限制应用程序对 RTOS 的耦合和依赖。毕竟,你永远不知道它什么时候会改变。

5. 不要将信号量用作互斥体

互斥量和信号量是为不同的目的而设计的。互斥锁旨在提供对资源的互斥访问。信号量是为任务通知和协调而设计的。

设计人员和开发人员经常使用二进制信号量作为互斥体。互斥锁可以锁定/解锁资源。可以给出或获取二进制信号量,从而导致看起来很像锁定/解锁的状态。但是,这两者之间有一个重要的区别。互斥体有一个称为优先级继承的特性。在优先级倒置的情况下,优先级继承可以提升任务的优先级,将优先级倒置的影响降到最低。

信号量不支持优先级继承,因此当用作互斥体时会导致优先级反转和其他设计问题。确保你了解这些差异,并且永远不要使用信号量来保护数据访问。使用正确的工具,即互斥锁。

结论

RTOS 设计正在成为或已经成为嵌入式开发人员需要执行的一项常见活动,很多困难可以通过我们刚刚研究的5个RTOS设计最佳实践来缓解。仔细研究这些方法,你可以避免很多烦恼。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部