IR模块
在ARM架构中,中断向量表中存放了每个中断服务函数,当中断信号出现时,由中断向量控制器接受该信号,然后进入统一的中断枢纽例程中,在中断枢纽例程中查询向量表,然后跳转到对应的中断服务函数中执行。
对于TC23x而言,其中断的响应路线比较相似,不同的是TC23x中没有中断枢纽例程,CPU接受中断信号后直接跳转到中断向量表,在中断向量表中每个中断最多有32字节的代码空间。一般是在向量表中存档跳转指令,跳转到实际的中断服务函数中。
1 IR介绍
整个系统包含中断源(软件或硬件)、中断路由器IR和服务提供者(CPU或DMA)。在这里中断请求称为服务请求,因为既可以触发一个CPU中断,也可能是触发一个DMA转换。
当外部中断源如ADC等模块产生了服务请求信号,会发送给IR,IR根据配置的优先级进行仲裁,将高优先级的服务请求路由给对应的服务提供者。
IR模块主要包括服务请求节点(SRN)、中断控制单元(ICU)以及服务提供者。
每个可以生成服务请求的TC23x模块都连接到中央中断路由器模块中的一个或多个服务请求节点(SRN)。中断路由器模块还包含多个通用服务请求节点(SRN),这些节点可用于软件(SW)触发的服务请求。
每个 SRN 包含一个服务请求控制寄存器(SRC),用于配置服务请求,例如设置优先级、映射到可用的服务提供者之一。
每个 SRN 都与中断路由器模块中的所有 ICU 相连,其中 SRN 的控制寄存器设置定义了目标服务提供者和服务请求的优先级。
每个 ICU 负责处理映射到该 ICU 的 SRN 之间的服务请求中断仲裁。
每个 ICU 连接到一个服务提供者(CPU 或 DMA 模块),其中 ICU 提供仲裁轮次中的有效获胜服务请求SRN,服务提供者在处理何时以及哪个服务请求时向 ICU 发出信号。
1.1 服务请求节点(SRN)
每个SRN对应一个硬件的服务请求。每个SRN都有一个服务请求控制寄存器(SRC),可以设置具体的中断优先级、使能、状态查询等
1.2 中断控制单元(ICU)
每个SRN的服务请求会路由到一个ICU中,一个ICU连接一个CPU或者DMA,每个ICU内部进行服务请求的仲裁,并将仲裁的结果发送到连接的服务提供者。ICU中一般不需要配置,与CPU和DMA的连接相对比较固定。我们可以通过查询ICU的寄存器查看仲裁或路由情况,包括LWSR、LASR等,这些寄存器一般是只读的,不需要用户配置,这里就不展开介绍了。
最新获胜服务请求寄存器(LWSR)提供有关最后一次服务请求仲裁轮获胜者的信息
最后确认服务请求寄存器(LASR)提供有关最后被服务提供商接受的服务请求的信息
1.3 中断服务提供者(CPU)
当服务请求被路由到CPU的时候,CPU会接收IR的信号并作应答,然后执行对应的服务例程,也就是我们常说的中断。接下来我们从CPU的角度介绍中断的处理流程。在此之前,我们先介绍两个重要的寄存器,中断向量表基址指针(BIV)和ICU中断控制寄存器(ICR)。这里需要注意的是,这两个寄存器属于CPU寄存器,在多核系统中,每个核都有一套自己的CPU寄存器,所以会存在CPU0_ICR,CPU1_ICR,而前文提到的IR模块寄存器属于外设寄存器,一个系统里只有一套。CPU寄存器不能直接读写,要通过ENABLE、DISABLE、MTCR、MFCR等内核指令访问。
中断向量表基址指针(BIV),包括中断向量表基址BIV和向量空间选择位VSS。
中断向量表基址BIV,TC23x的中断向量表是存放在Flash中的连续地址,因此需要该寄存器来表示向量表基地址。
向量空间选择位VSS,该位表征每个中断向量所占的内存空间,0表示每个中断向量占据32字节,1表示8字节,默认为32字节
ICU中断控制寄存器(ICR),其中包括全局中断使能位IE,当前CPU中断优先级位CCPN和等待中断优先级位PIPN
IE,我们所使用的关闭所有中断操作,就是将该位置0,因为每个CPU是独立的,也有自己的ICR控制器,所以IE只控制当前核的中断开关;
CCPN,在非中断程序执行时,该位为0,进入中断时,该位会被硬件设置为所触发中断的优先级;
PIPN,表征当前CPU收到IR路由但还未处理的中断优先级;
1.4 中断服务提供者(DMA)
除了CPU接收IR的服务请求信号执行中断响应程序以外,TC23x的中断系统还有一个亮点,那就是将服务请求信号路由到DMA中,硬件触发一次DMA转换。这种连接,我们只需要将SRC.TOS设置为DMA,然后将SRC.SRPN设置为目标DMA通道号,即可实现路由。
SRPN的数值越高,优先级越高。即通道0的优先级最低。
2 CPU中断处理流程
当所有条件满足,CPU就要开始响应中断了,下面我们将介绍CPU对于中断的响应和退出流程。
在CPU决定响应中断时,并不是直接去按向量表执行其中断服务例程,而是先由硬件执行一系列操作进行上下文保存,也就是保护现场,而在退出中断之后也需要加载上下文,也就是恢复现场。下面我们先详细介绍CPU对于中断的硬件响应步骤:
(1)保存上下文
(2)切换系统模式
(3)切换中断环境
3 EB工程搭建(ADC采样)
3.1 配置Adc
参考【AUTOSAR实战系列】(8):MCAL之ADC模块原理与EB配置
注意:如下图所示,配置Adc组的请求源AdcGroupRequestSource,用于软件触发、中断触发等,提供四种选择,中断的时候就对应其中一个SRC。
3.2 配置Irq
(1)Irq
各个模块都有对应的配置选项卡,当使用了OSEK OS时,需要打开该选项
(2)IrqAdcConfig
前面配置Adc时,配置的是ADC0,组0选择的请求源是SRC0,所以这里对应的是ADC0的SR0。
4 Tasking工程搭建
4.1 导入库文件和EB生产的配置文件
这里Irq库文件中只保留用到的模块的文件,删除没用到的。EB只会生成Irq配置的头文件。
4.2 添加导入文件的路径在Include Paths项目下
"\${workspace_loc:/\${ProjName}/Aurix_MC-ISAR/irq_infineon_tricore}" "\${workspace_loc:/\${ProjName}/Aurix_MC-ISAR/irq_infineon_tricore/ssc}" "\${workspace_loc:/\${ProjName}/Aurix_MC-ISAR/irq_infineon_tricore/ssc/inc}" "\${workspace_loc:/\${ProjName}/Aurix_MC-ISAR/irq_infineon_tricore/ssc/src}"5 API接口
| API接口 | 解释 |
|---|---|
| IrqXxx_Init | 初始化Xxx模块的中断 |
6 Demo示例
intmain(void){Std_ReturnType RetVal;Adc_ValueGroupType AdcResultBuffer[16];// 定义数组volatileIcu_17_GtmCcu6_InputStateType State;Icu_17_GtmCcu6_DutyCycleType Duty;volatileuint32 Pwm_PeriodTime;volatilefloatPwm_Duty;Mcu_Init(&Mcu_ConfigRoot[0]);// 初始化McuRetVal=Mcu_InitClock(0);if(RetVal==E_OK){while((Mcu_GetPllStatus())==0){}Mcu_DistributePllClock();}Port_Init(&Port_ConfigRoot[0]);// 初始化PortDio_Init(&Dio_ConfigRoot[0]);// 初始化DioIcu_17_GtmCcu6_Init(&Icu_ConfigRoot[0U]);// 初始化IcuIcu_17_GtmCcu6_StartSignalMeasurement(0);// 开始测量,EB中配置的是监测P33.4IO口Gtm_EnableTomChannel(1,12);//一路PWM输出Adc_Init(&Adc_ConfigRoot[0]);// ADC初始化Adc_SetupResultBuffer(AdcConf_AdcGroup_AdcGroup_0,AdcResultBuffer);// 设置Group0数据保存位置IrqAdc_Init();// Adc中断初始化while(1){State=Icu_17_GtmCcu6_GetInputState(0);// 返回测量信号状态if(State==ICU_ACTIVE){State=ICU_IDLE;Dio_WriteChannel(DioConf_DioChannel_LED1,STD_ON);Icu_17_GtmCcu6_GetDutyCycleValues(0,&Duty);// 获取测量到的信号属性Pwm_PeriodTime=100000000/Duty.PeriodTime;Pwm_Duty=(float)Duty.ActiveTime/(float)Duty.PeriodTime;}// 软件触发Group转换Adc_StartGroupConversion(AdcConf_AdcGroup_AdcGroup_0);}}7 测试
MCU:TC234
调试器:Lauterbach
调试软件:TRACE32 ICD TriCore USB
7.1 非同步转换
劳德巴赫中监测变量值如下:
7.2 同步转换
劳德巴赫中监测变量值如下: