S5PV210中断的介绍与配置

发布者:PositiveVibes最新更新时间:2022-08-03 来源: csdn关键字:S5PV210  中断  配置 手机看文章 扫描二维码
随时随地手机看文章

一、介绍

1、三星S5PV210中断体系介绍

异常向量表(矢量中断控制器

异常向量表是CPU中某些特定地址的特定定义,当中断发生的时候,中断要通知CPU处理中断,在CPU设计时,定义了CPU中一些特定地址作为特定异常的入口地址,异常向量表的实现,是基于SoC内部的矢量中断控制器


关于矢量中断控制器的描述,这里摘录了网友“亦大乐谍“的博客:


S5PV210是三星推出的一款基于Cortex-A8的Soc,其内部集成的中断控制器由4个ARM PrimeCell

PL192矢量中断控制器级连(daisy-chain)而成,每个PL192 VIC(Vectored Interrupt

Controller)支持32个中断源,所以最多支持128个。S5PV210使用了其中的93个。所谓“矢量”是指当中断发生时,软件可以直接从VIC得到提前设好的中断服务程序ISR(Interrupt

Service Routine)。

CPU在对VIC进行初始化的过程中,将各个中断源的ISR写入到VIC中存储起来,在中断发生以后,VIC会自动挑选出当前优先级最高的中断源,并将其ISR推送到VICADDRESS寄存器里,CPU可以直接拿到ISR(一般就是一个函数的起始地址),将PC跳转到这个地址取执行就可以了,速度大大加快

在这里插入图片描述在这里插入图片描述

以上讲的是CPU硬件设计时对异常向量表的支持,接下来就需要软件支持。硬件已近决定了的发送什么异常CPU自动跳转PC到那个地址执行,软件需要做的就是把处理这个异常的代码的收地孩子填入这个异常向量的地址。


二、异常处理的两个阶段

(1)第一个阶段之所以能够进行,主要依赖于CPU设计时提供的异常向量表机制。第一个阶段的主要任务是从异常发生到响应异常并且保存/恢复现场,跳转到真正的异常处理程序处。

(2)第二个阶段的目的是识别多个中断源中究竟是哪一个发生了中断,然后调用相应的中断处理程序来处理这个中断。


三、编程思路

整个中断的工作分为2部分:

第一部分是我们为中断响应的预备工作

1、初始化中断控制器

2、绑定写好的isr到中断控制器

3、相应的中断的所有条件的使能

第二部分是当硬件产生中断后如何自动执行isr

1、第一步,经过异常向量表跳转入IRQ/FIQ入口

2、第二步,做中断现场保护(在start.s),然后跳入isr_handler

3、第三步,在isr_handler中先去搞清楚是哪个VIC中断了,然后直接去VIC的ADDR寄存器中去isr来执行即可

4、第四步,isr执行完,中断现场恢复,直接返回继续做常规任务。


四、使用外部中断时需要配置的几个重要的寄存器

1、VIC0INTENABLE和VIC0INTENCLEAR

在这里插入图片描述

(1) VICnINTENABLE ------interrupt enable

VINTENCLEAR ------interrupt enable clear

(2)INTENABLE寄存器负责相应的中断的使能;INTENCLEAR寄存器负责相应的中断的禁止。

(3)当我们想使能(意思就是启用这个中断,意思就是当硬件产生中断时CPU能接收的到)某个中断时,只要在这个中断编号对应的VICnINTENABLE的相应bit位写1即可(注意这个位写1其他位写0对其他位没有影响);如果我们想禁止某个中断源时,只要向VICnINTENCLEAR中相应的位写1即可。注意:这里的设计一共有2种:有些CPU是中断使能和禁止是一个寄存器位,写1就使能写0就禁止(或者反过来写1就禁止写0就使能),这样的中断使能设计就要非常小心,要使用我们之前说过的读改写三部曲来操作;

另一种就是使能和禁止分开为2个寄存器,要使能就写使能寄存器,要禁止就写禁止寄存器。这样的好处是我们使能/禁止操作时不需要读改写,直接写即可。

2、VICnINTSELECT(Interrupt Select Register,中断模式选择寄存器,0选择IRQ ,1FIQ)

在这里插入图片描述

(1)设置各个中断的模式为irq还是fiq。一般都设置成irq

(2)IRQ和FIQ究竟的区别:

irq是普通中断,fiq是快速中断。快速中断提供一种更快响应处理的中断通道,用于对实时性要求很高的中断源。fiq在CPU设计时预先提供了一些机制保证fiq可以被快速处理,从而保证实时性。fiq的限制就是只能有一个中断源被设置为fiq,其他都是irq。

(3)CPU如何保证fiq比irq快?有2个原因:第一,fiq模式有专用的r8~r12,因此在fiq的isr中可以直接使用r8-r12而不用保存,这就能节省时间;第二,异常向量表中fiq是最后一个异常向量入口。因此fiq的isr不需要跳转,可以直接写在原地,这样就比其他异常少跳转一次,省了些时间。

3、VICnIRQSTATUS和VICnFIQSTATUS

在这里插入图片描述

中断状态寄存器,是只读的。当发生了中断时,硬件会自动将该寄存器的对应位置为1。

4、VICnVECTPRIORITY0~VICnVECTPRIORITY31


(1)中断优先级设置寄存器,设置多个中断同时发生时先处理谁后处理谁的问题。一般来说高优先级的中断可以打断低优先级的中断,从而嵌套处理中断。当然了有些硬件/软件可以设置不支持中断嵌套。

5、VICnVECTADDR0~VICnVECTADDR31、VICnADDR

在这里插入图片描述

(1)VICnVECTADDR0~31这32个寄存器分别用来存放真正的各个中断对应的isr的函数地址。相当于每一个中断源都有一个VECTADDR寄存器,程序员在设置中断的时候,把这个中断的isr地址直接放入这个中断对应的VECTADDR寄存器即可。

(2)VICnADDR这个寄存器是只需要读的,它里面的内容是由硬件自动设置的。当发生了相应中断时,硬件会自动识别中断编号,并且会自动找到这个中断的VECTADDR寄存器,然 后将其读出复制到VICnADDR中,供我们使用。这样的设计避免了软件查找中断源和isr,节省了时间,提高了210的中断响应速度。


五、代码分析

(一)代码分析—中断模式下的现场保护和恢复


IRQ_handle:


// 设置IRQ模式下的栈 0xD003_7F80


 ldr sp, =IRQ_STACK   


// 保存LR

// 因为ARM有流水线,所以PC的值会比真正执行的代码+8,


 sub lr, lr, #4


// 保存r0-r12和lr到irq模式下的栈上面


 stmfd sp!, {r0-r12, lr}


// 在此调用真正的isr来处理中断


 bl irq_handler


// 处理完成开始恢复现场,其实就是做中断返回,关键是将r0-r12,pc,cpsr一起恢复


 ldmfd sp!, {r0-r12, pc}^


(二)代码分析—从main函数中中断的相关函数入手拆解


 int main(void)

{

 int n = 0;

 uart_init();

 

 // 如果程序中要使用中断,就要调用中断初始化来初步初始化中断控制器

 system_init_exception();

 eint_init();

 // 绑定isr到中断控制器硬件

 intc_setvectaddr(KEY_DOWN, key_isr_eint2);

 intc_setvectaddr(KEY_BACK, key_isr_eint16171819);

 intc_enable(KEY_DOWN);

 intc_enable(KEY_BACK);

 

 while (1)

 {

  printf("%d ", n++);

  delay(10000);

 }

 

 return 0;

}


①代码:key_init_interrupt();

void key_init_interrupt(void)

{

//1、外部中断对应的GPIO模式设置

rGPH0CON |= 0xFF<<8; //GPH0_2和GPH0_3设置为外部中断模式

rGPH2CON |= 0XFFFF<<0; //GPH2_0,1,2,3共4个引脚设为外部中断模式

//2、中断触发模式设置,这里设为下降沿触发

EXT_INT_0_CON &= ~(0XFF<<8); //bit8~bit15全部清零

EXT_INT_0_CON |= ((2<<8)|(2<<12));//EXT_INT2和EXT_INT3设置位下降沿触发。

//3、 中断允许,清挂

rEXT_INT_0_MASK &= ~(3<<2);

rEXT_INT_2_MASK &= ~(3<<0x0f<<0);

//4、清挂起,清除是写1

rEXT_INT_0_PEND |= (3<<2);

rEXT_INT_2_PEND |= (0x0F<<0);

}


②代码:System_init_exception();

// 主要功能:绑定第一阶段异常向量表;禁止所有中断;选择所有中断类型为IRQ;

// 清除VICnADDR为0

void system_init_exception(void)

{ // 第一阶段处理,


绑定异常向量表

r_exception_reset = (unsigned int)reset_exception;

r_exception_undef = (unsigned int)undef_exception;

r_exception_sotf_int = (unsigned int)sotf_int_exception;

r_exception_prefetch = (unsigned int)prefetch_exception;

r_exception_data = (unsigned int)data_exception;

r_exception_irq = (unsigned int)IRQ_handle;

r_exception_fiq = (unsigned int)IRQ_handle;

// 初始化中断控制器的基本寄存器

intc_init();

}


代码:void intc_init(void)

// 禁止所有中断

// 为什么在中断初始化之初要禁止所有中断?

// 因为中断一旦打开,因为外部或者硬件自己的原因产生中断后一定就会寻找isr

// 而我们可能认为自己用不到这个中断就没有提供isr,这时它自动拿到的就是乱码

// 则程序很可能跑飞,所以不用的中断一定要关掉。

// 一般的做法是先全部关掉,然后再逐一打开自己感兴趣的中断。一旦打开就必须

// 给这个中断提供相应的isr并绑定好。

void intc_init(void)

{

VIC0INTENCLEAR = 0xffffffff;

VIC1INTENCLEAR = 0xffffffff;

VIC2INTENCLEAR = 0xffffffff;

VIC3INTENCLEAR = 0xffffffff;

// 选择中断类型为IRQ

VIC0INTSELECT = 0x0;

VIC1INTSELECT = 0x0;

VIC2INTSELECT = 0x0;

VIC3INTSELECT = 0x0;

// 清VICxADDR

intc_clearvectaddr();

}

-代码:void intc_clearvectaddr(void)

// 清除需要处理的中断的中断处理函数的地址

void intc_clearvectaddr(void)

{

// VICxADDR:当前正在处理的中断的中断处理函数的地址

VIC0ADDR = 0;

VIC1ADDR = 0;

VIC2ADDR = 0;

VIC3ADDR = 0;

}


③ 代码:intc_setve

ctaddr(KEY_INT2, isr_eint2);

// 绑定isr到中断控制器硬件


 intc_setvectaddr(KEY_INT2, isr_eint2);

 intc_setvectaddr(KEY_INT3, isr_eint3);

 intc_setvectaddr(KEY_INT16_19, isr_eint16171819);


// 绑定我们写的isr到VICnVECTADDR寄存器

// 绑定过之后我们就把isr地址交给硬件了,剩下的我们不用管了,硬件自己会处理

// 等发生相应中断的时候,我们直接到相应的VICnADDR中去取isr地址即可。

// 参数:intnum是int.h定义的物理中断号,handler是函数指针,就是我们写的isr

// VIC0VECTADDR定义为VIC0VECTADDR0寄存器的地址,就相当于是VIC0VECTADDR0~31这个

// 数组(这个数组就是一个函数指针数组)的首地址,然后具体计算每一个中断的时候

// 只需要首地址+偏移量即可。


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;

}


