1. 以2812为例(28335也是),PIE Vector在Memory Map的位置是0x0D00~0x0E00
这个是在cmd文件中的MEMORY部分指定的:
PIE_VECT : origin = 0x000D00, length = 0x000100 /* PIE Vector Table */
在SECTIONS部分指定了File的映射:
PieVectTableFile : > PIE_VECT, PAGE = 1
这里的File指:
#pragma DATA_SECTION(PieVectTable,"PieVectTableFile");
2. PieVectTable就是中断向量表,它是一个存放ISR地址的结构体:
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;
...
}
extern struct PIE_VECT_TABLE PieVectTable;
其中的PINT是interrupt指针:
typedef interrupt void(*PINT)(void);
3.但这个结构体需要被赋值,也就是在main之前的:
void InitPieVectTable(void)
{
int16 i;
Uint32 *Source = (void *) &PieVectTableInit;
Uint32 *Dest = (void *) &PieVectTable;
EALLOW;
for(i=0; i < 128; i++)
*Dest++ = *Source++;
EDIS;
// Enable the PIE Vector Table
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
}
4.这里的PieVectTableInit是const struct PIE_VECT_TABLE :
const struct PIE_VECT_TABLE PieVectTableInit = {
PIE_RESERVED, // 0 Reserved space
PIE_RESERVED, // 1 Reserved space
PIE_RESERVED, // 2 Reserved space
PIE_RESERVED, // 3 Reserved space
PIE_RESERVED, // 4 Reserved space
...
// Group 8 PIE Vectors
I2CINT1A_ISR, // 8.1 I2C
I2CINT2A_ISR, // 8.2 I2C
rsvd_ISR, // 8.3
...
};
5. PieVectTableInit 中的I2CINT2A_ISR等都是ISR的入口地址 :
interrupt void TINT0_ISR(void); // Timer 0
6. CPU响应中断的过程和从PIE中fetch vector的过程:
综上,PIE初始化的目的就是从给0xD00~0xE00的PIE Vector空间赋初值,这个初值来源于const,表示PIE ISR的入口地址。那既然是常量,为什么不像IQMath Table那样放到ROM中呢?