Autosar CP 操作系统详解

2023-12-13 10:49:18

一、背景介绍

我们知道传统所说的“裸机编程”就是不带操作系统的编程,在统需求相对比较简单的情况下使用裸机编程可以满足要求。

在Main函数中,写一个大循环(While),然后加一个定时器,分时间片的方式,定时去执行代码,就完成了简单的调度功能。

但是随着系统需求越来越复杂,此时就需要用到模块化设计方法以及多任务编程思想,否则后期软件升级维护成本将会急剧增加。

此时迫切需要一种机制来替我们完成各个任务之间的调度功能,使得开发人员能够更关注于应用软件的开发,提高软件开发效率,为此OS(Operation System)便应运而生

二、什么是操作系统

1、介于应用层和目标硬件之间,提供中间层的软件。

2、提供应用软件和目标硬件之间的抽象层

?

(1)管理分配控制器资源(CPU、内存、设备等)。

(2)控制执行应用层程序和I/O设备的操作

(3)以有效率的方式使用控制器硬件资源

三、操作系统分类

1、分时操作系统(TSOS)

分时操作系统是使一台计算机采用时间片轮转的方式同时为几个、几十个甚至几百个用户服务的一种操作系统。

把计算机与许多终端用户连接起来,分时操作系统将系统处理机时间与内存空间按一定的时间间隔,轮流地切换给各终端用户的程序使用。

由于时间间隔很短,每个用户的感觉就像他独占计算机一样。分时操作系统的特点是可有效增加资源的使用率。例如UNIX系统就采用剥夺式动态优先的CPU调度,有力地支持分时操作。

上图中,CPU是不可抢占的,即便高优先级的任务就绪了,也不能马上中断低优先级任务而得到执行,必须要等到低优先级任务主动挂起(sleep)或者时间片结束才能得到执行。

我们平常使用微软的windows、谷歌的Android、苹果的mac OS X这些操作系统,会遇到应用程序无响应的问题,也是因为这个原因。即:硬件资源一旦被其他任务占用,本任务就得不到立即执行

2、实时操作系统(RTOS)

实时操作系统”(Real Time OS)泛指所有据有一定实时资源调度以及通讯能力的操作系统。而所谓“实时”,不同语境中往往有着非常不同的意义。

某些时候仅仅用作“高性能”的同义词。但在操作系统理论中“实时性”所指的通常是特定操作所消耗的时间(以及空间)的上限是可预知的。

比如,如果说某个操作系统提供实时内存分配操作,那也就是说一个内存分配操作所用时间(及空间)无论如何也不会超出操作系统所承诺的上限。?

实时性在某些领域非常重要,比如在汽车行业、工业控制、医疗器材、影音频合成、以及军事领域,实时性都是无可或缺的特性。

?在上图中右边的任务2优先级高于左边的任务1当优先级更高的任务2就绪的时候,即便任务1正在运行中,也必须立刻交出CPU的使用权,也就是引入“中断”机制,先执行任务2,等任务2执行完或者主动挂起(sleep)让出CPU的时候,任务1才能接着运行。在真实的程序运行中,一般有多任务执行的情况下,就会引入“中断”机制。

?

3、硬件虚拟化技术

理论上两种类型的操作系统有着本质的区别,但Hypervisor(硬件虚拟化技术,提供虚 拟平台支持多操作系统)的出现,让两者出现了“融合”。

Hypervisor是一种将操作系统与硬件抽象分离的方法,以达到host machine的硬件能同时运行一个至多个虚拟机作为guest machine的目的,这样能够使得这些虚拟机高效地分享主机硬件资源

4、分时操作系统和实时操作系统的区别

评判标准

分时操作系统

实时操作系统

调度能力

高吞吐量

高效率使用系统资源

规定时间内完成所需任务(即使在资源使用率很高的情况下)

响应速度

快速平均响应时间

可预测对紧急事件的快速响应能力

