AUTOSAR笔记:OS

Task

AUTOSAR定义2种Task:Basic Task(基础任务),Extended Task(扩展任务).

区别:Extended Task多了一个等待状态,相当于Linux中的阻塞态(等待外部IO事件).

Task可配置为自启动、Alarm周期触发、手动触发.

Basic Task

特点:优先级高的Task先执行,优先级低的可被抢占.

  1. 启动OS后,所有Task进入挂起状态;
  2. 由用户触发需要执行的Task(通常在Davinci中配置,可生成代码,如配置成初始化后执行,或100ms周期性执行);
  3. 被触发的Task进入准备状态,等待OS调用 <=> Linux 就绪态;
  4. OS根据优先级调度Task,如果有高优先级Task进入准备状态,OS就会暂停执行低优先级Task <=> 运行态;

Basic Task生命周期:

img
from ref [1]

Extended Task

Basic Task有个缺点:如果Basic Task需要等待IO事件,那么将会一直死循环等待,而不放弃CPU资源

Extended Task在Basic Task基础上添加了 等待状态,以解决该问题. Task在运行时,如果需要等待IO资源(可能是某个事件,WaitEvent),那么会主动放弃CPU资源,进入等待状态. 这样,低优先级Task得以执行. 等到等待的资源得以满足(事件发生,setEvent),那么Task会进入准备状态.

img
from ref. [1]

Alarms

Task从 挂机状态 → 准备状态,可由一个配置好的周期触发完成,这个周期就是由Alarms(闹钟)完成.

Alarams设置一个周期定时,不仅能触发Task,还能设置Event事件,或者调用回调函数.

可在Davinci中完成Alarms设置,或者Task中修改.

Alarms的基准时间是怎么来的?

通过硬件定时器产生的Tick Time(如S32K144, core interrupt 15 System timer/SysTick),Tick时间跨度可在Davinci中配置. 当SysTicker.counter达到指定值时,Alarms设置的定时就触发了.

Interrupt

中断优先级 > Task

AUTOAR OS中断又分为:一类中断、二类中断

优先级:一类中断 > 二类中断

  • 一类中断(Cat1)

不访问OS服务,中断执行完后,返回中断发生处(相当于MCU原始中断). OS依然按正常的调度执行

  • 二类中断(Cat2)(常用)

访问部分OS服务,但有些OS服务不被允许,如TerminateTask. 中断执行完后,OS重新调度Task

IOC

IOC(Inter OS Application Communicatoin),在内存中开辟一个被保护的IOC区域,用于核间通信. 支持多输入多输出,由OS管理,Davinci中一般自动生成,无需修改.

OS Resource

2个以上Task并行访问同一资源,可能出错. OS Resource用于避免这类问题,将资源锁住,类似于Linux 互斥锁.

既然用到锁,就存在死锁问题. AUTOSAR OS如何解决死锁问题?

答:有多种方法.
1)优先级天花板协议(PCP)
当任务取得资源时,临时提升其优先级至资源的天花板级别

2)严格资源排序
所有任务必须按顺序申请资源,违反顺序的配置将触发编译报错

3)超时强制释放资源

另外,有2种设计方法可以避免死锁:
1)单一资源请求原则:每次只申请一个资源,在下次申请资源前必须释放

2)不可抢占原则:确保对资源的操作是原子操作,无法被中断. 确定是禁用中断时间通常有严格要求,如MPC5744P要求<20μs

OS运行实例

下面看一个OS启动后的运行实例,看看5个Task(Task1..5)发生了什么.

img
from ref. [2]

  1. 启动OS

红色代表当前流程运行之处(可以认为是PC指针). 启动OS后,会触发3个能自启动的Task("AutoStart=true"所指3个Task)

  • BtInit(Task1):Task1先运行Initialization代码进行初始化,调用IOC与Task2进行了核间通信,最后Terminate结束任务. Task1通过ioc_Write向IOC写数据,Task2通过ioc_Read从IOC读取数据.

  • EtReceive(Task3):Task3先运行Application code2,然后等待Event1事件.

  • ErTransmit(Task5):Task5先运行Application code4,然后获取OS Resource资源,但未释放(未调用ReleaseResource);接着等待Event2、3

如果没有Alarms和Interrupt(中断),各任务能运行的代码到此为止.

  1. 周期Alarms

img
from ref. [2]

如果Alarms突然触发,会先触发(ActivateTask)Task2 BtCyclic,并且设置Event1

  • BtCyclic(Task2):先运行Application Code1;再通过ioc_Read读取IOC数据;最后Terminate结束

  • EtReceive(Task3):由于等到的Event1事件到来,那么继续执行代码,它会通过ActivateTask触发Task4

  • BtCyclic(Task4):先运行Application Code3;再设置Event2,会触发Task5的执行(如果它在等待Event2);然后,获取OS Resource,但是,由于Task5 EtTransmit一直占用Resource不释放,因此获取失败;最后直接Terminate

  • EtTransmit(Task5):被BtCyclic触发事件Event2后,继续执行Application Code5

  1. 中断Interrupt

img

接着2,如果此时发生中断

  • ISR Cat2:先获取Resource资源,但会失败,因为Task4未释放;然后,设置Event3,由于Task5 EtTrasmit正在执行Application Code5,未等待Event3,所以此时设置Event3没有效果

  • EtTransmit:继续执行Application Code5

问题:如果Interrupt比Alarm先到呢?

答:ISR Cat2会获取Resource,但不会释放,接着设置Event3;
Task5会获取Resource失败,而在等待Event3时,由于ISR Cat2设置Event3而触发运行Application Code5;
等Alarm到来后,Task4 设置Event2没有效果,获取Resource失败.

参考

[1] AutoSAR系列讲解(实践篇)7.5-OS原理进阶(上)

[2] AutoSAR系列讲解(实践篇)7.6-OS原理进阶(下)

[2] Linux进程管理

[3] Linux 自旋锁,互斥量(互斥锁),读写锁

posted @ 2025-07-08 13:42  明明1109  阅读(465)  评论(0)    收藏  举报