3 ARM结构中中断向量表的动态配置方法
要在ARM结构中实现与X86中一样方便的在中断向量的随机存取功能,向量表的地址数据必须可以安排在任意32位地址的RAM空间中。为此,中断处理必须增加一条指令,先跳转到向量表,然后执行向量表中动态生成的跳转指令,跳转到中断服务程序,参见下列初始化代码:
;******向量表******
ENTRY
B ResetHandle ;原向量偏移 ,中断号
B ReseHandle ;0x00 ,00
LDR PC,=NewVectorTable+0x08 ;0x04,未定义 ,01
LDR PC,=NeWVector Table+0x10 ;0x08,SWI,02
LDR PC,=NewVectorTable+0x18 ;0x0c,未定义 ,03
LDR PC,=NewVectorTable+0x20 ;0x10,未定义 ,04
LDR PC,=NewVectorTable+0x28;0x14,未定义 0,05
LDR PC,=NewVectorTable+0x30 ;0x18,IRQ ;06
LDR PC,=NewVectorTable+0x38 ;0x1c,FIQ ,07
……
;******代码段******
ResetHandle
……
;***数据段,为NewVectorTable分配数据空间***
NewVectorTable # 128;大小根据需要定义,每向量2个字(8字节);
程序运行时,中断服务的初始化 程序必须设置好新的中断向量表,即在NewVectorTable表中动态生成下列指令:
NewVectorTable;表安排在RAM顶端0x0c1fff00处(由硬件设定)
LDR PC,[PC,#4];指令代码为0xe51ff004,功能为PC〈-[PC+4]
nVt00 DCD ISR_RESET_HANDLE
LDR PC,[PC,#4];与LDR PC,nVt01指令等效
nVt01 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
nVt02 DCD ISR_SWI_HANDLE
LDR pC,[PC,#4]
nVt03 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
nVt04 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
nVt05 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
NVt06 DCD ISR_IRQ_HANDLE
LDR PC,[PC,#4]
nVt07 DCD ISR_FIQ_HANDLE
……
可用C函数在NweVectorTable中生成含上述指令的向量表,具体实现如下:
#define VECTOR_TABLE 0x0c1fff00
//向量表首地址,根据实际硬件来配置
#define INSTRUCTION_LDR_PC 0xe51ff004
//加载PC寄存器的指令码
//设置向量C函数,ISR_Handle中断服务程序地址
void SetVector(unsigned char no,unsigned long int ISR_Handle){
unsigned long int * pVectorTable;
//定义32位无符号数指令,指向向量表
pVectorTable=((unsigned long int *)(VECTOR_TABLE+(no<<3)));
*pVectorTable++=INSTRUCTION_LDR_PC;
//在向量表中放置LDR PC,[PC,#4]指令
*pVectorTable=ISR_Handle;//设置中断服务例程入口地址
}
//读取向量C函数,no代表中断号
unsigned long int GetVector(unsigned char no){
unsigned long int *pVectorTable;
pVectorTable=((unsigned long int *)(VECTOR_TABLE+(no<<3)));
return *(++pVectorTable);//返回中断处理程序入口地址
}
使用上述初始化代码和向量设置函数,除复位向量外,其它所有中断向量都可以指向了在RAM数据区中的新向量表,并给定一个统一的中断编号。中断服务程序可以放在任何模块文件中编译连接,不需要修改原向量表代码,但在打开中断使用中断服务例程前必须使用C函数SetVector()设置中断向量。
3 ARM结构中中断向量表的动态配置方法
要在ARM结构中实现与X86中一样方便的在中断向量的随机存取功能,向量表的地址数据必须可以安排在任意32位地址的RAM空间中。为此,中断处理必须增加一条指令,先跳转到向量表,然后执行向量表中动态生成的跳转指令,跳转到中断服务程序,参见下列初始化代码:
;******向量表******
ENTRY
B ResetHandle ;原向量偏移 ,中断号
B ReseHandle ;0x00 ,00
LDR PC,=NewVectorTable+0x08 ;0x04,未定义 ,01
LDR PC,=NeWVector Table+0x10 ;0x08,SWI,02
LDR PC,=NewVectorTable+0x18 ;0x0c,未定义 ,03
LDR PC,=NewVectorTable+0x20 ;0x10,未定义 ,04
LDR PC,=NewVectorTable+0x28;0x14,未定义 0,05
LDR PC,=NewVectorTable+0x30 ;0x18,IRQ ;06
LDR PC,=NewVectorTable+0x38 ;0x1c,FIQ ,07
……
;******代码段******
ResetHandle
……
;***数据段,为NewVectorTable分配数据空间***
NewVectorTable # 128;大小根据需要定义,每向量2个字(8字节);
程序运行时,中断服务的初始化 程序必须设置好新的中断向量表,即在NewVectorTable表中动态生成下列指令:
NewVectorTable;表安排在RAM顶端0x0c1fff00处(由硬件设定)
LDR PC,[PC,#4];指令代码为0xe51ff004,功能为PC〈-[PC+4]
nVt00 DCD ISR_RESET_HANDLE
LDR PC,[PC,#4];与LDR PC,nVt01指令等效
nVt01 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
nVt02 DCD ISR_SWI_HANDLE
LDR pC,[PC,#4]
nVt03 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
nVt04 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
nVt05 DCD ISR_UNDEF_HANDLE
LDR PC,[PC,#4]
NVt06 DCD ISR_IRQ_HANDLE
LDR PC,[PC,#4]
nVt07 DCD ISR_FIQ_HANDLE
……
可用C函数在NweVectorTable中生成含上述指令的向量表,具体实现如下:
#define VECTOR_TABLE 0x0c1fff00
//向量表首地址,根据实际硬件来配置
#define INSTRUCTION_LDR_PC 0xe51ff004
//加载PC寄存器的指令码
//设置向量C函数,ISR_Handle中断服务程序地址
void SetVector(unsigned char no,unsigned long int ISR_Handle){
unsigned long int * pVectorTable;
//定义32位无符号数指令,指向向量表
pVectorTable=((unsigned long int *)(VECTOR_TABLE+(no<<3)));
*pVectorTable++=INSTRUCTION_LDR_PC;
//在向量表中放置LDR PC,[PC,#4]指令
*pVectorTable=ISR_Handle;//设置中断服务例程入口地址
}
//读取向量C函数,no代表中断号
unsigned long int GetVector(unsigned char no){
unsigned long int *pVectorTable;
pVectorTable=((unsigned long int *)(VECTOR_TABLE+(no<<3)));
return *(++pVectorTable);//返回中断处理程序入口地址
}
使用上述初始化代码和向量设置函数,除复位向量外,其它所有中断向量都可以指向了在RAM数据区中的新向量表,并给定一个统一的中断编号。中断服务程序可以放在任何模块文件中编译连接,不需要修改原向量表代码,但在打开中断使用中断服务例程前必须使用C函数SetVector()设置中断向量。
举报