已知最坏情况下对事件响应的时间

超负荷

平等共享过载资源的使用

当系统对事件的处理过载后,无法满足所有的任务在规定时间内完成响应,但仍然可以保证系统对于关键事件的处理

5、为什么使用RTOS?

(1)最大化使用CPU。

(2)提供良好定义的操作系统相关的功能和行为。

(3)调度行为与时间相关,与应用功能分离。

(4)硬件与软件的实现对应用开发者不可见。

(5)简化软件系统设计。

(6)操作系统成为接口(API),而非硬件。

(7)支持代码生成。

(8)提供软件复用、移植的能力。

6、分时操作系统和实时操作系统的应用场景

  • 对于安全气囊控制器来说,由于这是与安全相关的关键功能,极小的时间误差(太早或太迟)都会产生灾难性后果,甚至导致人员伤亡,所以必须使用实时操作系统;
  • 对于车载终端来说,我们可能需要一边打电话,一边进行实时导航,所以使用分时操作系统。

四、Autosar CP操作系统

1、CP Autosar 概览图

CP AUTOSAR OS 不支持动态创建任务,所有 OS 行为需要在编译时进行定义。

对于传统汽车电子开发领域,早期使用的OS则是OSEK OS, 其中OSEK是德文“Offene Systeme und deren Schnittstellen für die Elektronik im Kraftfahrzeug”的缩写,译为汽车电子开放系统及接口

OSEK OS是一个为满足汽车电子可靠性、实时性、成本敏感性等需求而打造的实时单核操作系统(RTAOS)。

AUTOSAR OS 基于OSEK OS继承发展而来。

?

AUTOSAR OS根据是否支持时间保护内存保护细分为4种可扩展级别

等级

多核

内存保护

时间保护

调度表

OSEK OS

Comments

SC1

×

×

包含标准OSEK OS,还定义了标准的计数器接口和轮询的调度表。

SC2

×

SC2=SC1+时间保护和监控。

时间保护:任务时间执行过长时,被停止。

时间监控:防止任务时间过长而影响其他任务的实时性。

SC3

×

SC3=SC1+内存保护。阻止未授权访问安全相关软件组件的内存区域。

SC4

SC4=SC1+时间保护+内存保护。

配置位置:

(1)TimingProtection

时间保护作为保证Task和Isr运行的准确性,时间保护需新建立Counter,做为时间保护的时间计算机制,可确保连续Task或Isr的时间、锁Ⅱ类中断时间、锁所有中断时间和Task或Isr的运行时间,出现超时则进ProtectionHook,记录超时信息。

(2)MemoryProtection

内存保护是做为对数据区的一种保护,可对Core、Application、Isr和Task进行保护,设置保护起始地址和结束地址,在访问时,若不满足访问权限的用户进行访问则会进入ProtectionHook,记录错误信息。

2、六大基本对象?

基本对象

功能含义

Counter

用于作为Alarm或者Schedule Table的触发基准

Alarm

用于定时触发某个Task或者某个Event

Schedule Table

用于定时同步触发多个Task或者多个Event

Task

Autosar OS调度的基本功能单元

ISRs

内外部中断(主要包含Category Ⅰ与Category Ⅱ级中断)

Resource

用于多个Task访问同一个资源时,防止并行访问出错

举个小例子,方便大家记住:

OS如果是【公司】,Core则是其中一个【部门】,Application就是某个部门下面的一个【小组】,Object就是组内的各个【员工】,大家分工配合完成整个OS的正常运转。如下图:

2.1、Core

Core作为系统任务的处理者,Core是直接指向代码运行的,Core越多,那么该系统的处理能力就越强。

2.2、Application

单个Core上有多个Application。为什么会有Application的概念?原因是当单个Object出现问题时,不至于影响整个Core。单个Application出现问题,可以重启或关闭当前Application,做到了独立管理一部分Object单元。

OS Application可分为TrustedNot Trusted这两种类型。

Trusted OS Application:可以运行在监控或保护功能关闭的情况下,对于内存或者OS Api的访问没有限制;如果处理器支持,可以运行在特权模式,OS默认Trusted类型的OS Application不会引发内存相关故障,如果发生了内存故障,系统稳定性将不再保证,可能需要关闭OS。

Non-Trusted OS Application:不允许关闭监控或保护功能,对于内存或OS Api的访问也受权限控制,也不允许运行在特权模式

2.3、Counter

Counter对系统来说就是系统的心脏,通过晶振的方式进行计数,得到的计数在进行时间的计算。每个Count都会与芯片定时器进行结合,然后进行中断,在中断时处理激活任务、激活事件和计算时间保护等。

Counter概念的引入是为了实现对硬件计数器以及软件计数器的管理,为Alarm与Schedule table提供支持。即多个Alarm可以共用一个Counter,一个Schedule Table只能由一个Counter来驱动?

Counter按照AUTOSAR定义可分为以下两种:

  • Hardware Counter:?该Counter的增加由硬件外设驱动,如Gpt或者timer等;
  • Software Counter:该Counter的增加通过调用API函数IncrementCounter来实现,且每次只能增加1;

?基本原则:优先使用Hardware Counter,因为可以根据Task的激活状况来减少无意义的时钟中断。

?上图清晰的表现了Counter是如何驱动Schedule Table和Alarm的。

2.4、Alarm

警报处理是根据Counter设置到时做一些动作,这些动作包含激活Task激活Event通知回调函数设置软件Couter

而警报器还区分绝对时间警报相对时间警报

绝对时间:设置具体时间,例如10点10分为警报时间,到时间则开始警报;

相对时间:设置一段时间,例如设置10分钟后警报,则到10分钟后开始警报。

同时警报器还支持自动启动,设置自动则到期直接警报。

2.5、ISRs

中断是我们经常使用的,中断分为Ⅱ类中断和Ⅰ类中断。

?Ⅰ类中断:不归Os调度管理,且Ⅰ类中断的优先级高于Ⅱ类中断,Ⅰ类中断总是可以打断Ⅱ类中断的执行。不访问OS服务,中断结束后,直接返回中断处,如下图:

Ⅱ类中断:归于Os调度管理的,中断的上下文管理,栈的管理都由Os管理。会访问OS服务,中断结束后,会发生一次OS的task的重新调度,如下图:

每个中断处理程序将在代码执行期间阻止所有优先级相同较低的中断。中断、任务的详细优先级如下图:

在编写中断处理程序时,处理程序执行时长尽可能短。长时间运行的处理程序会为低优先级中断的服务增加额外的延迟。

使用中如果需要在中断中处理较多的代码,可以采用:将代码写到Task中,再通过中断来激活Task,这样更低优先级的中断任务可以打断该Task,从而减少低优先级中断的延迟,示例代码如下?:

2.6、Task

任务分为Basic任务Extend任务

Basic 任务:任务不能停止,所以无法等待Event激活。

Extend 任务:任务可以停止,只激活一次,等待Event激活,当处于Waiting状态时,会释放CPU资源。(扩展任务=基础任务+waiting状态)

?扩展任务示例:

任务还区分为可抢断任务不可抢断任务,不可抢断任务执行则不会被其他任务所打断。任务还区分是否为自动启动,自动启动任务启动一次后不会再次被激活。

2.7、Event

事件是与Extend Task结合实现的,只有在Extend Task中Event才会实现。Event属于等待某个动作,满足这个动作才会激活Event。

Event也区分为Cycle Event和Wait event。

Cycle Event:是通过Alarm周期进行激活Event实现调度;

Wait Event:是通过SetEvent来实现激活的,每次调用SetEvent激活一次Event。

Event

Description

TimingEvent

定时时间事件 由OS-时钟实现

DataReceivedEvent

数据接收事件 由OS-Event实现

DataReceiveErrorEvent

数据接收错误事件 由OS-Event实现

DataSendCompletedEvent

数据发送完成事件 由OS-Event实现

OperationInvokedEvent

操作调用事件 由OS-Event实现

AsynchronousServerCallReturnsEvent

异步服务器调用返回事件 由OS-Event实现

ModeSwitchEvent

模式切换事件

2.8、ScheduleTable

调度表的原理为时间到期后开始执行其内部注册的Task或Event。

总时间到期开始调用此调度表,通过偏移时间,调度具体的Task或Event,调度表可自行进行时间矫正,同时也区分绝对时间和相对时间。

从调度表的起点到初始到期点的距离被称为初始偏移(InitialOffset),相邻到期点间的距离被称为延迟(Delay),最后一个到期点到调度表终点的距离称之为最后延迟(FinalDelay)

调度表由一系列按时间先后顺序排序的到期点组成,其中每个到期点都有自己的任务。

有的到期点可能是激活一系列的任务,有的是设置一系列的事件,还有的可能是既激活一系列的任务,又设置一系列的事件。

假如tick是1ms,那么上面的调度表就是50ms要做的事情:

  • 4ms要激活TaskA和TaskB,并设置一些Event
  • 12ms不激活task,但是要设置Event
  • 20ms需要激活TaskA和TaskE
  • 32ms需要激活TaskA和TaskE,并设置Event
  • 40ms需要激活TaskB和TaskF,并设置Event

思考题:Alarm 和 ScheduleTable都可以触发任务被调度,那它们两者有什么区别?

2.9、SpinLock

(1)互斥锁:多线程访问同一个资源的时候,避免发生数据不一致的问题。访问一次锁,看资源是否被释放,如果资源没被释放,它退出cpu资源占用;如果资源已经被释放,它可以正常的读写该资源。

