-
Autosar OS基础
-
概述
-
Autosar简介
-
定义
- Autosar(汽车开放系统架构)是由汽车制造商,软件供应商及其他相关厂商专为汽车软件合作指定的规范、标准、架构。
-
目标
- 建立一个独立于硬件的分层软件架构:实现高内聚、低耦合,提高软件的可重用性、可扩展性和互操作性。
- 为应用实施提供一套方法论:包括制定无缝的软件架构堆叠流程,并将应用软件无缝整合至ECU中。
- 制定统一的车辆应用接口规范:作为应用软件整合的通用标准,以便于软件构件在不同汽车平台之间的复用。
- 降低开发与维护成本:通过标准化和模块化,减少重复性工作,缩短开发周期,促进汽车电子系统的创新和发展。
-
优点
- 缩短开发周期,提高开发效率
- 提高代码的可复用性
- 协同开发,方便维护
- 工具配置,降低手写代码导致的问题,提高代码质量
-
Autosar应用领域
- 汽车电子控制系统
- 车载网络和系统内存管理
- AUTOSAR架构实现对车载网络
- 系统内存管理
- 系统诊断
- 自动驾驶系统
- ......
-
Autosar OS
-
概述
- Autosar OS是基于OSEK OS继承发展而来,完全包含了OSEK OS的功能并对其进行了扩展。Autosar OS位于Autosar OS软件架构的BSW层,具体在BSW/Service Layer/Autosar OS。Autosar OS是整个Autosar架构中一个关键的组成部分,提供了任务管理,调度,通信,资源管理,安全管理等重要功能。
-
特点
- 静态配置:Autosar OS认为,一旦配置确定,软件生成后,所有使用内存资源(RAM/ROM)都确定好了,OS为了避免内存泄漏导致的安全问题,不支持动态内存管理,且不提供动态内存管理相关的任何接口和方法。
- 能够推断系统的实时性能:Autosar 没有规定Os_Monitor的实现方法和测量,各个软件供应商可以按照自身条件去开发属于自己的Os_Monitor功能;另,为了方便性能的检查,各个OS供应商的工具中一般生成orti文件供劳德巴赫等调试工具使用,以方便调试的时候观察系统性能
- 提供基于优先级的调度策略:Autosar OS中存在Cat1 ISR, Cat2 ISR, Task三类现场,这三类现场的优先级关系满足Cat1 ISR > Cat2 ISR > Task,同类现场之间遵循优先级调度策略(注:许多厂家的工具中Task优先级配置的数字越高,其Task优先级越高,这与许多OS不一样)
- 提供保护功能(内存、时间等):Autosar OS为了系统的安全性和可控性,提供了多种保护功能,其中包括栈溢出检查,内存保护功能(SC3/SC4),时间保护功能(SC2/SC4)等
- 可运行在MCU上且无需外部资源:Autosar OS对系统资源要求极低,几乎只要MCU存在一个定时器就能部署一个简易的Autosar OS并运行。
-
Autosar OS内容
-
裁剪等级(Scalability Class)
- SC1:包含OSEK OS的基本功能以及调度表(Schedule Table)
- SC2:在SC1的基础上增加了时间保护(Timing Protection)功能
- ExecutionBudget
- TimeFrame
- AllInterruptLockBudget
- OsInterruptLockBudget
- ResourceLockBudget
- SC3:在SC1的基础上增加了内存保护(Memory Protection)功能
- SC4:包含OSEK OS的基本功能、调度表、时间保护以及内存保护四个功能,是功能最全面的裁剪等级
-
OS相关对象
-
Core
-
Application:Trusted/NoTrusted
-
Alarm
- OsAlarmAction
- OsAlarmActivateTask
- OsAlarmCallback
- OsAlarmIncrementCounter
- OsAlarmSetEvent
-
Counter
- OsCounterType
- HARDWARE:由硬件驱动
- SOFTWARE:通过调用IncrementCounter驱动
-
Isr
- OsIsrCategory
- CATEGORY_1:一类中断响应速度快,但不受OS控制
- CATEGORY_2:二类中断相对一类中断响应速度慢,但受OS控制
-
ScheduleTable
- 类型
- 按是否同步划分
- 按是否循环划分
- 按启动方法分
- 绝对启动
- 相对启动(隐式同步表不支持相对启动)
- 同步启动
- 行为
- OsScheduleTableEventSetting
- OsScheduleTableTaskActivation
-
Task
- 类型
- 扩展(Extend)Task
- 扩展Task需要依赖于Event事件,因此也有将其称之为"事件Task"
- 标准(Basic)Task
- 状态
- SUSPENDED
- READY
- RUNNING
- WAITING(标准Task没有Waiting状态)
-
Event
- 同扩展(Extend)Task配合一起完成任务, 不可被标准(Basic)Task使用
-
Ioc
- 描述
- “IOC”负责操作系统应用程序之间的通信,特别是跨核心或内存保护边界的通信。由于一般应用于跨核通信,所以许多场合下也称其为核间通信。如果系统中只存在单核或没有内存保护,则也可以省略IOC模块。(Ioc通常和spinlock配合使用)
- 类型
- 按通信对象分
- 传输方式
- 队列传输
- Os_Ioc_Send
- Os_Ioc_Receive
- 非队列传输
-
Resource
- Resource(资源锁)是实现核内资源互斥访问的一种手段,可以对临界资源起到绝对的“原子操作”的保护。资源锁为了实现资源访问的绝对互斥,以及为了避免死锁,如果是Task获取资源锁,则会临时提升该Task的优先级到所有期望获取该资源锁的Task的最高优先级,并屏蔽掉所有期望获取该资源锁最高优先级的二类中断及其以下的优先级。
-
spinlock
- Spinlock(自旋锁)对作用类似于Resource(资源锁),不同的是Spinlock(自旋锁)实现核间资源互斥访问的一种重要手段,可以在核间临界资源起到绝对的“原子操作”的保护。Spinlock为了实现资源访问的绝对互斥,需要芯片支持原子操作指令或spinlock Ip,以此实现Spinlock功能。Spinlock也常常配置Ioc实现核间通信功能。注:为了避免自旋锁死锁,不建议在同一个核的不同现场使用同一个Spinlock。
-
Api介绍及使用
-
ActivateTask
- 原型
- StatusType ActivateTask (TaskType TaskID)
- 描述
- 此服务函数会把指定的Task从挂起状态转换为就绪状态,系统会根据调度策略去执行指定的Task
- 形参
- 返回值
-
TerminateTask
- 原型
- StatusType TerminateTask (void)
- 描述
- 此函数会结束当前的Task,调用此函数后该Task会从RUNNING状态转换到SUSPENDED状态。此函数正常执行不会返回,遇到错误会返回错误值
- 形参
- 返回值
-
ChainTask
- 原型
- StatusType ChainTask (TaskType TaskID)
- 描述
- 此函数结束当前调用者的Task,切换到指定的Task执行。此函数正常执行不会返回,遇到错误会返回错误值
- 形参
- 返回值
-
Schedule
- 原型
- StatusType Schedule (void)
- 描述
- 该接口将执行一次系统调度器功能,如果存在比执行该接口的Task优先级更高的Task处于就绪态,则会发生系统调度,切换上下文。
- 形参
- 返回值
-
GetTaskID
- 原型
- StatusType GetTaskID (TaskRefType TaskID)
- 描述
- 形参
- 返回值
-
GetTaskState
- 原型
- StatusType GetTaskState (TaskType TaskID, TaskStateRefType State)
- 描述
- 形参
- TaskID:被询问状态的Task 标识。
- State:询问Task状态的指针。
- 返回值
-
DisableAllInterrupts
- 原型
- void DisableAllInterrupts (void)
- 描述
- 禁用全部中断,包括一类中断和二类中断DisableAllInterrupts只禁用本核的所有中断,对其他核不应该有影响。时间保护的中断不受影响。 注意:DisableAllInterrupts不可以嵌套调用。
- 形参
- 返回值
-
EnableAllInterrupts
- 原型
- void EnableAllInterrupts (void)
- 描述
- 恢复DisableAllInterrupts().调用前保存的中断状态。
- 形参
- 返回值
-
SuspendAllInterrupts
- 原型
- void SuspendAllInterrupts (void)
- 描述
- 挂起全部中断,保存所有能识别到的中断状态,禁用硬件支持的所有可以禁用的中断。
- 形参
- 返回值
-
ResumeAllInterrupts
- 原型
- void ResumeAllInterrupts (void)
- 描述
- 恢复调用SuspendAllInterrupts()之前保存的中断状态。
- 形参
- 返回值
-
SuspendOSInterrupts
- 原型
- void SuspendOSInterrupts (void)
- 描述
- 挂起OS中断,保存所有二类中断状态,禁用二类中断。
- 形参
- 返回值
-
ResumeOSInterrupts
- 原型
- void ResumeOSInterrupts (void)
- 描述
- 恢复SuspendOSInterrupts调用前保存的中断状态
- 形参
- 返回值
-
GetResource
- 原型
- StatusType GetResource (ResourceType ResID)
- 描述
- 获取资源锁,此函数提供让代码进入临界区的功能。进入临界区的任务/中断不能被资源锁优先级以下的任务/中断打断。
- 形参
- 返回值
-
ReleaseResource
- 原型
- StatusType ReleaseResource (ResourceType ResID)
- 描述
- 释放资源锁,本服务用来结束代码临界区,恢复Task/ISR2原来的优先级
- 形参
- 返回值
-
SetEvent
- 原型
- StatusType SetEvent (TaskType TaskID, EventMaskType Mask)
- 描述
- 形参
- TaskID :计划被修改状态的Task 标识。
- Mask:事件的掩码。
- 返回值
-
ClearEvent
- 原型
- StatusType ClearEvent (EventMaskType Mask)
- 描述
- 形参
- 返回值
-
GetEvent
- 原型
- StatusType GetEvent (TaskType TaskID, EventMaskRefType Mask)
- 描述
- 形参
- TaskID:被询问的Task的标识。
- EventMaskRefType Mask :获取事件掩码的指针。
- 返回值
-
WaitEvent
- 原型
- StatusType WaitEvent (EventMaskType Mask)
- 描述
- 该函数使任务进入等待状态,直到指定的Event发生。任务在等待状态下不会占用CPU。当给定的Event被触发时,Task才会被激活。
- 形参
- 返回值
-
GetAlarmBase
- 原型
- StatusType GetAlarmBase (AlarmType AlarmID, AlarmBaseRefType Info)
- 描述
- 此函数可以读取Alarm的基本描述信息,返回值是存到AlarmBaseType类型的数据
- 形参
- 返回值
-
GetAlarm
- 原型
- StatusType GetAlarm (AlarmType AlarmID,TickRefType Tick)
- 描述
- 此函数用来获取该Alarm当前Tick到下一次到期的Tick差值。
- 形参
- AlarmID:Alarm 标识。
- Tick:指针参数输入,输出的数据是在alarm到期之前的相对值。
- 返回值
-
SetRelAlarm
- 原型
- StatusType SetRelAlarm (AlarmType AlarmID, TickType Increment, TickType Cycle)
- 描述
- 此函数设置指定的Alarm,经过Increment 参数指定的Tick后,Alarm会被触发,此后按照Cycle指定的周期触发Alarm。
- 形参
- AlarmID:指 Alarm标识。
- Increment:设置Alarm后第一次激活Alarm的相对tick值。
- Cycle:Alarm的周期值增量值,单次alarm的cycle应该设置为0。
- 返回值
-
SetAbsAlarm
- 原型
- StatusType SetAbsAlarm (AlarmType AlarmID, TickType Start, TickType Cycle)
- 描述
- 此函数设置指定的Alarm,当第一次到达Start指定tick,Alarm会被触发。此后按照Cycle指定的周期触发Alarm。
- 形参
- AlarmID:指 Alarm标识。
- Start:设置Alarm后第一次激活Alarm的绝对Tick值。
- Cycle:周期Alarm的周期增量值,单次Alarm的Cycle应该设置为0。
- 返回值
-
CancelAlarm
- 原型
- StatusType CancelAlarm (AlarmType AlarmID)
- 描述
- 此函数为取消指定的Alarm,设置Alarm状态为OS_ALARM_OFF。
- 形参
- 返回值
-
GetActiveApplicationMode
- 原型
- AppModeType GetActiveApplicationMode(void)
- 描述
- 该服务返回当前活动的应用程序模式(即传递给 StartOS() 的 parameter 的值)。该服务可用于编写依赖于应用程序模式的代码
- 形参
- 返回值
-
StartOS
- 原型
- void StartOS (AppModeType Mode)
- 描述
- 形参
- 返回值
-
ShutdownOS
- 原型
- void ShutdownOS (StatusType Error)
- 描述
- 形参
- Error:执行ShutdownOS时传入的错误码。
- 返回值
-
GetApplicationID
- 原型
- ApplicationType GetApplicationID(void)
- 描述
- 形参
- 返回值
-
GetISRID
-
CallTrustedFunction
- 原型
- StatusType CallTrustedFunction (TrustedFunctionIndexType FunctionIndex, TrustedFunctionParameterRefType FunctionParams)
- 描述
- 形参
- FunctionIndex:受信函数标识
- FunctionParams:受信函数入参。
- 返回值
-
CheckISRMemoryAccess
- 原型
- AccessType CheckISRMemoryAccess( ISRType ISRID, MemoryStartAddressType Address, MemorySizeType Size)
- 描述
- 该服务可返回二类中断对需要检查的地址范围的可操作权限
- 形参
- ISRID:指二类中断的标识
- Address:需要检查的起始地址
- Size:需要检查的内存区域的大小
- 返回值
-
CheckTaskMemoryAccess
- 原型
- AccessType CheckTaskMemoryAccess (TaskType TaskID, MemoryStartAddressType Address, MemorySizeType Size)
- 描述
- 该服务可返回Task对需要检查的地址范围的可操作权限
- 形参
- TaskID:指Task标识
- Address:需要检查的起始地址
- Size:需要检查的内存区域的大小
- 返回值
-
CheckObjectAccess
- 原型
- ObjectAccessType CheckObjectAccess (ApplicationType ApplID, ObjectTypeType ObjectType, Os_AnyType Object)
- 描述
- 检查Application是否可以范围指定的OS对象
- 形参
- ApplID:要检查其访问权限的 OS-Application 标识符。
- ObjectType:对象的类型(OBJECT_TASK、OBJECT_ISR、OBJECT_ALARM、OBJECT_RESOURCE、OBJECT_COUNTER 或 OBJECT_SCHEDULETABLE)。
- Object:要检查其访问权限的对象标识符。
- 返回值
- NO_ACCESS/ACCESS(是否允许访问该对象)
-
CheckObjectOwnership
- 原型
- ApplicationType CheckObjectOwnership (ObjectTypeType ObjectType, Os_AnyType Object)
- 描述
- 该服务可获取要检查的对象对应的Application 标识
- 形参
- ObjectType:对象的类型(OBJECT_TASK、OBJECT_ISR、OBJECT_ALARM、OBJECT_RESOURCE、OBJECT_COUNTER 或 OBJECT_SCHEDULETABLE)。
- Object:要检查其访问权限的对象标识符。
- 返回值
-
StartScheduleTableRel
- 原型
- StatusType StartScheduleTableRel (ScheduleTableType ScheduleTableID, TickType Offset)
- 描述
- 形参
- ScheduleTableID:调度表标识。
- Offset:启动偏移。
- 返回值
-
StartScheduleTableAbs
- 原型
- StatusType StartScheduleTableAbs (ScheduleTableType ScheduleTableID, TickType Offset)
- 描述
- 形参
- ScheduleTableID:调度表标识。
- Offset:启动偏移。
- 返回值
-
StopScheduleTable
- 原型
- StatusType StopScheduleTable(ScheduleTableType ScheduleTableID)
- 描述
- 形参
- 返回值
-
NextScheduleTable
- 原型
- StatusType NextScheduleTable (ScheduleTableType ScheduleTableID_From, ScheduleTableType ScheduleTableID_To)
- 描述
- 该服务可以指定在from表执行完当前周期后继续执行的to表
- 形参
- ScheduleTableID_From:原调度表标识
- ScheduleTableID_To:目的调度表标识
- 返回值
-
StartScheduleTableSynchron
- 原型
- StatusType StartScheduleTableSynchron(ScheduleTableType ScheduleTableID)
- 描述
- 以同步的方式启动调度表。该接口只能用于启动显式调度表(此接口只能在SC2/SC4的裁剪等级下使用)
- 形参
- 返回值
-
SyncScheduleTable
- 原型
- StatusType SyncScheduleTable (ScheduleTableType ScheduleTableID, TickType Value)
- 描述
- 同步显式调度表时间。(此接口只能在SC2/SC4的裁剪等级下使用)
- 形参
- ScheduleTableID:调度表标识。
- Value:需要同步的时间值。
- 返回值
-
GetScheduleTableStatus
- 原型
- StatusType GetScheduleTableStatus (ScheduleTableType ScheduleTableID, ScheduleTableStatusRefType ScheduleStatus)
- 描述
- 形参
- ScheduleTableID:调度表标识
- ScheduleStatus:调度表状态
- 返回值
-
SetScheduleTableAsync
- 原型
- StatusType SetScheduletableAsync(ScheduleTableType ScheduleTableID)
- 描述
- 停止显示调度表的时间同步(此接口只能在SC2/SC4的裁剪等级下使用)
- 形参
- 返回值
-
IncrementCounter
- 原型
- StatusType IncrementCounter(CounterType CounterID)
- 描述
- 形参
- 返回值
-
GetCounterValue
- 原型
- StatusType GetCounterValue(CounterType CounterID, TickRefType Value)
- 描述
- 形参
- 返回值
-
GetElapsedValue
- 原型
- StatusType GetElapsedValue (CounterType CounterID, TickRefType Value, TickRefType ElapsedValue)
- 描述
- 形参
- CounterID:计数器标识
- Value:之前获取的计数器Tick数的指针并传出当前获取的Tick数。
- ElapsedValue:两次调用的Tick差值指针。
- 返回值
-
TerminateApplication
- 原型
- StatusType TerminateApplication (ApplicationType Application, RestartType RestartOption)
- 描述
- 形参
- Application:计数器标识
- RestartOption:重启方式,包括选择重启或不重启。
- 返回值
-
AllowAccess
- 原型
- StatusType AllowAccess (void)
- 描述
- 该调用将调用 OS-Application 的状态更改为 APPLICATION_ACCESSIBLE,前提是当前状态为 APPLICATION_RESTARTING。
- 形参
- 返回值
-
GetApplicationState
- 原型
- StatusType GetApplicationState (ApplicationType Application, ApplicationStateRefType Value)
- 描述
- 形参
- 返回值
-
ControlIdle
- 原型
- StatusType ControlIdle (CoreIdType CoreID, IdleModeType IdleMode)
- 描述
- 此调用设置核心的空闲模式。可以使用 OS_CURRENT_IDLEMODE() 宏读取为当前正在运行的内核设置的值。(此 API 是为 AUTOSAR 版本 4.1.x 添加的,但 RTA-OS 也允许在早期版本中使用它。)
- 形参
- CoreID :Core标识
- IdleMode:要设置的模式
- 返回值
-
GetCurrentApplicationID
- 原型
- ApplicationType GetCurrentApplicationID(void)
- 描述
- 获取当前正在运行的Application标识(在CallTrustedFunction中调用此函数获取的应用分区标识不再是当前线程的应用分区标识,而是CallTrustedFunction所属的应用分区标识。)
- 形参
- 返回值
-
OS错误机制
-
系统保护策略
-
系统服务类保护
- 参数无效或值超出范围
- E_OS_ID:调用系统服务,为调用对象输入的标识未定义。
- E_OS_VALUE:调用系统服务时,为调用对象输入的参数超过配置项规定的范围值
- E_OS_ILIEGAL_ADDRESS:无效地址作为参数传给OS系统服务
- E_OS_PARAM_ADDRESS:空指针作为参数传给OS系统服务
- 非法上下文调用
- E_OS_CALLEVEL:AUTOSAR OS标准规定了调用系统服务的有效上下文,如果用户调用系统服务时上下文不符合则返回该错误类型。
- 期望行为缺失
- E_OS_MISSINGEND:Task未调用TerminateTask() 或者ChainTask()结束
- E_OS_DISABLEDINT:CAT2 ISR在结束时存在未释放的中断,或在禁止中断后调用了除操作中断外的其他OS服务
- E_OS_RESOURCE:Task/CAT2 ISR结束时存在未释放的资源
- E_OS_SPINLOCK:Task/CAT2 ISR结束时存在未释放的自旋锁
- 跨核跨应用分区调用系统服务
- E_OS_ACCESS:调用者和调用对象分属不同的应用分区,且调用者对调用对象没有访问权限
- E_OS_CORE:期望跨核去调用不允许跨核访问的OS服务,或访问的目标核无效或已停止运行。
- 对象状态导致调用错误
- E_OS_NOFUNC:未按照OS的Api调用顺序调用接口,如未调用GetResource就ReleaseResource,使用CancelAlarm去结束一个未运行的Alarm等行为。
- E_OS_STATE:表示调用服务的对象状态错误,例如调用TerminateApplication关闭已经被关闭的状态为APPLICATION_TERMINATED的Application
- E_OS_SERVICEID:调用CallTrustedFunction 输入参数functionIndex指定的函数没有被配置
-
时间保护
- E_OS_PROTECTION_TIME:Task/CAT2 ISR的执行时间超过了配置时设置的预设时间(OsTaskExecutionBudget、OsIsrExecutionBudget)
- E_OS_PROTECTION_ARRIVAL:Task/CAT2 ISR连续激活时间小于配置时设置的间隔最小时间(OsTaskTimeFrame/OsIsrTimeFrame)
- E_OS_PROTECTION_LOCKED:禁止中断时间超过预设的最小时间(InterruptLockBudget)
-
内存保护
- E_OS_STACKFAULT:栈溢出错误,该功能需要使能栈监控功能才可以使用。
- E_OS_PROTECTION_MEMORY:内存检测违规,该功能错误一般出现在SC4的裁剪等级下。
-
系统错误报告处理
-
系统应用错误
- 错误原因:应用错误(Application Errors)是指OS不能执行需求的OS API 服务引发的错误。
- 处理方式
- 如果配置了全局的ErrorHook,则会将错误报告给ErrorHook集中处理,然后如果对应现场所属的Application配置OsAppErrorHook(AppErrorHook只支持在SC3和SC4下开启),则会调用AppErrorHook进行单独的应用分区错误管理
-
保护性错误
- 错误原因:保护错误(Protection Errors)由应用Application执行时违背预先设定的界限或者进入未处理的异常和中断引发的错误
- 处理方式
- 发生保护性错误OS将会调用ProtectionHook(SC1不支持该功能)进行处理,用户可以在ProtectionHook中更具错误码分析错误原因,并须设置返回值来告诉系统接下来的操作,如果未配置ProtectionHook则会执行Shutdown操作
-
系统严重错误
- 错误原因
- 系统因为保护性错误进入ProtectionHook ,用户填写返回值PRO_TERMINATETASKISR,但是调用者Task/ISR2和错误不相关
- 系统因为保护性错误进入ProtectionHook ,用户填写返回值无效
- OS供应商自定义行为,如重复进入ErrorHook,如初始化阶段无效CoreID索引等。
- 处理方式:系统将调用ShutDownOs关停系统或屏蔽所有中断进入死循环进入宕机状态。
-
OS基础问题排查
- 系统错误:能够由OS记录的错误都属于系统错误,该类错误只需要在进入ErrorHook/ProtectionHook时记录对应的ErrorID和现场,就大致可以判断出来出现问题的地方和原因,OS本身也会记录最后一次出现系统错误的现场和原因,具体实现策略和记录方式需要视具体OS而定。OS正常运行工程中不应该出现任何错误,一旦出现错误需要立即解决。
- 现场错误:一般出现在系统切换上下文时没有切换到期望的地方执行代码,此类问题可能比较明显也可能比较隐蔽,一旦出现此类问题,首先应该考虑是否存在栈溢出,栈踩踏的事件发生,一般需要检查需要使用较多局部变量的现场。此外,也可能是由于OS本身切换现场时存在bug。
- OS频繁报Task激活错误:此类错误首先需要检查高优先级Task的执行时间是否过长,是否存在长时间的临界保护或资源保护,需要检查task激活时间点是否有效使用offset来均衡负载,需要检查是否存在高频中断,最后需要检查core的cpuload
- 硬件异常:根据异常中断判断产生异常原因,如除0异常,内存异常,FPU异常,指令异常等,需要第一时间抓到异常现场,针对性的分析原因。
- 。。。。。。