[资料分享] TI源码对TMS320f28335中断机制的进一步理解

Aguilera   2018-2-21 21:14 楼主
因为TI官方给出的28335的例子中,对中断向量表的定义为
// Define Vector Table:
struct PIE_VECT_TABLE {
// Reset is never fetched from this table.
// It will always be fetched from 0x3FFFC0 in
// boot ROM
      PINT     PIE1_RESERVED;
      PINT     PIE2_RESERVED;
      PINT     PIE3_RESERVED;
      PINT     PIE4_RESERVED;
      PINT     PIE5_RESERVED;
      PINT     PIE6_RESERVED;
      PINT     PIE7_RESERVED;
      PINT     PIE8_RESERVED;
      PINT     PIE9_RESERVED;
      PINT     PIE10_RESERVED;
      PINT     PIE11_RESERVED;
      PINT     PIE12_RESERVED;
      PINT     PIE13_RESERVED;
// Non-Peripheral Interrupts:
      PINT     XINT13;    // XINT13 / CPU-Timer1
      PINT     TINT2;     // CPU-Timer2
      PINT     DATALOG;   // Datalogging interrupt
      PINT     RTOSINT;   // RTOS interrupt
      PINT     EMUINT;    // Emulation interrupt
      PINT     XNMI;      // Non-maskable interrupt
      PINT     ILLEGAL;   // Illegal operation TRAP
      PINT     USER1;     // User Defined trap 1
      PINT     USER2;     // User Defined trap 2
      PINT     USER3;     // User Defined trap 3
      PINT     USER4;     // User Defined trap 4
      PINT     USER5;     // User Defined trap 5
      PINT     USER6;     // User Defined trap 6
      PINT     USER7;     // User Defined trap 7
      PINT     USER8;     // User Defined trap 8
      PINT     USER9;     // User Defined trap 9
      PINT     USER10;    // User Defined trap 10
      PINT     USER11;    // User Defined trap 11
      PINT     USER12;    // User Defined trap 12
// Group 1 PIE Peripheral Vectors:
      PINT     SEQ1INT;
      PINT     SEQ2INT;
      PINT     rsvd1_3;
      PINT     XINT1;
      PINT     XINT2;
      PINT     ADCINT;    // ADC
      PINT     TINT0;     // Timer 0
      PINT     WAKEINT;   // WD
      ...}(只列出到了group1,到这里就够了)因为TI的官方手册中《TMS320x2833x, 2823x System Control and Interrupts Reference Guide》给出的中断向量排布是通过TI源码对TMS320f28335中断机制的进一步理解
5899.jpg
就在这个地方需要注意的是Reset和INT1~INT12一共13个向量是没有使用的,这里只是作为一个32位无符号整数占据地址位置,而在代码中程序员没有这么写,直接是PIE1_RESERVED~PIE13_RESERVED,这让我一开始看代码的时候产生了很大困惑,因为文档中说Reset向量复位的时候是不从这个表中取的,是从boot ROM中取的,所以Reset向量这里就没写,但是CMD文件中PIE_VECT    : origin = 0x000D00, length = 0x000100,中断向量表的起始地址是 0x000D00,如果不定义Reset向量,那所有后面的向量不就向前面移动了两个地址,后来我为了地址对应就在向量表定义中加入了一行 PINT Reset_RESERVED,结果编译报错,好像是CMD中分配的地址重叠了,因为多加了一项,我就把向量表中的最后一项注释掉了(group12的最后一项),编译过了,但是发现进不了指定中断(我这里用的是TI例程中看门狗中断的例子),只能进入中断向量表初始化时指定的默认中断(就是一个NOP空操作,这里多说一句,为什么一定要初始化中断向量表,因为一旦有中断发生,没有初始化中断向量表,中断向量表中的地址值是随机的,这样程序就跳转到一个随机地址,程序就跑飞了,所以开始给所有中断向量赋一个指定的地址值,一旦发生中断,程序就跳到那个地址去执行,这里TI给的代码中,这个初始化地址就是一个只包含一个NOP指令的函数不对程序产生影响),继续说我们的调试,我发现CPU是从0x0D4E这个地址中取出的中断函数(看PIECTRL Register的1~15位就知道了,第0位是PIE使能位),而手册上说WAKEINT这个中断也确实是在0x0D4E这个地址上,而我们指定的中断服务函数PieVectTable.WAKEINT = &wakeint_isr却在下一个地址0x0D50的位置上(中断向量表每条中断向量都是32位的)。这我就基本明白了,一旦发生某个中断,CPU是去某个固定地址取中断向量,这是CPU硬件自动完成的,不是软件可以改变的,比如这个例子,只要看门狗中断发生,CPU就去0x0D4E这个地址去取中断向量。
       好吧现在我们继续批判TI偷懒的程序员给我们带来这么大的困扰,其实他并没有遗漏Reset这个向量,仔细数数代码中PIE1_RESERVED~PIE13_RESERVED一共13个占位地址,看手册中只用INT1~INT12是没有使用的,INT13是外部中断13或者CPU Timer1中断,好吧INT1~INT12+Reset中断一共13个未用中断,TI的程序员你赢了,正好和PIE1_RESERVED~PIE13_RESERVED对应,这样地址也是正好对应的,一切问题都没有。不过他这种坑爹写法,让我浪费了好几个小时调试,不过也让我进一步认清了中断机制的真面目。就算扯平了吧。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复