CP AUTOSAR OS 是用于车载 ECU的实时操作系统, 在协议栈中属于 System Services 中的一个模块。
CP AUTOSAR OS 是基于 OSEK/VDX 的 Operating System, 其基础原理可以参考 OSEK OS 相关文档。
OSEK OS 是基于事件触发的操作系统,可以灵活的对任务进行调度。需要注意的是,CP AUTOSAR OS 不支持动态创建任务,所有 OS 行为需要在编译时进行定义。
CP AUTOSAR OS 支持多核。下图所示为,CP AUTOSAR 概览图。
CP AUTOSAR OS 根据是否支持时间保护和内存保护分为四个 Class
MemoryProtection 是指用于防止不同的 OS Application 异常访问其他不允许的程序段或数据段。
Timing Protection 用于监控任务或者中断是否超时 (超过规定的时间 deadline)
OS Application 是程序应用的单元,每个 OS Application 包含如下内容:
-
-
-
-
-
Countersand Alarms (时基和警报器)
-
-
OS Application 各项关系图如下图所示:
Counters(时基)是 OSEK OS 中一个组件,在软件中可理解为 Ticks。
Alarm(警报器)是由 Counter 驱动的,多个 Alarm 可以连接到同一个 Counter。
Counter 每次累加都会触发相关联 Alarm 的检查,如果满足触发条件,Alarm 会被触发。
Alarm 向上关联到 1 个任务,激活的 Alarm 可以触发一次任务执行(BCC task)或者触发一次事件(Set Event)
–Relative(相对时间Alarm):对比当前时基又过了 Tick 数量后触发。
–Absolute(绝对时间Alarm):当 Counter 到达固定数值后触发,或者周期固定间隔触发。
上述代码启动了一个 1 秒的周期类型的 RelativeAlarm
此 Alarm 与 Core0_App_100msTask 连接用于周期性的激活任务。
CounterType: 采用硬件时钟并关联到硬件 Timer
Counter Tick Per Base: 每 100 个硬件 TimerCounter 触发 OS Counter 累加
Seconds Per Tick: 1us, 为了增加 OS 调度速度,精度不宜过小。
基础任务英文缩写为:BCCtask,主要包括以下特性:
Task Activation 是指同时只允许一次任务激活
Priority 指任务优先级, 高优先级任务可以抢占低优先级任务(如果低优先级任务配置成支持抢占类型)
Stack Size 设置为1K (根据当前任务所需要 Stack 进行设置,如果 Stack 产生Overflow,OS 会在任务切换时报错挂死)
Type 类型为 Basic Task(基础任务)
Event 主要用于扩展类型任务的触发执行(从Waiting状态到Run状态)
扩展任务经常是运行在 while 循环中的,一般不会结束,但视应用场景也可以结束。
扩展任务可以进入 Waiting 状态,待事件触发后,继续执行
Task Activation 指同时只允许一次任务激活
Priority 指任务优先级, 高优先级任务可以抢占低优先级任务(如果低优先级任务配置成支持抢占类型)
Stack Size: 1K (根据当前任务所需要 Stack 进行设置,如果 Stack 产生Overflow,OS 会再任务切换时报错挂死)
– 任务激活方式,同时激活的任务按优先级排队执行,扩展类型任务可以由软件控制执行
– 任务切换时任务现场会保存再对应任务的 Task Stack 中,右侧下图 Task T2 黄色部分为任务切换程序执行。抢占过多会造成任务切换过多导致 CPURuntime 的损失。
任务同步管理用于管理多个任务共享的资源(数据和外设等),防止task1再读取共享数据的时候被 Task2 改写。
常规方法包含 (ExclusiveArea Handling):
中断服务程序再 OSEK OS 中具有高于任务的优先级
Category1, 不要 OS 接管,不受 OS 中断优先级等管理
Category2,中端触发后,OS 接管,受 OS 控制
如上述代码所示,中断向量表不直接指定中断服务程序,而是指向 Os_Hal_IsrRun程序由 OS 接管中断服务程序。
AUTOSAR 协议栈中的 OS 启动如下图所示:
1、执行 Os_InitMemory 初始化 OS 参数(OS 使用到的变量等)
2、执行 Call Os_Init() 初始化OS. (变量,OS 中断控制器,MPU 等)
3、执行 EcuM_Init() 初始化部分硬件模块(Port,Dio,Adc…)
4、执行 EcuM_StartOS() 启动 OS
5、再 OS 开始执行后 Task_Init 会首先被调用. 执行 EcuM_StartupTwo() ,此函数会调用 BswM_Init() 来初始化其他硬件模块(CAN/LIN/NVM…).
6、再 BswM_Init 函数最后执行 Rte_Start() 用于启动所有任务。
1、使能两个核并关联到到不同的 EcucParatition
2、建立两个 OSApplication 并分配到不同的 EcucParatition
3、每个 OSApplication 可关联不同的 Task/ISR 等,这样关联的任务就会在相应核执行
核间通信(已 Core0 到 Core1 通信为例)流程:
1、Core0 发送方通过RTE将数据写入 IOC 并触发 Core1 任务
2、Core1 执行完任务将结果通过 RTE 反馈到 IOC 并触发 Core0 任务
原文始发于微信公众号(汽车电子与软件):CP AUTOSAR OS 工程实践