欢迎光临
我们一直在努力

Classic AUTOSAR深入浅出系列 - 【第十九篇】Runnable、Event 与 Timing:函数是如何被“触发”的

第 18 篇|Runnable、Event 与 Timing:函数是如何被“触发”的

在这里插入图片描述

【Application Layer / RTE】

在上一篇我们说过一句很关键的话:

Runnable 才是 AUTOSAR 应用里真正会执行的函数。

但这句话只说了一半。

另一半是:

Runnable 永远不会“自己跑起来”。

它一定是被某种 Event 触发的。
而 Event,本质上是 RTE 和 OS 之间的一份“触发契约”。


从一个最朴素的问题开始

先不要想 AUTOSAR,我们先想一个最原始的问题:

一个函数,凭什么每 10ms 执行一次?

在裸机或普通 RTOS 里,你可能会写:

while(1)
{
Task_10ms();
Delay(10);
}

或者在 RTOS 里:

  • Task 周期 10ms
  • 函数直接写在 Task 里

函数 ≈ Task ≈ 时间
三者是绑死的。

而 AUTOSAR 从一开始就刻意把它们拆开:

  • Task 是 OS 的概念
  • Runnable 是应用的概念
  • 时间触发,是 Event 的事

Runnable 不等于周期

这是 AUTOSAR 非常反直觉、但又非常重要的一点。

Runnable 自身没有“时间属性”。

Runnable 只是一个函数:

  • 没有周期
  • 没有优先级
  • 没有上下文

所有“什么时候跑”的信息,都在 Event 里。


Event:Runnable 的“触发原因”

在 Classic AUTOSAR 里,Event 可以理解为:

“当某个条件成立时,RTE 负责触发某个 Runnable。”

这些条件,来自不同层级:

  • 时间
  • 数据
  • 调用
  • 系统状态

从工程角度看,你可以把 Event 分成几大类。


TimingEvent:最容易被误解的一类

我们先讲最常见、也最容易被误解的 TimingEvent。

TimingEvent 的真实含义

很多人以为:

TimingEvent = 周期

但更准确的说法是:

TimingEvent = RTE 声明:这个 Runnable 需要“被周期性触发”。

而“周期性”这件事,最终一定是 OS 在做。

也就是说:

  • TimingEvent 本身不计时
  • 不产生 Tick
  • 不配置硬件 Timer

它只是告诉 RTE:

“请你想办法,让这个 Runnable 按这个节奏被调用。”


从 TimingEvent 到 Task 的真实路径

我们用一张完整链路图把这件事说清楚。

#mermaid-svg-5nTlOpIUgwIzTSKO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5nTlOpIUgwIzTSKO .error-icon{fill:#552222;}#mermaid-svg-5nTlOpIUgwIzTSKO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5nTlOpIUgwIzTSKO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5nTlOpIUgwIzTSKO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5nTlOpIUgwIzTSKO .marker.cross{stroke:#333333;}#mermaid-svg-5nTlOpIUgwIzTSKO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5nTlOpIUgwIzTSKO p{margin:0;}#mermaid-svg-5nTlOpIUgwIzTSKO .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO .cluster-label text{fill:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO .cluster-label span{color:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO .cluster-label span p{background-color:transparent;}#mermaid-svg-5nTlOpIUgwIzTSKO .label text,#mermaid-svg-5nTlOpIUgwIzTSKO span{fill:#333;color:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO .node rect,#mermaid-svg-5nTlOpIUgwIzTSKO .node circle,#mermaid-svg-5nTlOpIUgwIzTSKO .node ellipse,#mermaid-svg-5nTlOpIUgwIzTSKO .node polygon,#mermaid-svg-5nTlOpIUgwIzTSKO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5nTlOpIUgwIzTSKO .rough-node .label text,#mermaid-svg-5nTlOpIUgwIzTSKO .node .label text,#mermaid-svg-5nTlOpIUgwIzTSKO .image-shape .label,#mermaid-svg-5nTlOpIUgwIzTSKO .icon-shape .label{text-anchor:middle;}#mermaid-svg-5nTlOpIUgwIzTSKO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5nTlOpIUgwIzTSKO .rough-node .label,#mermaid-svg-5nTlOpIUgwIzTSKO .node .label,#mermaid-svg-5nTlOpIUgwIzTSKO .image-shape .label,#mermaid-svg-5nTlOpIUgwIzTSKO .icon-shape .label{text-align:center;}#mermaid-svg-5nTlOpIUgwIzTSKO .node.clickable{cursor:pointer;}#mermaid-svg-5nTlOpIUgwIzTSKO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5nTlOpIUgwIzTSKO .arrowheadPath{fill:#333333;}#mermaid-svg-5nTlOpIUgwIzTSKO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5nTlOpIUgwIzTSKO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5nTlOpIUgwIzTSKO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5nTlOpIUgwIzTSKO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5nTlOpIUgwIzTSKO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5nTlOpIUgwIzTSKO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5nTlOpIUgwIzTSKO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5nTlOpIUgwIzTSKO .cluster text{fill:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO .cluster span{color:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5nTlOpIUgwIzTSKO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5nTlOpIUgwIzTSKO rect.text{fill:none;stroke-width:0;}#mermaid-svg-5nTlOpIUgwIzTSKO .icon-shape,#mermaid-svg-5nTlOpIUgwIzTSKO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5nTlOpIUgwIzTSKO .icon-shape p,#mermaid-svg-5nTlOpIUgwIzTSKO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5nTlOpIUgwIzTSKO .icon-shape rect,#mermaid-svg-5nTlOpIUgwIzTSKO .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5nTlOpIUgwIzTSKO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5nTlOpIUgwIzTSKO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5nTlOpIUgwIzTSKO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

TimingEvent (10ms)

RTE Generated Code

OS Task (10ms)

Runnable_X()

关键点在这里:

  • TimingEvent → RTE 配置
  • Task → OS 配置
  • 两者通过 RTE 生成代码“绑”在一起

所以你在 ARXML 里改 TimingEvent 的周期,
最后一定会体现在:

  • Task 的 Alarm
  • 或 ScheduleTable
  • 或 Task 激活频率

常见误解:一个 TimingEvent = 一个 Task?

这是项目里非常常见的误区。

实际上:

  • 一个 Task 可以承载多个 TimingEvent
  • 一个 Runnable 也可以被多个 Event 触发(虽然不推荐)

例如:

#mermaid-svg-YvsanzHIcV6c84B0{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YvsanzHIcV6c84B0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YvsanzHIcV6c84B0 .error-icon{fill:#552222;}#mermaid-svg-YvsanzHIcV6c84B0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YvsanzHIcV6c84B0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YvsanzHIcV6c84B0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YvsanzHIcV6c84B0 .marker.cross{stroke:#333333;}#mermaid-svg-YvsanzHIcV6c84B0 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YvsanzHIcV6c84B0 p{margin:0;}#mermaid-svg-YvsanzHIcV6c84B0 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-YvsanzHIcV6c84B0 .cluster-label text{fill:#333;}#mermaid-svg-YvsanzHIcV6c84B0 .cluster-label span{color:#333;}#mermaid-svg-YvsanzHIcV6c84B0 .cluster-label span p{background-color:transparent;}#mermaid-svg-YvsanzHIcV6c84B0 .label text,#mermaid-svg-YvsanzHIcV6c84B0 span{fill:#333;color:#333;}#mermaid-svg-YvsanzHIcV6c84B0 .node rect,#mermaid-svg-YvsanzHIcV6c84B0 .node circle,#mermaid-svg-YvsanzHIcV6c84B0 .node ellipse,#mermaid-svg-YvsanzHIcV6c84B0 .node polygon,#mermaid-svg-YvsanzHIcV6c84B0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YvsanzHIcV6c84B0 .rough-node .label text,#mermaid-svg-YvsanzHIcV6c84B0 .node .label text,#mermaid-svg-YvsanzHIcV6c84B0 .image-shape .label,#mermaid-svg-YvsanzHIcV6c84B0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-YvsanzHIcV6c84B0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YvsanzHIcV6c84B0 .rough-node .label,#mermaid-svg-YvsanzHIcV6c84B0 .node .label,#mermaid-svg-YvsanzHIcV6c84B0 .image-shape .label,#mermaid-svg-YvsanzHIcV6c84B0 .icon-shape .label{text-align:center;}#mermaid-svg-YvsanzHIcV6c84B0 .node.clickable{cursor:pointer;}#mermaid-svg-YvsanzHIcV6c84B0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YvsanzHIcV6c84B0 .arrowheadPath{fill:#333333;}#mermaid-svg-YvsanzHIcV6c84B0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YvsanzHIcV6c84B0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YvsanzHIcV6c84B0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YvsanzHIcV6c84B0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YvsanzHIcV6c84B0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YvsanzHIcV6c84B0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YvsanzHIcV6c84B0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YvsanzHIcV6c84B0 .cluster text{fill:#333;}#mermaid-svg-YvsanzHIcV6c84B0 .cluster span{color:#333;}#mermaid-svg-YvsanzHIcV6c84B0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YvsanzHIcV6c84B0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YvsanzHIcV6c84B0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-YvsanzHIcV6c84B0 .icon-shape,#mermaid-svg-YvsanzHIcV6c84B0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YvsanzHIcV6c84B0 .icon-shape p,#mermaid-svg-YvsanzHIcV6c84B0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YvsanzHIcV6c84B0 .icon-shape rect,#mermaid-svg-YvsanzHIcV6c84B0 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YvsanzHIcV6c84B0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YvsanzHIcV6c84B0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YvsanzHIcV6c84B0 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

Task_10ms

Runnable_A (10ms)

Runnable_B (20ms)

在这种情况下:

  • Task 10ms 运行一次
  • Runnable_B 通过内部计数或 RTE 逻辑,每 20ms 才真正执行

这也是为什么Task 周期 ≠ Runnable 周期。


DataReceivedEvent:数据驱动,而不是时间驱动

第二类非常重要的 Event 是 DataReceivedEvent。

它描述的不是“时间到了”,而是:

“当某个数据被更新时,触发 Runnable。”

典型场景包括:

  • CAN 信号接收
  • 状态变化
  • 外部 ECU 事件

SWCRTECOMSWCRTECOM#mermaid-svg-znmErmqvuL2O0Ys9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-znmErmqvuL2O0Ys9 .error-icon{fill:#552222;}#mermaid-svg-znmErmqvuL2O0Ys9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-znmErmqvuL2O0Ys9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-znmErmqvuL2O0Ys9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-znmErmqvuL2O0Ys9 .marker.cross{stroke:#333333;}#mermaid-svg-znmErmqvuL2O0Ys9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-znmErmqvuL2O0Ys9 p{margin:0;}#mermaid-svg-znmErmqvuL2O0Ys9 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-znmErmqvuL2O0Ys9 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-znmErmqvuL2O0Ys9 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-znmErmqvuL2O0Ys9 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-znmErmqvuL2O0Ys9 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-znmErmqvuL2O0Ys9 .sequenceNumber{fill:white;}#mermaid-svg-znmErmqvuL2O0Ys9 #sequencenumber{fill:#333;}#mermaid-svg-znmErmqvuL2O0Ys9 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-znmErmqvuL2O0Ys9 .messageText{fill:#333;stroke:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-znmErmqvuL2O0Ys9 .labelText,#mermaid-svg-znmErmqvuL2O0Ys9 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .loopText,#mermaid-svg-znmErmqvuL2O0Ys9 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-znmErmqvuL2O0Ys9 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-znmErmqvuL2O0Ys9 .noteText,#mermaid-svg-znmErmqvuL2O0Ys9 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-znmErmqvuL2O0Ys9 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-znmErmqvuL2O0Ys9 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-znmErmqvuL2O0Ys9 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-znmErmqvuL2O0Ys9 .actorPopupMenu{position:absolute;}#mermaid-svg-znmErmqvuL2O0Ys9 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-znmErmqvuL2O0Ys9 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-znmErmqvuL2O0Ys9 .actor-man circle,#mermaid-svg-znmErmqvuL2O0Ys9 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-znmErmqvuL2O0Ys9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}Signal updatedTrigger Runnable_DataIndication

这里有一个非常工程化的差异:

  • TimingEvent:OS 先动
  • DataReceivedEvent:通信先动

但最终:

  • 都是通过 RTE
  • 都落到 Runnable

OperationInvokedEvent:Client-Server 的触发方式