③代码:intc_ena

ble(KEY_DOWN);

// 使能中断

// 通过传参的intnum来使能某个具体的中断源,中断号在int.h中定义,是物理中断号


#define NUM_HSMMC3 (96+2)

#define NUM_CEC (96+3)

#define NUM_TSI (96+4)

#define NUM_MDNIE0 (96+5)

#define NUM_MDNIE1 (96+6)

#define NUM_MDNIE2 (96+7)

#define NUM_MDNIE3 (96+8)

#define NUM_ADC1 (96+9)

#define NUM_PENDN1 (96+10)

#define NUM_ALL (200)


void intc_enable(unsigned long intnum)

{

unsigned long temp;

// 确定intnum在哪个寄存器的哪一位

// <32就是0~31,必然在VIC0

if(intnum<32)

{

temp = VIC0INTENABLE;

temp |= (1<// 直接写。

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{

temp = VIC3INTENABLE;

temp |= (1<<(intnum-96));

VIC3INTENABLE = temp;

}

// NUM_ALL : enable all interrupt

else

{

VIC0INTENABLE = 0xFFFFFFFF;

VIC1INTENABLE = 0xFFFFFFFF;

VIC2INTENABLE = 0xFFFFFFFF;

VIC3INTENABLE = 0xFFFFFFFF;

}

}

关键字:S5PV210  中断  配置 引用地址:S5PV210中断的介绍与配置

上一篇:S5PV210的启动过程详解
下一篇:ARM汇编指令集的特点

推荐阅读最新更新时间:2024-11-12 22:54

S3C2440裸机------异常与中断__定时器中断程序示例
1.定时器的工作原理 注意当TCNTn=TCMPn时不会产生中断。 2.代码 2.1 timer.c 首先是根据上面的两个寄存器设置时钟; /* 设置TIMER0的时钟 */ /* Timer clk = PCLK / {prescaler value+1} / {divider value} = 50000000/(99+1)/16 = 31250 */ TCFG0 = 99; /* Prescaler 0 = 99, 用于timer0,1 */ TCFG1 &= ~0xf; TCFG1 |= 3; /* MUX0 : 1/16 */ 然后根据上图的寄存器设置初始值。 /*
[单片机]
S3C2440裸机------异常与<font color='red'>中断</font>__定时器<font color='red'>中断</font>程序示例
make the OC8051 run
作为开头,很多细节我就先略过了,主要简单的介绍几个步骤to make the OC8051 run。 1、获取OC8051源代码。(opencore或某电子类论坛下载)。 2、修改oc8051_defines.v。此文件可让用户对硬件进行裁剪和配置。 修改如下(部分): 1 // 2 // oc8051 pherypherals 3 // 4 `define OC8051_UART 5 `define OC8051_TC01 6 `define OC8051_TC2 7 `define OC8051_PORTS //ports global enable 8 `define OC8051_PORT0
[单片机]
make the OC8051 run
包含中断的LED显示汇编语言程序
例:电路如图。要求编程实现:主程序将P1口的8个LED从上到下循环显示(间隔时间约1S ), 中断 时(INT0)使8个LED同时闪烁5次(间隔时间约1S,设单片机晶振为6M)。 图片1 (1)主程序 ORG 0000H LJMP START START:MOV IE,#10000001B;允许INT0中断 MOV IP,#00000001B;INT0中断优先 MOV TCON,#01H ;INT0边沿触发方式 MOV SP,#70H MOV A,#80H ;左移初值 LOOP1:RL A
[单片机]
包含<font color='red'>中断</font>的LED显示汇编语言程序
MSP430外部中断源程序
#include msp430x41x.h unsigned int L7=~((0X01) 6); unsigned int L8=~((0X01) 7); void main(void) { WDTCTL = WDTPW + WDTHOLD; // 禁止看门狗定时器 //P1DIR |= 0x01; // 设置P1.0为输出方向 P2DIR = 0xff; //设置P2口方向为输出 P2OUT = 0xff; P2OUT |= BIT0; P1IE |= 0x10; // P1.4中断使能 P1IES |= 0x10; // P1.4设置为高低边沿中断 P1IFG &= ~
[单片机]
MSP430 LaunchPad定时器中断(连续模式)
#include msp430g2231.h int main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P1DIR |= 0x01; TACCTL0 = CCIE;//使能CCIFG标志产生的中断 TACCR0 = 50000;(试验了一下,这句不加也可以) TACTL = TASSEL_2 + MC_2;//选择timer时钟和模式 // _BIS_SR(GIE); _EINT();//开总中断 while(1); } /*中断服务程序*/ #pragma vector
[单片机]
汽车雷达系统成为主流配置
    还记得吗?小时候,无论我们在做什么,妈妈似乎都能看到,就好像她们的脑袋后面也长着眼睛。事实上,在日常生活中,我们有时需要察看前方视野之外的事物,这对我们来说至关重要。其中一个情况就是在驾驶汽车的时候。最近有一条汽车广告将路面交通描述为“杂乱无章”。这条广告描述了正常驾驶时会遇到的各种危险和意外,主要为了推广基于雷达的最新高级驾驶员辅助系统 (ADAS) ,此系统能够帮助驾驶员及时发现这些危险和路面上的障碍物。这条广告中最有趣的一个地方在于其所展示的车辆并非豪华轿车,而是标准的中型家用轿车。诸如盲点监视、路口交通警报、障碍物检测和碰撞预警系统已经出现了很多年,然而,它们的配置数量有限,并且只用于高端车辆。    
[汽车电子]
STM32学习笔记之外部中断实验
实验目的: 当按键按下时,让PF10引脚的LED灯亮, 当按键再次按下时,让PF10引脚的LED灯灭; 无论按下与否,PF9引脚的LED灯循环闪烁; 实验步骤: 实验程序: /***********************************led.c*********************************/ #include stm32f4xx.h //在SYSTEM目录下可以找到 #include sys.h void LED_Init(void){ RCC- AHB1ENR = 1 5; //使能GPIO端口的F时钟 GPIO_Set
[单片机]
STM32学习笔记之外部<font color='red'>中断</font>实验
STM32如何确定执行哪个中断函数
如下面所示: NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //NRF24L01 中断响应 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级为1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_Init(&NVIC_InitStructure); 则对应的中断函数就是 STM3210x_
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved