TriCore架构学习笔记(一):架构总览

汽车嵌入式开发中,需要不断地拓宽自己的知识结构,才能更有效地理解Bug的本质,进而想出更好的解决策略。如果大家项目中,使用的是英飞凌系列芯片,熟悉TriCore架构是有必要的,这有助于你理解链接文件启动代码的一些操作。本文分享一下自己对TriCore架构的一些理解。

1 TriCore架构寄存器

了解TriCore架构,我们首先得知道TriCore架构会用到哪些寄存器,TriCore架构寄存器包括:16个通用的地址寄存器A[0] ~ A[15],16个通用的数据寄存器D[0]~D[15],1个PC(Program Counter)寄存器,1个程序状态字寄存器PSW(Program Status Word),1个上下文信息寄存器PCXI( Previous Context Information register)。除了这些,还有Core Special Function Registers (CSFRs),这里不一一展开。上述寄存器均是32 Bit寄存器,TriCore架构寄存器如下所示:
在这里插入图片描述
通用寄存器中,编号0~7对应的[地址寄存器|数据寄存器]称为低位寄存器(Lower Registers),编号8~15对应的[地址寄存器|数据寄存器]称为高位寄存器(Upper Registers)。
PSW、PCXI不仅记录着程序运行的状态信息,而且与PC寄存器一样,是程序切换过程中,存储(Save)和恢复(Restore)上下文的重要组成部分
A[10]、A[11]、A[15]、D[15]这4个通用寄存器还有特殊功能:

  • A[10]:栈指针寄存器Stack Pointer (SP) register

  • A[11]:返回地址寄存器Return Address (RA) register

  • A[15]:隐式基地址寄存器Implicit Address register

  • D[15]:隐式数据寄存器Implicit Data register

A[0]、A[1]、A[8]、A[9]是系统全局寄存器,也就是说在函数调用、中断发生过程中,上下文的Save和Restore不会存储这4个寄存器中的信息。
这里需要着重关注一下A[11]和D[15]寄存器。这两个寄存器对于Bug问题的排查非常有用,为什么这样说呢?因为当程序异常时,D[15]寄存器存储记录TIN(Trap Identification Number),A[11]记录Trap的入口地址。如果能获取这两个信息,很多问题可被快速定位。注意,如果Bug问题是异步的(Asynchronous),A[11]寄存器最近捕获的地址并不一定是问题发生点的入口地址。

D[15]寄存器很有用,在Tricore架构中,Trap分为8个等级:MMU (Memory Management Unit)、 Internal Protection、 Instruction Error、Context Management、System Bus and Peripherals、Assertion Trap、System Call、Non-Maskable Interrupt (NMI)。通过D[15]记录的TIN号即可确认Trap的Class,因此,可以在Trap程序中,将D[15]和A[11]寄存器的信息存储到NVM中,以便于Bug问题的排查

2 Tasks和Context

在TriCore架构中,Tasks分为两种: Software Managed Tasks (SMTs) 和 Interrupt Service Routines (ISRs)。ISR 由硬件触发,直接响应中断;SMT任务由OS创建和调度,因此称为User Tasks。

每个Task会关联对应地模式(Mode):

  • User-0 Mode: 用于不访问外设的Tasks,不能由中断操作

  • User-1 Mode:用于访问一些不受保护的外设Tasks,比如:定时器(TIM)访问任务,此类型任务可以短时间关中断。

  • Supervisor Mode:可访问系统所有寄存器和外设,且可以关闭中断。

一个Tasks执行过程中,会关联多个元素,也就是我们常说的任务上下文(Context)。而这些任务上下文信息是处理器(processor)工作所必须的输入,不然,岂不是“巧妇难为无米之炊”?
任务上下文信息都包括啥呢?任务使用的一些通用寄存器(General Registers)、PC寄存器、程序状态信息寄存器(PSW、PCXI)。Tasks的有效运行和维护由硬件直接操作

TriCore架构中,Context分为Upper context 和Lower context,Upper context 由硬件自动存储,速度快;Lower context需要手动维护。

1、CSA(Context Save Areas)

上下文存储区(CSA)不知道你是否有留意。在链接文件中,会分配一定大小的CSA区间,如下所示:
在这里插入图片描述
上述3个栈的空间分配如下所示:
在这里插入图片描述
如何理解上述的空间分配参数呢?结合tc397,这里做一个分析:

  • LCF_DSPR0_START:DSPR0的起始地址,LCF_DSPR0_SIZE:DSPR0的空间大小。这些值的大小不能随便设定,需要根据Datasheet设置,如下所示:
    在这里插入图片描述
  • LCF_CSA0_SIZE:设置CSA0的大小(本例:8k),一般放在DSPR空间;
  • LCF_USTACK0_SIZE:设置用户栈大小(本例:2k);
  • LCF_ISTACK1_SIZE:设置中断栈大小(本例:1k)。这三个参数的设置根据项目使用情况预估。
    TriCore架构中,CSA是由固定大小(64 bytes)组成的连续存储空间,64 bytes边界对齐。且每个CSA只能保存upper context 或者lower context。
    在这里插入图片描述
    upper context / lower context是什么?upper context 或者lower context均对应16个32 bit寄存器,所以upper context 或者lower context会占用64 bytes空间,保存的内容就是这16个寄存器存储的内容。upper context /lower context示例如下所示:
    在这里插入图片描述
    上图示意中,upper context /lower context放到了Cached区间(Segment 8),启动Cached功能,CPU访问数据或者指令的效率更高(DCached/PCached属于high-speed RAM)。对于Cache功能,可以参考前文Aurix:初识Cached和Non-Cached。

2、CSA作用

铺叙了这么多,需要聊一下CSA(Context Save Area),CSA干什么用的呢?程序在执行的过程中,会有Interrupt、Trap、Function Call发生,而这些事件的执行均需要保存对应的upper context 或者lower context,以便于知道程序应从哪里返回,以及返回时对应的上下文信息等
示例:Function_A()在执行的过程中需要调用Function_B()。

  1. t0时刻,Function_A()调用Function_B()之前需要将对应的upper context 或者lower context信息存储(Save)到CSA中;

  2. t1时刻,开始执行Function_B();

  3. t2时刻,返回Function_A()之前,需要将CSA中的信息恢复(Restore);

  4. t3时刻,返回Function_A()继续执行。

上述流程如下所示:
在这里插入图片描述
注意:

当Interrupt、Trap、Function Call发生时,upper context自动保存;

每个CSA实体16 Word对齐(64 byte)。

参考资料

Infineon-AURIX_TC3xx_Part1-UserManual-v01_00-EN.pdf

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值