(2)自旋锁:多线程访问同一个资源的时候,避免发生数据不一致的问题。访问一次锁,看资源是否被释放,如果资源没被释放,它就while循环占用CPU资源一直等到资源被释放。(单核的情况下就会卡死!!

此种锁定数据区的方式比较强硬,通过设置寄存器锁,在此期间写数据时不允许被其他用户去更改此数据区,直达解锁后才可以再次写数据。

2.9.1、为啥需要用SpinLock

"多核"系统中,假设Core0和Core1同时访问共享参数Argu_Opt01(uint32),且两者均可对该参数进行改写,如下所示:

(1)t0时刻,Core0和Core1同时访问参数Argu_Opt01,且Core 0操作Argu_Opt01 = 0x55555555,Core 1操作Argu_Opt01 = 0x66666666;

(2)t1时刻,读取参数Argu_Opt01时,Argu_Opt01 = 0x55555555,还是Argu_Opt01 = 0x66666666?

可以看出,当多核操作同一个全局变量的时候,会存在数据一致性问题。所以,为了避免多核操作同一个全局变量,出现数据不一致问题,Spinlock机制出现了。

2.9.2、Spinlock机制

(1)既然,不同的Core同时访问同一个全局变量,会使得该全局变量一致性得不到保证,怎么办呢?

答:互斥访问。就是说,不同的Core在访问同一个全局变量的时候,要分先后顺序,“谁先访问,谁使用,先访问的Core,对该变量上锁,使用完再解锁,变量在被锁住期间,其他Core一直等待”。

这种处理机制,生活中,也有类似的场景。举个例子:飞机上,乘客甲先进入WC,乘客甲进入WC后,首先将WC上锁,乘客甲开始使用WC。在乘客甲使用WC的期间,如果有乘客乙要使用WC,乘客乙只能等待,等待乘客甲使用完WC后,乘客乙才能使用。

(2)那么在软件开发中,如何实现“等待”呢?

答:这个等待的过程可以用while()处理,Get/Release Spinlock代码示意如下所示:

Spinlock使用示例:

如上,某个Core需要访问某个全局变量(核间共享变量)的时候,先加锁,之后开始操作该变量,操作完成,释放锁。?

(3)如上述,Spinlock的机制适用于多核系统,那么同一个Core中,是否可以使用Spinlock呢

答:不能。为什么不能呢?如下图所示:

假设,Core0有两个Task:Task highTask low

t0时刻,Task low对锁A上锁;

t1时刻,由于Task high的优先级高,抢占Task low;

t2时刻,Task high尝试获取锁A,由于锁A被Task low占用,使得Task high一直while(),等待锁A的释放,最终导致死锁问题。此处,最终会因看门狗超时而导致程序异常(eg:Reset)。

(4)不同核,Spinlock使用注意事项

当某个Core在轮询lock状态的时候,可能会被更高优先级的Task/ISR抢占,干扰当前获取lock状态的任务。为了避免获取lock状态的任务被抢占,可以使用Os_SuspendAllInterrupts()接口,挂起中断

除了任务抢占需要注意以外,lock变量的使用顺序也需要提前定义,避免Core之间的互锁问题,如下所示:

t0时刻,Core0获取了lock A,Core1获取了lock B,之后各自执行任务;

t1时刻,Core0尝试获取lock B,Core1尝试获取lockA,由于Core0获取lock B时,Core1没有释放lock B,Core0需要等待。

同样的,由于Core1获取lock A时,Core0没有释放lock A,Core1也需要等待,这样就使得Core0和Core1均在while()中,无法跳出程序,造成互锁

因此,为了避免不同Core之间的互锁现象,一般,不建议Spinlock之间嵌套。如果Spinlock之间需要嵌套,则需要定义好Task/ISR使用Spinlock的顺序。

2.10、Ioc

跨核通信是通过在多核共享区建立缓存Buffer,Core0去Send然后Core1去Recive。当Buffer为数组形式时,则不需要Spinlock,通过循环队列方式去Send与Recive。非数组形式则需要Spinlock,保证数据写的时候不会被复写。

2.11、Resources

资源访问多用作Isr和Task中,作为提升Isr和Task的优先级,将其优先级提升至最高,不会被其他Isr和Task打断。

Resource不属于任何OS Application,在配置工具中的选择仅代表OS Application是否有权限访问。(Spinlock同理)

3、多核系统的启动过程(更多时序图,参见:EcuM Autosar文档)

多核的启动和硬件紧密相关,通常情况下,硬件会启动一个核作为主核(Master Core),而从核(Slave Core)由软件启动,这种模式称为主从模式(Master-Slave Startup Behavior)。启动过程如下图所示:??

系统启动流程:?

(1)当uC供电以后,程序从复位向量入口开始执行(Reset Vector),具体的起始地址可以在链接文件中查看,提示:此地址属于自定义的用户地址,一般是Boot程序地址;?

(2)程序在Boot中,会判断App的有效性,如果App有效,程序跳转到App的Main函数处(上图中的C init Code);

(3)在App的main函数中,会调用EcuM_Init()接口,EcuM开始接管ECU的StartUp流程。在StartPreOS的时序中,调用StartOS()接口,Os从EcuM临时拿过程序的控制权,之后,Os通过ActivateTask()激活任务。在BswM Task中,通过EcuM_StartupTwo()接口将程序的控制权再交还给EcuM,之后,进一步地执行StartPost Os时序。

代码示例:

4、多核系统的关闭过程(更多时序图,参见:EcuM Autosar文档)

一个任务拥有调用Shutdown All Cores的权限时,关闭信号会被发送至所有核。

当关闭过程启动后,所有的中断服务和任务都不会被激活,关闭前必须完成的程序由EcuM保证完成。

关闭完成前,由OS Application Shutdown Hooks完成相应的回调程序,然后等待至同步点所有核主席那个关闭回调函数。?

系统下电流程:

?

文章来源:https://blog.csdn.net/rwlsh/article/details/134962963
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。