ARM中断系统详述3
2016-08-26 02:36
239 查看
第三步是void system_init_exception(void);
这个函数的作用是初始化中断控制器
寄存器在上一章已经声明过了,接下来我们只写程序。
void system_init_exception(void)
{
//绑定异常向量表(这些函数名地址转换成四个字节的地址)
//如果有异常产生时,CPU就会从异常向量表中找到处理程序的地址,转而去执行异常处理程序
(*(volatile unsigned int *)exception_reset) = (unsigned int)reset_exception;
(*(volatile unsigned int *)exception_undef) = (unsigned int)undef_exception;
(*(volatile unsigned int *)exception_sotf_int) = (unsigned int)sotf_int_exception;
(*(volatile unsigned int *)exception_prefetch) = (unsigned int)prefetch_exception;
(*(volatile unsigned int *)exception_data) = (unsigned int)data_exception;
(*(volatile unsigned int *)exception_irq) = (unsigned int)IRQ_handle;
(*(volatile unsigned int *)exception_fiq) = (unsigned int)IRQ_handle;
// 初始化中断控制器的基本寄存器
// 不用的中断一定要关掉,否则则程序很可能跑飞(硬件置1则进去执行,如果里面的代码是乱码那就跑飞了)
// 先全部关掉,然后再逐一打开需要的中断。一旦打开就必须给这个中断提供相应的isr并绑定好。
VIC0INTENCLEAR = 0xffffffff;
VIC1INTENCLEAR = 0xffffffff;
VIC2INTENCLEAR = 0xffffffff;
VIC3INTENCLEAR = 0xffffffff;
// 选择中断类型为IRQ
VIC0INTSELECT = 0x0;
VIC1INTSELECT = 0x0;
VIC2INTSELECT = 0x0;
VIC3INTSELECT = 0x0;
// 清VICxADDR
// VICxADDR:当前正在处理的中断的中断处理函数的地址
//每个中断源都有一个VECTADDR寄存器,用来存放这个中断对应的函数的地址(程序员自己存)
//中断产生的时候,硬件自动找到中断源的中断编号,并把则中断对应的函数的地址推入
//VICnADDR寄存器,我们直接读出来就可以使用了。
VIC0ADDR = 0;
VIC1ADDR = 0;
VIC2ADDR = 0;
VIC3ADDR = 0;
}
第四步:绑定isr函数的地址到中断控制器硬件
等发生相应中断的时候,我们直接到相应的VICnADDR中去取isr地址即可。
VIC0VECTADDR定义为VIC0VECTADDR0寄存器的地址,就相当于是VIC0VECTADDR0~31这个函数指针数组的首地址,
然后具体计算每一个中断的时候只需要首地址+偏移量即可
这两个参数中,intnum是int.h定义的物理中断号,handle是isr函数的指针
void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{
//VIC0
if(intnum<32)
{
*( (volatile unsigned long *)(VIC0VECTADDR + 4*(intnum-0)) ) = (unsigned)handler;
}
//VIC1
else if(intnum<64)
{
*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;
}
//VIC2
else if(intnum<96)
{
*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;
}
//VIC3
else
{
*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;
}
return;
}
第五步是使能中断
通过intnum(物理中断号)来使能某个具体的中断源
void intc_enable(unsigned long intnum)
{
unsigned long temp;
// 确定intnum在哪个寄存器的哪一位
if(intnum<32)
{
temp = VIC0INTENABLE;
temp |= (1<<intnum);
VIC0INTENABLE = temp;
}
else if(intnum<64)
{
temp = VIC1INTENABLE;
temp |= (1<<(intnum-32));
VIC1INTENABLE = temp;
}
else if(intnum<96)
{
temp = VIC2INTENABLE;
temp |= (1<<(intnum-64));
VIC2INTENABLE = temp;
}
else if(intnum<NUM_ALL)
{
temp = VIC3INTENABLE;
temp |= (1<<(intnum-96));
VIC3INTENABLE = temp;
}
//这个机制可以一次打开所有中断源
else
{
VIC0INTENABLE = 0xFFFFFFFF;
VIC1INTENABLE = 0xFFFFFFFF;
VIC2INTENABLE = 0xFFFFFFFF;
VIC3INTENABLE = 0xFFFFFFFF;
}
}
S5PV210的好处就是,往VICnINTENABLE里面写1的时候,不管VICnINTENABLE里面是啥,都会使写1的那一位对应的中断使能,
往VICnINTENABLE里面写1的时候,不管VICnINTENABLE里面是啥,都会使写1的那一位对应的中断禁止。
这个函数的作用是初始化中断控制器
寄存器在上一章已经声明过了,接下来我们只写程序。
void system_init_exception(void)
{
//绑定异常向量表(这些函数名地址转换成四个字节的地址)
//如果有异常产生时,CPU就会从异常向量表中找到处理程序的地址,转而去执行异常处理程序
(*(volatile unsigned int *)exception_reset) = (unsigned int)reset_exception;
(*(volatile unsigned int *)exception_undef) = (unsigned int)undef_exception;
(*(volatile unsigned int *)exception_sotf_int) = (unsigned int)sotf_int_exception;
(*(volatile unsigned int *)exception_prefetch) = (unsigned int)prefetch_exception;
(*(volatile unsigned int *)exception_data) = (unsigned int)data_exception;
(*(volatile unsigned int *)exception_irq) = (unsigned int)IRQ_handle;
(*(volatile unsigned int *)exception_fiq) = (unsigned int)IRQ_handle;
// 初始化中断控制器的基本寄存器
// 不用的中断一定要关掉,否则则程序很可能跑飞(硬件置1则进去执行,如果里面的代码是乱码那就跑飞了)
// 先全部关掉,然后再逐一打开需要的中断。一旦打开就必须给这个中断提供相应的isr并绑定好。
VIC0INTENCLEAR = 0xffffffff;
VIC1INTENCLEAR = 0xffffffff;
VIC2INTENCLEAR = 0xffffffff;
VIC3INTENCLEAR = 0xffffffff;
// 选择中断类型为IRQ
VIC0INTSELECT = 0x0;
VIC1INTSELECT = 0x0;
VIC2INTSELECT = 0x0;
VIC3INTSELECT = 0x0;
// 清VICxADDR
// VICxADDR:当前正在处理的中断的中断处理函数的地址
//每个中断源都有一个VECTADDR寄存器,用来存放这个中断对应的函数的地址(程序员自己存)
//中断产生的时候,硬件自动找到中断源的中断编号,并把则中断对应的函数的地址推入
//VICnADDR寄存器,我们直接读出来就可以使用了。
VIC0ADDR = 0;
VIC1ADDR = 0;
VIC2ADDR = 0;
VIC3ADDR = 0;
}
第四步:绑定isr函数的地址到中断控制器硬件
等发生相应中断的时候,我们直接到相应的VICnADDR中去取isr地址即可。
VIC0VECTADDR定义为VIC0VECTADDR0寄存器的地址,就相当于是VIC0VECTADDR0~31这个函数指针数组的首地址,
然后具体计算每一个中断的时候只需要首地址+偏移量即可
这两个参数中,intnum是int.h定义的物理中断号,handle是isr函数的指针
void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{
//VIC0
if(intnum<32)
{
*( (volatile unsigned long *)(VIC0VECTADDR + 4*(intnum-0)) ) = (unsigned)handler;
}
//VIC1
else if(intnum<64)
{
*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;
}
//VIC2
else if(intnum<96)
{
*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;
}
//VIC3
else
{
*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;
}
return;
}
第五步是使能中断
通过intnum(物理中断号)来使能某个具体的中断源
void intc_enable(unsigned long intnum)
{
unsigned long temp;
// 确定intnum在哪个寄存器的哪一位
if(intnum<32)
{
temp = VIC0INTENABLE;
temp |= (1<<intnum);
VIC0INTENABLE = temp;
}
else if(intnum<64)
{
temp = VIC1INTENABLE;
temp |= (1<<(intnum-32));
VIC1INTENABLE = temp;
}
else if(intnum<96)
{
temp = VIC2INTENABLE;
temp |= (1<<(intnum-64));
VIC2INTENABLE = temp;
}
else if(intnum<NUM_ALL)
{
temp = VIC3INTENABLE;
temp |= (1<<(intnum-96));
VIC3INTENABLE = temp;
}
//这个机制可以一次打开所有中断源
else
{
VIC0INTENABLE = 0xFFFFFFFF;
VIC1INTENABLE = 0xFFFFFFFF;
VIC2INTENABLE = 0xFFFFFFFF;
VIC3INTENABLE = 0xFFFFFFFF;
}
}
S5PV210的好处就是,往VICnINTENABLE里面写1的时候,不管VICnINTENABLE里面是啥,都会使写1的那一位对应的中断使能,
往VICnINTENABLE里面写1的时候,不管VICnINTENABLE里面是啥,都会使写1的那一位对应的中断禁止。
相关文章推荐
- ARM中断系统详述2
- ARM中断系统详述1
- ARM S3C2410X系统中断编程机制的研究与应用
- ARM系统中断向量表的动态配置
- ARM920T(S3C2440)的中断系统
- linux-arm中断系统之GIC
- ARM嵌入式系统中断向量表的动态配置
- ARM嵌入式系统中断向量表的动态配置
- linux-arm中断系统之中断过程
- linux-arm中断系统之GIC
- 异常和中断处理 ARM系统开发者指南 Chapter9-1
- 关于 arm的中断系统 分类: 嵌入式开发学习 2011-04-11 19:30 560人阅读 评论(0) 收藏
- ARM系统中断产生流程
- ARM系统中断产生流程
- linux-arm中断系统之GIC
- ARM系统中断产生流程
- ARM嵌入式系统中断向量表的动态配置
- ARM系统中断产生流程
- arm920t中断系统详解
- ARM体系结构笔记①---(ARM的7种模式、寄存器、存储空间、指令、中断、最小系统)