当你使用 Client-Server Interface 时,
对应的 Event 就是 OperationInvokedEvent。

你可以把它理解为:

“有人 Call 了我这个接口,所以我要跑。”

ServerSWCRTEClientSWCServerSWCRTEClientSWC#mermaid-svg-vbBqy062ZWflF7pM{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vbBqy062ZWflF7pM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vbBqy062ZWflF7pM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vbBqy062ZWflF7pM .error-icon{fill:#552222;}#mermaid-svg-vbBqy062ZWflF7pM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vbBqy062ZWflF7pM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vbBqy062ZWflF7pM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vbBqy062ZWflF7pM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vbBqy062ZWflF7pM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vbBqy062ZWflF7pM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vbBqy062ZWflF7pM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vbBqy062ZWflF7pM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vbBqy062ZWflF7pM .marker.cross{stroke:#333333;}#mermaid-svg-vbBqy062ZWflF7pM svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vbBqy062ZWflF7pM p{margin:0;}#mermaid-svg-vbBqy062ZWflF7pM .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vbBqy062ZWflF7pM text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-vbBqy062ZWflF7pM .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-vbBqy062ZWflF7pM .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-vbBqy062ZWflF7pM .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-vbBqy062ZWflF7pM .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-vbBqy062ZWflF7pM #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-vbBqy062ZWflF7pM .sequenceNumber{fill:white;}#mermaid-svg-vbBqy062ZWflF7pM #sequencenumber{fill:#333;}#mermaid-svg-vbBqy062ZWflF7pM #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-vbBqy062ZWflF7pM .messageText{fill:#333;stroke:none;}#mermaid-svg-vbBqy062ZWflF7pM .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vbBqy062ZWflF7pM .labelText,#mermaid-svg-vbBqy062ZWflF7pM .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-vbBqy062ZWflF7pM .loopText,#mermaid-svg-vbBqy062ZWflF7pM .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-vbBqy062ZWflF7pM .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-vbBqy062ZWflF7pM .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-vbBqy062ZWflF7pM .noteText,#mermaid-svg-vbBqy062ZWflF7pM .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-vbBqy062ZWflF7pM .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vbBqy062ZWflF7pM .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vbBqy062ZWflF7pM .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vbBqy062ZWflF7pM .actorPopupMenu{position:absolute;}#mermaid-svg-vbBqy062ZWflF7pM .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-vbBqy062ZWflF7pM .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vbBqy062ZWflF7pM .actor-man circle,#mermaid-svg-vbBqy062ZWflF7pM line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-vbBqy062ZWflF7pM :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}Rte_Call_Service()Runnable_Service()

这个 Runnable:

  • 没有周期
  • 完全由调用驱动
  • 可能运行在调用者 Task 中(同步)
  • 也可能被映射到独立 Task(异步)

Runnable 的执行上下文,并不是它自己决定的。


多 Event 触发同一个 Runnable,可以吗?

规范上:可以。
工程上:强烈不推荐。

例如:

  • 一个 Runnable 同时被 TimingEvent 和 DataReceivedEvent 触发
  • 或同时被多个 TimingEvent 触发

结果往往是:

  • 执行时序混乱
  • 数据一致性难以保证
  • Debug 极其痛苦

Runnable 的一个重要设计原则是:触发原因要单一、可解释。


Runnable 设计的几个“落地原则”

这一部分,我刻意不讲“规范推荐”,而讲项目里踩过坑之后总结出来的原则。

一个 Runnable,只做一类事

不要在一个 Runnable 里同时:

  • 采集数据
  • 做控制
  • 发通信

否则:

  • Event 一复杂,你会完全失控

Runnable 不应该关心“为什么现在被调用”

Runnable 的代码里,不应该出现:

  • “这是第几次调用”
  • “是不是 20ms 才该跑”
  • “是不是某个模式下”

这些都应该在:

  • Event 配置
  • 或上层逻辑里解决

Runnable 的执行时间要可控

因为 Runnable 最终跑在 Task 里:

  • 它会影响同 Task 下其他 Runnable
  • 也会影响 OS 调度

所以在设计时要非常现实地问一句:

这个 Runnable,最坏情况下要跑多久?


把一切串起来:从配置到执行

我们用一条“从配置到代码”的链路收尾。

#mermaid-svg-ZZB1lLEJPH89ESUG{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZZB1lLEJPH89ESUG .error-icon{fill:#552222;}#mermaid-svg-ZZB1lLEJPH89ESUG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZZB1lLEJPH89ESUG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZZB1lLEJPH89ESUG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZZB1lLEJPH89ESUG .marker.cross{stroke:#333333;}#mermaid-svg-ZZB1lLEJPH89ESUG svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZZB1lLEJPH89ESUG p{margin:0;}#mermaid-svg-ZZB1lLEJPH89ESUG .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG .cluster-label text{fill:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG .cluster-label span{color:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG .cluster-label span p{background-color:transparent;}#mermaid-svg-ZZB1lLEJPH89ESUG .label text,#mermaid-svg-ZZB1lLEJPH89ESUG span{fill:#333;color:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG .node rect,#mermaid-svg-ZZB1lLEJPH89ESUG .node circle,#mermaid-svg-ZZB1lLEJPH89ESUG .node ellipse,#mermaid-svg-ZZB1lLEJPH89ESUG .node polygon,#mermaid-svg-ZZB1lLEJPH89ESUG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZZB1lLEJPH89ESUG .rough-node .label text,#mermaid-svg-ZZB1lLEJPH89ESUG .node .label text,#mermaid-svg-ZZB1lLEJPH89ESUG .image-shape .label,#mermaid-svg-ZZB1lLEJPH89ESUG .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZZB1lLEJPH89ESUG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZZB1lLEJPH89ESUG .rough-node .label,#mermaid-svg-ZZB1lLEJPH89ESUG .node .label,#mermaid-svg-ZZB1lLEJPH89ESUG .image-shape .label,#mermaid-svg-ZZB1lLEJPH89ESUG .icon-shape .label{text-align:center;}#mermaid-svg-ZZB1lLEJPH89ESUG .node.clickable{cursor:pointer;}#mermaid-svg-ZZB1lLEJPH89ESUG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZZB1lLEJPH89ESUG .arrowheadPath{fill:#333333;}#mermaid-svg-ZZB1lLEJPH89ESUG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZZB1lLEJPH89ESUG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZZB1lLEJPH89ESUG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZZB1lLEJPH89ESUG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZZB1lLEJPH89ESUG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZZB1lLEJPH89ESUG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZZB1lLEJPH89ESUG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZZB1lLEJPH89ESUG .cluster text{fill:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG .cluster span{color:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZZB1lLEJPH89ESUG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZZB1lLEJPH89ESUG rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZZB1lLEJPH89ESUG .icon-shape,#mermaid-svg-ZZB1lLEJPH89ESUG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZZB1lLEJPH89ESUG .icon-shape p,#mermaid-svg-ZZB1lLEJPH89ESUG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZZB1lLEJPH89ESUG .icon-shape rect,#mermaid-svg-ZZB1lLEJPH89ESUG .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZZB1lLEJPH89ESUG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZZB1lLEJPH89ESUG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZZB1lLEJPH89ESUG :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

ARXML\\n(Event / Runnable Mapping)

RTE Generator

OS Task

Runnable C Code

当你在项目里遇到:

  • Runnable 没跑
  • 跑得不准
  • 跑的次数不对

排查顺序永远是:

  • Event 配置
  • RTE 生成关系
  • OS Task / Alarm
  • 最后才是 C 代码

  • 小结

    这一篇你只需要记住三句话:

    • Runnable 是函数,不是周期
    • Event 决定“为什么触发”
    • OS 决定“什么时候调度”

    AUTOSAR 真正厉害的地方,不是它复杂,
    而是它把这些本来混在一起的概念,强行拆开了。

    下一篇,我们会继续沿着这条线往下走:

    👉 下一篇预告
    RTE:看起来很蠢,但不可或缺的胶水层

    我们会直接打开 RTE 生成代码,
    看看这些 Event 和 Runnable,到底是怎么被“粘”在一起的。

    赞(0)
    未经允许不得转载:171主机测评 » Classic AUTOSAR深入浅出系列 - 【第十九篇】Runnable、Event 与 Timing:函数是如何被“触发”的
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址