
TC3xx芯片的Trap详解
前言
前面介绍了TC3xx一系列的功能与特性,看起来感觉高大上,但是总有一种空中楼阁的感觉:这些复杂的架构、特性、功能在平时好像也用不到呀?今天就来介绍和日常开发及问题分析强相关的TC3xx芯片的Trap功能,也就是在程序/系统异常后,TC3xx的异常处理机制。同时回答以下两个关键问题:
1.发生Trap后,怎么确定发生了哪一个Trap?
2.是程序的哪个地方导致发生了Trap?
注意:本文使用TC3xx芯片及Vector的AUTOSAR配置工具。
参考文档:
1.Infineon-AURIX_TC3xx_Part1-UserManual-v02_00-EN
2.学习笔记 | Aurix TC3xx Architecture
缩略词
简写 | 全称 |
TCN | Trap Class Number |
TIN | Trap Identification Number |
TSR | Trap Service Router |
NMI | Non-Maskable Interrupt |
BTV | Base Trap Vector Table Pointer |
正文
1.Trap发生
当系统中发生不可屏蔽中断(NMI)、指令异常(Instruction exception)、内存管理异常(Memory management exception)或者非法访问(Illegal access)时,Trap就会发生。Trap功能永远是Active的,不可被Disable的。
2.Trap类型
TC3xx有8种类型的Trap(Class 0 – Class 7),通过TCN标识,每类Trap下又定义了一系列的具体Trap,通过TIN(Trap Identification Number标识)。
也就是说,异常(exception)发生后,我们能知道具体的TCN和TIN,就能确定是哪一种Trap发生了。
3.Trap向量表
TC3xx的BTV寄存器保存了异常向量表的基地址。BTV寄存器中保存的异常向量表的基地址的[8:5]位域”或 or”上TCN码就能确定异常发生时调用的具体的TSR(Trap service router,或者叫异常处理程序)所在的地址。
4.Trap定位
定位Trap类型
从上文中得知,我们能知道具体的TCN和TIN,就能确定是哪一种Trap发生了。
D[15]寄存器保存了Trap/Exception发生后TIN号。
在DataSheet中没有知道如何确定TCN号,从后面的调试分析中可以得知,异常发生后,D[4] = (TCN << 16) | TIN,也就是可以通过D[4]寄存器确定TCN号。
定位发生Trap的位置:
A[11]寄存器保留了函数的返回地址,可以通过A[11]来推测异常发生的函数。
5.AUTOSAR架构图下Trap实例分析
异常测试代码
uint8 TrapTestFlag = 0;
uint32* ZeroAdress = (uint32 *)0x00000000;
static void TrapTest(void)
{
/* Trap for Memory Protection Null Address*/
if(1 == TrapTestFlag)
{
TrapTestFlag = 0;
*ZeroAdress = 0x12345678;
}
}
给零地址处赋值制造异常。
TrapTest函数发生异常,触发异常处理程序TSR。
Os_Hal_MemoryTrapEntry是本次异常发生时的TSR,通过汇编代码又调用了Os_Hal_MemFaultExceptionHandler
从Os_Hal_MemoryTrapEntry代码及注释中可以知道,异常的时候D[15]寄存器保存了TIN,D[4]寄存器保存了TCN << 16 | TIN
在异常处理程序处打断点:
D[15]: 6,也就是TIN为6
D[4]: 0x00010006,也就是TCN为1
A[11]: 0x8013CB18,也就是如果没有异常,函数返回地址是0x8013CB18
BTV: 0x70102000
分析1:通过D[15]和D[4]确定TIN和TCN后确定异常为零地址访问异常
分析2:通过A[11]为0x8013CB18后查看Map文件,确定0x8013CB18为TrapTest函数的返回地址
分析3:BTV | (TCN << 5) à 0x70102020为本次TSR(异常处理函数)的地址
分析4:我们也可以查看OS的报错
Error Type为14 ,也就是0x0E,为E_OS_PROTECTION_MEMORY
6. 实际应用思路
如果是必现问他,通过lauterbach仿真器很容易就能定位到异常原因和位置,但是,如果是实车上偶发出现异常,无法通过仿真器仿真又该怎么办了?
这里仅提供一个设计思路,更具体是详细设计和代码实现请关注本公众号的后续文章。
思路:
1.MCU预留Backup Ram(软件复位后数据不丢失RAM)
2.配置OS,使得Os shutdown后能够调用到自定义的Callout函数
3. Callout函数中将异常复位的Trap信息(TCN,TIN,Return Adress等)保存到Backup Ram
4. Callout最后调用Mcu_PerformReset软件复位
5. 复位后能识别到上一次的异常信息,并把异常信息写道NVM中去
6.通过诊断DID能够读取到异常信息
这样在实车上发生异常后,就能通过诊断读取到异常信息,从而便于分析和定位问题。
7.总结
. TC3xx有8类TCN, 每类TCN下又有具体的TIN
. 异常发生的时候,可以通过D[4]和D[15]寄存器定位具体的异常类型
.异常发生的时候,可以通过A[11]寄存器定位异常发生的位置
文章转载自公众号:汽车电子嵌入式
