AUTOSAR OS模块详解中断ISR

admin 2025年5月18日23:13:17评论2 views字数 10251阅读34分10秒阅读模式

点击上方蓝字谈思实验室

获取更多汽车网络安全资讯

AUTOSAR OS模块详解中断ISR

01

模块介绍

对于嵌入式系统来说,实时性是一个非常重要的特性,相比较于桌面端系统,嵌入式系统往往部署在各种硬件设备上,这些硬件设备的控制往往都要求毫秒甚至微秒级的反馈。而在车规级控制器中,有些硬件功能的实时性要求就更为严苛。

本文就从纯软件的角度,解析Autosar Os中的中断定义及处理逻辑。

02

功能介绍

2.1 中断分类

在Autosar Os中,中断分为两类,就叫做一类中断和二类中断。其中一类中断的执行不经过Os的调度管理,中断发生后直接到达中断业务逻辑,对于Os来说是无感的,而二类中断则是需要Os进行调度管理的,有专门的程序控制块。除此之外,二者还具有以下区别:

  • 一类中断的优先级恒高于二类优先级(配置强限制);

  • 临界区层级不同,例如SuspendOsInterrupt只关闭Os中断而不关闭一类中断,SuspendAllInterrupt则关闭所有中断;

  • 因为一类中断不被Os管理,因此一类中断的处理过程中不需要切换线程和保存上下文;

一般情况下,对于外设等的中断,如DMA、SPI、PWM等与OS并非直接关联的,建议设置为一类中断,省去了Os调度的消耗;而对于CAN、Eth等与协议栈MainFunction等关联性较强的中断,甚至需要Os资源提供数据保护的,建议使用二类中断。

2.2 中断源

在Vector DaVinci工具中配置中断,要区别于在EB中配置中断,在EB中每个模块都详细列出来,而在DaVinci工具中,还需要配置一个中断源,顾名思义,该中断源用于指定该中断连接到哪个硬件中断信号上。中断源填写的是所使用中断的SRC寄存器偏移地址,具体需要查询芯片用户手册,下面我们以CAN中断为例介绍如何查询。

我们这里配置使用CAN0INT0,关于CAN中断及其连接,读者可以翻阅本公众号发布的CAN模块的介绍,此处不进行赘述。

我们来到所使用芯片的UserMannual中,注意是系列手册,不是family手册,这里我的芯片是TC387,使用的TC38x-UserManual。打开16.4 IR章节中的TC38x Specific Service Request Control (SRC) registers。

这里我们可以看到两个表,一个是Table 262 Register Address Space - SRC,里面说明了SRC寄存器地址范围,另一个是Table 263 Register Overview - SRC (ascending Offset Address),里面说明了所有该芯片各个中断的SRC寄存器偏移地址,也就是我们需要查阅的目标。

AUTOSAR OS模块详解中断ISR

我们在第二个表中搜索CAN可以找到如下条目:

AUTOSAR OS模块详解中断ISR

我们需要查找的是CAN0INT0,这里将x、y代入得出偏移地址为0x5B0,即1456,后续我们在中断源配置中需要填入该值。

另外值得一提的是Os Counter的中断源是不需要我们填的,我们在Counter配置中选定了硬件定时器后工具会自动进行配置。

2.3 中断配置

OS配置这里我们选择Os Counter作为示例进行演示,虽然该中断有些配置项是OS自动配置的,但是配置项和其他我们添加的配置也是一样的。

AUTOSAR OS模块详解中断ISR

OsIsrShortName

中断的ShortName和其他元素的不太一样,我们自行添加的中断没有Special Function Name那项配置的话,Os会使用ISR这个宏对ShortName进行展开,进行中断入口函数的声明,如ISR(CanIsr_0)展开成Os_Isr_CanIsr_0。

OsIsrCategory

中断类型,一类还是二类。一类的话无法由OS控制,所以下面的中断嵌套和中断使能都无法勾选。另外如果我们要配置Trap向量表(Vector OS支持用户配置部分Trap,这个我们以后在Os异常处理中介绍),这里不能选为二类。

OsIsrEnableNesting

是否可以嵌套,如果可以嵌套,则该中断可以被高优先级中断打断。

OsIsrInitialEnableInterruptSource

是否由OS使能该中断,一般默认选择开启,OS会在初始化后使能该中断,无需用户手动操作。一类中断此处无法配置,所以一类的初始化和使能需要用户在初始化中实现。

OsIsrInterruptMapping

中断映射,我们知道TC3XX系列芯片可以将中断路由到DMA中,这里可以选择DMA进行路由。

OsIsrInterruptPriority

中断优先级,与硬件相关,这里即TC3XX的中断优先级,数字越大优先级越高,中断入口代码在向量表中按优先级排布。

OsIsrInterruptSource

中断源,即前文提到的硬件中断关联,Os Counter的中断源是根据用户选的定时器自动计算的。这里为了演示配置方法,我们查询手册,我选的定时器是STM0(默认Compare0中断),其中断源在手册中为0x300,即上述配置中的768。

AUTOSAR OS模块详解中断ISR

OsIsrInterruptType

中断类型,这里配置为EXTERNAL即可,如果是配置Trap的话,则要配置为EXCEPTION。

OsIsrMemoryProtectionIdentifier

内存保护的识别号,Task和Isr的内存保护我们一般不单独配置,因为芯片没有那么多的Set足够每个Task或者Isr单独配置,一般是继承Application的识别号。

OsIsrSpecialFunctionName

指定的中断函数,因为Counter的中断函数是Vector内置的,所以这里强行配置了Os_TimerPfrtIsr,这个函数我们在Counter章节中也介绍过。

OsIsrStackSize

二类中断栈大小,一般情况下1024就够用了,甚至偏多,除非是用户手写代码。一类中断不由OS管理,这里配置了也没用。需要注意的是一类中断在进入时直接使用当前线程的栈,如果使用较多则需要注意。

OsIsrUsesFpu

是否使用浮点运算单元,在ARM等芯片中,FPU这类协处理器是具有独立的寄存器的,因此Task/Isr切换的过程中,是需要保存FPU上下文的。TriCore内核芯片FPU没有单独的上下文,这里不使能即可。

Cross-core channel receiver interrupt

多核通道接收中断,Vector中利用TC3XX的软中断,实现X-Signal跨核通信,对应的中断这里需要配置使能。

Timing Protection Enabled

是否使用时间保护,在SC2和SC4中,该配置可以用于中断时间监控。

2.4 中断向量表

在TC3XX中断文章中,我们介绍过,该系列芯片的中断向量表是一段指定的连续Flash地址,按照优先级进行中断入口函数的排布。

AUTOSAR OS模块详解中断ISR

在Vector代码中,该向量表由OS维护,统一进行中断入口的管理,包括一类中断。

在Os_Hal_Entry_Lcfg.c中我们可以看到该向量表,是以Memmap包裹的特殊宏定义。

Memmap的功能是将该段代码以OS_INTVEC_CORE0_CODE的section装载到指定内存中,并且中断向量表基址寄存器的初始化也会使用该代码段的地址标签。

每个中断优先级都以32字节对齐分配了一定的空间,用来存放中断入口,进行中断函数跳转。未配置的中断则使用Os_Hal_UnhandledInterruptEntry展开,用于异常触发时的处理。

#define OS_START_SEC_INTVEC_CORE0_CODE#include"Os_MemMap_OsSections.h"Os_Hal_InterruptSectionDeclaration(0)Os_Hal_UnhandledInterruptEntry(00)...Os_Hal_Cat2InterruptEntry(080, OS_CFG_HAL_ISR2_DISABLE_LEVEL, OsCfg_Isr_CounterIsr_SystemTimer)...Os_Hal_Cat2InterruptEntry(085, OS_CFG_HAL_ISR2_DISABLE_LEVEL, OsCfg_Isr_CanIsr_0)...#define OS_STOP_SEC_INTVEC_CORE0_CODE#include"Os_MemMap_OsSections.h"

在使用Tasking编译器时,一类中断宏按照如下形式展开,我们可以看到其仅仅声明了一个函数名,保存低上下文供中断使用,然后根据用户配置的中断函数进行跳转,并未做其他处理,所以我们说一类中断不经过OS管理。

define Os_Hal_Cat1InterruptEntry(core, level, function)   __asm ("  .SECT   ".text.OS_INTVEC_CORE"#core"_CODE"");   __asm ("  .ALIGN 32");   __asm ("  .EXTERN " #function);   __asm ("  .GLOBAL osIsrLevel_" #level "_Core" #core);   __asm ("osIsrLevel_" #level "_Core" #core": svlcx");   __asm ("  call " #function);  __asm ("  rslcx");  __asm ("  rfe");

二类中断的宏展开内容多了一些,仍然声明一个向量表函数名,然后这里extern了一个全局变量,是中断的配置结构体,作为入参传递到Os的二类中断处理函数中,比如CAN中断这里传入的就是前面的OsCfg_Isr_CanIsr_0。

所有的二类中断都要进入Os_Hal_IsrRun函数,在该函数中进行上下文切换,线程处理,然后才能进入实际中断执行代码。所以说二类中断是由OS进行管理的。

# define Os_Hal_Cat2InterruptEntry(core, level, systemlevel, isrconfig)   __asm ("  .SECT   ".text.OS_INTVEC_CORE"#core"_CODE"");   __asm ("  .ALIGN 32");   __asm ("  .EXTERN " #isrconfig);   __asm ("  .EXTERN Os_Hal_IsrRun");   __asm ("  .GLOBAL osIsrLevel_" #level "_Core" #core);   __asm ("osIsrLevel_" #level "_Core" #core": svlcx");   __asm ("  movh.a  a4, #@his("#isrconfig")");   __asm ("  lea  a4, [a4]@los("#isrconfig")");   __asm ("  call Os_Hal_IsrRun");   __asm ("  rslcx");   __asm ("  rfe");

2.5 代码分析

2.5.1 主要数据结构

中断Isr的主要数据结构为Os_IsrConfigType,我们到Os_Isr_Lcfg.c文件中可以找到该数据,Isr对应的变量名为 OsCfg_Isr_前缀加上中断Isr的配置名称。

另外如果是Os Counter中断,会特殊一点,类型为Os_TimerIsrConfigType,其中包含一个Os_IsrConfigType和一个Os_CounterConfigType的指针。这里就以Timer中断为例。

CONST(Os_TimerIsrConfigType, OS_CONST) OsCfg_Isr_CounterIsr_SystemTimer ={  /* .Isr     = */  {    /* .Thread   = */    {      /* .ContextConfig         = */ &OsCfg_Hal_Context_CounterIsr_SystemTimer,      /* .Context               = */ &OsCfg_Hal_Context_OsCore0_Isr_Level5_Dyn,      /* .Stack                 = */ &OsCfg_Stack_OsCore0_Isr_Core,      /* .Dyn                   = */ OS_ISR_CASTDYN_ISR_2_THREAD(OsCfg_Isr_CounterIsr_SystemTimer_Dyn),      /* .OwnerApplication      = */ &OsCfg_App_SystemApplication_OsCore0,      /* .Core                  = */ &OsCfg_Core_OsCore0,      /* .IntApiState           = */ &OsCfg_Core_OsCore0_Dyn.IntApiState,      /* .TimeProtConfig        = */ NULL_PTR,      /* .MpAccessRightsInitial = */ &OsCfg_Mp_CounterIsr_SystemTimer,      /* .AccessRights          = */ &OsCfg_AccessCheck_NoAccess,      /* .Trace                 = */ NULL_PTR,      /* .FpuContext            = */ NULL_PTR,      /* .InitialCallContext    = */ OS_CALLCONTEXT_ISR2,      /* .PreThreadHook         = */ NULL_PTR,      /* .InitDuringStartUp     = */ FALSE,      /* .UsesFpu               = */ FALSE    },    /* .SourceConfig              = */ &OsCfg_Isr_CounterIsr_SystemTimer_HwConfig,    /* .IsrId                     = */ CounterIsr_SystemTimer,    /* .IsEnabledOnInitialization = */ FALSE  }  ,  /* .Counter = */ OS_COUNTER_CASTCONFIG_TIMERPFRT_2_COUNTER(OsCfg_Counter_SystemTimer)};

该结构体是该Isr的句柄,相当于线程控制块。其中ContextConfig指向的结构体为OsCfg_Hal_Context_CounterIsr_SystemTimer,包含了栈信息等,其中Entry是该Isr的入口函数,ReturnAddress是中断调用栈的栈底Os_TrapIsrEpilogue,中断执行完毕之后在这里切回原有线程。

CONST(Os_Hal_ContextConfigType, OS_CONST) OsCfg_Hal_Context_CounterIsr_SystemTimer ={  /* .StackEndAddr     = */ (uint32)(OS_STACK_GETHIGHADDRESS(OsCfg_Stack_OsCore0_Isr_Core_Dyn)+1),  /* .StackStartAddr   = */ (uint32)OS_STACK_GETLOWADDRESS(OsCfg_Stack_OsCore0_Isr_Core_Dyn),  /* .ProgramStatus    = */ (uint32)OS_HAL_PSW_IS_MASK | OS_HAL_PSW_CDE_MASK | OS_HAL_PSW_IO_SUPERVISOR | OS_HAL_PSW_S_MASK | OS_HAL_PSW_PRS_PS0,  /* .Entry            = */ (uint32)&Os_Isr_Os_TimerPfrtIsr,  /* .ReturnAddress    = */ (uint32)&Os_TrapIsrEpilogue,  /* .IntStatus        = */ ((uint32)130<<OS_HAL_PCXI_PCPN_BIT_POSITION) | OS_HAL_PCXI_PIE_ENABLED};

Context所指向的OsCfg_Hal_Context_OsCore0_Isr_Level5_Dyn为该Isr的上下文信息,包括返回地址、CSA等信息,如下图所示。

AUTOSAR OS模块详解中断ISR

Dyn所指向结构体指示了该Isr的各种动态状态量,包括运行状态,运行时优先级等。在实际调试过程中可用于观察该中断状态。

 2.5.2 中断Isr初始化阶段

关于Os的初始化,在本系列Counter章节中已经介绍过,这里就不赘述了,与Counter、Task等相同,Isr的初始化也是在Os_AppInit中进行的,其调用栈如下图所示。

AUTOSAR OS模块详解中断ISR

中断的初始化相对于Task要简单,只有一个线程的初始化。

2.5.3 中断使能

中断在完成初始化之后,仅仅是配置了中断状态相关的寄存器此时中断还不能够运行,还需要使能中断。

一类中断的使能是需要用户手动操作的,推荐在EcuM_AL_SetProgrammableInterrupts函数中执行。

对于Os Counter的中断,之前的文章已经介绍过了,会在Timer的初始化中启动Os Tick所使用的中断。

而对于普通的二类中断,则是在Default_Init_Task_Trusted任务中进行使能的(前提是勾选了OsIsrInitialEnableInterruptSource),该任务是Os的内置任务,用户不可配置其中的Rbl,优先级也是建议配置为最高,启动Os之后优先执行。

在该任务中调用Os_InitialEnableInterruptSources函数,随后一路调用到Os_Hal_IntEnableSource函数中,在其中写入中断的SRC寄存器中SRE位域,使能该中断。

2.5.4 中断执行

一类中断的执行不经过Os进行处理,因此一类中断在经过中断向量表之后,直接跳转到其中断执行函数,此处不进行赘述。

对于二类中断,这里以Counter中断CounterIsr_SystemTimer为例,我们将断点打到中断向量表中。

AUTOSAR OS模块详解中断ISR

可以看到该段汇编首先保存了低上下文,以供中断函数使用,然后将0x800255f4作为指针入参传递该Os_Hal_IsrRun函数中,我们在Map里搜索该地址发现它就是前文提到的OsCfg_Isr_CounterIsr_SystemTimer,也就是该中断的句柄。

AUTOSAR OS模块详解中断ISR

然后我们从Os_Hal_IsrRun将其调用时序图画出。

AUTOSAR OS模块详解中断ISR

在进入Os_Hal_IsrRun之后,会直接调用Os_IsrRun,然后进入Os的中断处理函数。所有的二类中断都会经过这个函数,在这里进行线程的切换以及上下文的处理。

首先会通过Os_IntSuspend关闭中断(虽然硬件在进入中断时已经关闭,但对于Os需要保证自身完整性),如果使能了0类中断,接下来会重新打开,以保证0类中断能够进入。

然后使用Os_CoreInterruptedThreadsPush记录中断嵌套次数。

接下来就是通过Os_ThreadSuspendAndStart进行线程的上下文处理了。

{  Os_StackOverflowCheck();  /* #15 Store FPU context if needed */  Os_ThreadStoreFpuContext(Current);                                                                      /* #20 Resume memory protection access rights of Next. */  Os_MpSwitch(Current->Dyn->MpAccessRightsNext->Dyn->MpAccessRights);                                   /* #25 Switch current thread pointer. */  Os_CoreSetThread(Next);                                                                                 /* #30 Call PreThreadHook. */  Os_ThreadCallPreThreadHook(NextCallPreThreadHook);                                                    /* #40 Set the current stack pointer. */  Os_CoreSetCurrentStack(Next->StackNext->Core);                                                        /* #50 Prepare context of next thread. */  Os_Hal_ContextInit(Next->ContextConfigNext->Context);                                                 /* #60 Setup FPU for next thread. */  Os_ThreadInitFpu(Next);                                                                                 /* #70 Set parameter for the entry function, currently only used for hooks (hook thread pointer). */  Os_Hal_ContextSetParameter(Next->ContextNext);                                                        /* #80 Update the Msr of the next thread. */  Os_Hal_ContextSetUserMsrBits(Next->Context);                                                            /* #90 Perform context switch. */  Os_Hal_ContextCallOnStack(Current->ContextNext->Context);                                             /* #100 Restore FPU context if needed */  Os_ThreadRestoreFpuContext(Current);                                                                  }                                                                                                       

在这里首先进行当前线程的栈检查,然后保存FPU上下文(如果需要),切换内存保护集,设置线程全局指针等上下文操作,然后在Os_Hal_ContextCallOnStack中进行上下文切换,切换到目标中断线程中。

在Os_Hal_ContextCallOnStack中首先将当前线程的上下文信息进行保存,如PCXI、返回地址等,在Os_Hal_ContextIntRestore中加载中断线程的内容然后完成切换动作,然后我们就来到了实际要处理的中断函数Os_TimerPfrtIsr中。

AUTOSAR OS模块详解中断ISR

到这里Os真正开始处理对应的二类中断函数,也就是用户定义的业务代码。

当中断函数执行完毕之后,返回线程入口地址Os_TrapIsrEpilogue,然后调用Os_IsrEpilogue函数,在其中返回被打断的Task,或者返回被打断的其他中断,这样就切出了该中断线程,至此,该中断处理完成。

03

小结

本文介绍了Autosar Os中的中断Isr定义及其实现,就其类型及工具配置展开了介绍。通过对Vector Os实现机制进行了代码解析,详细介绍了中断Isr的处理过程。

 end 

AUTOSAR OS模块详解中断ISR

 精品活动推荐 

AUTOSAR OS模块详解中断ISR
AUTOSAR OS模块详解中断ISR

 AutoSec中国行系列沙龙 

AUTOSAR OS模块详解中断ISR

AUTOSAR OS模块详解中断ISR

 专业社群 

AUTOSAR OS模块详解中断ISR

部分入群专家来自:

新势力车企:

特斯拉、合众新能源-哪吒、理想、极氪、小米、宾理汽车、极越、零跑汽车、阿维塔汽车、智己汽车、小鹏、岚图汽车、蔚来汽车、吉祥汽车、赛力斯......

外资传统主流车企代表:

大众中国、大众酷翼、奥迪汽车、宝马、福特、戴姆勒-奔驰、通用、保时捷、沃尔沃、现代汽车、日产汽车、捷豹路虎、斯堪尼亚......

内资传统主流车企:

吉利汽车、上汽乘用车、长城汽车、上汽大众、长安汽车、北京汽车、东风汽车、广汽、比亚迪、一汽集团、一汽解放、东风商用、上汽商用......

全球领先一级供应商:

博世、大陆集团、联合汽车电子、安波福、采埃孚、科世达、舍弗勒、霍尼韦尔、大疆、日立、哈曼、华为、百度、联想、联发科、普瑞均胜、德赛西威、蜂巢转向、均联智行、武汉光庭、星纪魅族、中车集团、赢彻科技、潍柴集团、地平线、紫光同芯、字节跳动、......

二级供应商(500+以上):

Upstream、ETAS、Synopsys、NXP、TUV、上海软件中心、Deloitte、中科数测固源科技、奇安信、为辰信安、云驰未来、信大捷安、信长城、泽鹿安全、纽创信安、复旦微电子、天融信、奇虎360、中汽中心、中国汽研、上海汽检、软安科技、浙江大学......

人员占比

AUTOSAR OS模块详解中断ISR

公司类型占比

AUTOSAR OS模块详解中断ISR

原文始发于微信公众号(谈思实验室):AUTOSAR OS模块详解--中断ISR

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月18日23:13:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   AUTOSAR OS模块详解中断ISRhttp://cn-sec.com/archives/4078024.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息