2. RTE核心概念:RTE的基本术语、通信模式与触发机制
好,我们进入第二章。这一章是RTE的基石,说白了就是搞清楚RTE到底在干什么。我个人习惯把RTE看作一个“智能调度员”,它负责把SWC(软件组件)里的函数、数据、事件,有条不紊地串联起来。你想想看,没有RTE,各个SWC就像一群不会说话的哑巴,各自为战。
2.1 RTE的基本术语:Runnable、Port、Interface
这三个词,你几乎每天都会碰到。我们先一个个说清楚。
2.1.1 Runnable(可运行实体)
Runnable,说白了就是SWC里的一段可执行代码。它不是一个完整的任务,而是一个“函数块”。RTE负责调度它,在合适的时机把它拉出来跑一遍。
关键点:
- 每个Runnable都有一个唯一的ID,RTE靠这个ID找到它。
- Runnable不能自己决定什么时候跑,它得听RTE的。RTE根据触发事件(后面会讲)来决定。
- 一个SWC可以包含多个Runnable,它们可以并行或串行执行,取决于配置。
我遇到过的一个坑: 有一次,我把一个耗时很长的计算逻辑写成了一个Runnable,结果它阻塞了其他Runnable的执行。后来我把它拆成了几个小Runnable,用不同的触发周期去跑,问题就解决了。记住,Runnable要短小精悍。
2.1.2 Port(端口)
Port是SWC与外界通信的“接口”。它就像SWC的嘴巴和耳朵。一个SWC可以有多个Port,每个Port负责一种特定的数据交换。
Port的类型:
- 提供端口(PPort): SWC通过它向外提供数据或服务。比如一个传感器SWC,通过PPort向外发送温度值。
- 需求端口(RPort): SWC通过它从外界获取数据或服务。比如一个控制SWC,通过RPort获取温度值。
- 非易失性数据端口(NVPort): 用于读写非易失性数据,比如存储的配置参数。
我的习惯: 在设计Port时,我会尽量让每个Port只负责一种数据类型。比如一个Port只传温度,另一个只传压力。这样后期维护起来,脑子不会乱。
2.1.3 Interface(接口)
Interface定义了Port之间通信的“协议”。它规定了数据怎么传、传什么格式、有哪些操作。你可以把它理解成一份“合同”,两个Port必须遵守同一份合同才能通信。
Interface的分类:
| 类型 | 说明 | 示例 |
|---|---|---|
| Sender-Receiver Interface | 用于数据发送和接收,一对多或多对多。 | 传感器值、状态标志 |
| Client-Server Interface | 用于函数调用,请求-响应模式。 | 诊断服务、计算请求 |
| Mode Switch Interface | 用于模式切换通知。 | 启动模式、休眠模式 |
| Trigger Interface | 用于触发事件,没有数据负载。 | 定时触发、外部中断 |
嗯,这里要注意:Interface是抽象的,它不绑定具体的SWC。同一个Interface可以被多个SWC复用。这就像你写了一个“加法”函数,谁想用都可以调用。
2.2 RTE的通信模式
RTE支持两种主要的通信模式:Sender-Receiver(S/R)和Client-Server(C/S)。这两种模式,几乎覆盖了所有应用场景。
2.2.1 Sender-Receiver模式
这种模式,说白了就是“广播”。一个Sender把数据发出去,所有感兴趣的Receiver都能收到。它不关心谁在听,也不关心有没有人听。
特点:
- 异步: Sender发送数据后,不用等Receiver处理完,可以继续干自己的事。
- 一对多: 一个Sender可以对应多个Receiver。
- 数据驱动: 数据变化时,RTE会自动通知Receiver。
避坑指南: 我曾经在一个项目中,用S/R模式传递一个高频变化的信号。结果Receiver太多,导致总线负载过高。后来我加了一个“数据过滤”机制,只有数据变化超过一定阈值才发送,问题就解决了。
2.2.2 Client-Server模式
这种模式,说白了就是“打电话”。Client发起一个请求,Server处理完后返回结果。它是同步的,Client必须等Server处理完才能继续。
特点:
- 同步: Client调用Server的函数后,会阻塞等待结果。
- 一对一: 一个Client通常对应一个Server。
- 函数调用: 本质上是跨SWC的函数调用。
我的建议: 如果Server的处理时间很短(比如几微秒),用C/S模式没问题。但如果处理时间很长(比如几毫秒),最好用S/R模式,或者把Server设计成异步的。否则,Client会被卡死。
2.3 RTE的触发机制
RTE怎么知道什么时候该调度哪个Runnable?靠的就是触发机制。触发机制,说白了就是“闹钟”和“门铃”。
常见的触发类型:
- 定时触发: 每隔固定时间触发一次。比如每10ms执行一次传感器采集。
- 数据触发: 当某个Port的数据发生变化时触发。比如温度超过阈值时,触发报警逻辑。
- 操作触发: 当某个函数被调用时触发。比如Client调用Server的函数,Server的Runnable被触发。
- 模式触发: 当系统进入或退出某个模式时触发。比如从启动模式切换到运行模式时,触发初始化逻辑。
- 外部触发: 由硬件中断或外部事件触发。比如按键按下时,触发响应逻辑。
注意: 触发机制的选择,直接影响系统的实时性和资源消耗。我曾经见过一个项目,把所有Runnable都配成了定时触发,结果CPU负载爆表。后来改成了数据触发和事件触发,负载降了一半。
为什么会这样?因为定时触发是“轮询”,不管数据有没有变化,它都跑。而数据触发是“事件驱动”,只有数据变化时才跑。你想想看,哪个更高效?
好了,这一章的内容就到这里。RTE的基本术语、通信模式和触发机制,是理解RTE的钥匙。下一章,我们会深入RTE的配置和生成,看看这些概念怎么落地到代码里。