S3C2440中断控制器痛点详解
mini2440调试进不了中断解决方案

ldr r0,=SRCPND str r1,[r0] ldr r0,=INTPND str r1,[r0] ldr r0,=INTSUBMSK ldr r1,=0x7fff @all sub interrupt disable, 2002/04/10 str r1,[r0] @@@设置频率 mov r1, #CLK_CTL_BASE ldr r2, clock_locktime str r2, [r1, #oLOCKTIME] mov r1, #CLK_CTL_BASE ldr r2, clkdivn_value str r2, [r1, #oCLKDIVN] mrc p15, 0, r1, c1, c0, 0 @ read ctrl register orr r1, r1, #0xc0000000 @ Asynchronous mcr p15, 0, r1, c1, c0, 0 @ write ctrl register mov r1, #CLK_CTL_BASE ldr r2, mpll_value @ clock default str r2, [r1, #oMPLLCON] @@@@初始化串口 InitUART: @set GPIO for UART mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_H ldr r2, gpio_con_uart str r2, [r1, #oGPIO_CON] ldr r2, gpio_up_uart str r2, [r1, #oGPIO_UP] ldr r1, SerBase mov r2, #0x0 str r2, [r1, #oUFCON] str r2, [r1, #oUMCON] mov r2, #0x3 str r2, [r1, #oULCON] ldr r2, =0x245 str r2, [r1, #oUCON] .equ UART_BRD , ((UART_PCLK / (UART_BAUD_RATE*16)) - 1) mov r2, #UART_BRD str r2, [r1, #oUBRDIV] mov r3, #100 InitUART1:
实验5 S3C2440中断实验

LOOP0
stmfd sp!,{r0,r1,lr}; 保存现场 ldr r0,=0x20005000 ; 取LED灯驱动器端口地址 ldr r1,=0x01 str r1,[r0] ; 点亮第1个LED灯 bl Delay ; 延迟 ldr r0,=0x20005000 ; ldr r1,=0x03 str r1,[r0] ; 点亮第2个LED灯 bl Delay ; 延迟 ldr r0,=0x20005000; ldr r1,=0x07 str r1,[r0] ; 点亮第3个LED灯 bl Delay ; 延迟 ldr r0,=0x20005000 ; 点亮第4个LED灯 ldr r1,=0x0f str r1,[r0] bl Delay ;延迟 ldr r0,=0x20005000 ;熄灭所有LED灯 ldr r1,=0x00 str r1,[r0] ldr r0,=pSRCPND ; 清0中断源悬挂寄存器EINT3位 mov r1,#8 str r1,[r0] ldr r0,=pINTPND ; 清0中断悬挂寄存器EINT3位 str r1,[r0] ldmfd sp!,{r0,r1,pc}; 返回‘wait_server b.’下条指令
实验目的
掌握ARM处理器的中断处理机制及中断响应过程。 掌握S3C2440的中断控制寄存器的使用及中断处理程序
编程。
掌握基于嵌入式裸机系统的中断应用程序设计实现
实验内容
一、验证实验
输入并调试实验教程提供的参考程序,实现当按下与实 验箱外部中断3引脚EINT3连接的按键时,使8位LED中的低 4位LED依次点亮后再熄灭。
nCS_SEG1
D31~D0
EINT3(GPF3)
将INT3接之以按键 开关作为中断信号 输入端,每按一次 按键产生一次中断 请求,中断处理程 序使低4位LED逐个 点亮然后再熄灭。
S3C2440外部中断操作

1
20100831
编写:小龍
吧把 INTPND 中相应位置 1,所以同一时间只有一位是 1。也就是说前面的寄存 器置 1 是表示发生了,只有 INTPND 置 1,CPU 才会处理。 INTOFFSET :用来表示 INTPND 中哪一位置 1 了,好让你查询,普 通中断跳转时查询用。清除 INTPND、SRCPND 时自动清除。 4.各寄存器关系:
5
20100831 case 0x2000: if(rGPBDAT & 0x80) LED3_ON(); else LED3_OFF(); break; case 0x4000: if(rGPBDAT & 0x100) LED4_ON(); else LED4_OFF(); break; case 0x8000: LED_ON(); break; case 0x80000: LED_OFF(); break;
下面看图说明: 5.中断过程。 a 如果是不带子中断的内部中断:发生后 SRCPND 相应位置 1,如果没有被 INTMSK 屏蔽,那么等待进一步处理。 b 如果是带子中断的内部中断:发生后 SUBSRCPND 相应位置 1,如果没有被 INTSUBMSK 屏蔽,那么 SRCPND 相应位置 1,等待进一步处理,几个 SUBSRCPND 可能对应同一个 SRCPND,对应表如下: SRCPND SUBSRCPND INT_UART0 INT_RXD0,INT_TXD0,INT_ERR0 INT_UART1 INT_RXD1,INT_TXD1,INT_ERR1 INT_UART2 INT_RXD2,INT_TXD2,INT_ERR2 INT_ADC INT_ADC_S, INT_TC INT_CAM INT_CAM_C, INT_CAM_P INT_WDT_AC97 INT_WDT, INT_AC97
mdk下2440裸机中断

MDK下S3C2440裸机中断,断断续续将耗费了我将近了一个月的时间,在贵师大图书馆里几乎翻遍了有关图书,有关这方面的介绍寥寥而过,想必出书的人也未必弄得清楚。
网上的资料也五花八门,有些说MDK自带的2440的启动代码有误(确实跟2410的启动代码不同,但经过这段时间的验证,启动代码绝对没有任何问题);有些说必须内存映射到正确的地址,才可以进入相应异常(从NORFLASH启动绝对可以进入IRQ中断);大部分在书写中断服务程序时,__irq关键字都放在函数名的前面(ADS编译器__irq关键之放置在函数名前面,但MDK必须将__irq关键字放在函数最末端);有些说必须修改2440启动代码才能进入中断(没有对启动代码做任何修改,实现了IRQ中断)……在这些一大堆乱七八糟的资料中,我差点都放弃了ARM的学习。
为了实现IRQ中断而很吃力地学习了ARM汇编,试着修改2440的启动代码;学习了内存管理,试着映射异常向量的地址;如今回过头去看,能挺过来挺欣慰的。
为实现简单IRQ中断其实很简单的,真是踏破铁鞋无觅处,得来全不费功夫。
以下是关键的几点程序说明,希望对后面学习的朋友,有些帮助。
void irq_init() //irq初始化,这个函数其实比较简单,适当看看2440PDF就应该能设定寄存器了{GPFCON = 0xaaaa;SRCPND = 0x17;INTMSK &= ~(0x17);INTPND = 0x17;EINTPEND =(1<<4);__asm{nop}EINTMASK &=~(1<<4);__asm{nop}EXTINT0 = 0x0;}//这是个很关键的函数,但其实也简单中断服务函数照着这个形式写就应该没能进入IRQ中断了。
void IRQ_Handler(void) __irq //irq中断函数{int j=0;__asm{nop};__asm{nop};j= INTOFFSET;SRCPND = SRCPND | 0x17;INTPND = INTPND | 0x17;switch(j){case 0:irq_ent0();//为中断0break;case 1:irq_ent1();//外中断1break;case 2:irq_ent2();//外中断2break;case 4:irq_ent4();//外中断4irq_init();break;}}以上两个函数式实现IQR中断的关键函数,能弄清楚上面的两个函数,IRQ中断应该就没什么大问题了。
S3C2440源未决寄存器SRCPND和中断未决寄存器INTPND以及外部中断未决寄存器EINTPEND分析

S3C2440中断分析中断源未决寄存器(SRCPND)和中断未决寄存器(INTPND)以及外部中断未决寄存器(EINTPEND)分析2013年04月13日飞梦缘整理中断源未决寄存器SRCPND寄存器由32位构成,每一位与一个中断请求信号相关联。
当某个中断源请求中断服务时,SRCPND寄存器中相应位被置为1,即首先在源未决寄存器中做登记,因此该寄存器记录了哪个中断源的请求在等待处理。
注意SRCPND寄存器的每一位由中断源自动设置,而不管中断屏蔽寄存器中对应的位是否被屏蔽,此外,SRCPND寄存器也不受中断控制器的优先级逻辑影响。
当多个中断源提出中断请求后,SRCPND寄存器中相应位均被置为1,然后裁决逻辑基于优先级寄存器来进行处理,选中优先级最高的中断请求,对中断未决寄存器中相应的位设置为1。
注意:INTPND寄存器中只有一位可以被设置为1,如果该中断被屏蔽,SRCPND寄存器中相对应的位被设置为1,但不会导致INTPND寄存器中相应位也被设置为1,SRCPND寄存器是可读可写的,在某个特定中断源的中断服务程序中,SRCPND寄存器的相应位必须被清除,从而保证能收到同一中断源的下一次中断请求,如果从中断服务程序返回时没有清除相应的未决位,中断控制器会误以为该中断源产生了另一个中断请求,换句话说,如果SRCPND寄存器的某位始终设置为1,则被认为始终有一个与该位相对应的中断源,即一个有效的中断请求等待处理,何时进行清除相应的未决位取决于用户需求,如果想在中断服务程序中,再收到相同的中断源提出的另一个有效的中断请求,则应该首先清除相应的未决位,用户可以通过写数据“1”到SRCPND寄存器来清除相应的未决位,数据位为“1”表示该位置的未决位将被清除,而0表示该位置的未决位保持不变。
———————————————————————————————————————————————————前几天把外部中断基本搞好了,但对几个中断寄存器的具体含义和区别不是很了解。
S3C2440按键中断LED控制(详细注解)

按键与LED灯,四个中断控制四个灯LED引脚连接按键引脚连接://===================================================================== =// 开发板:GT2440// 工程名称:KEY_EINT// 功能描述:外部中断0 2 11 19 控制四个LED小灯//===================================================================== =/******************************************************************************4 个用户按键四个输入引脚:EINT0 -----( GPF0 )----INPUT---K1EINT2 -----( GPF2 )----INPUT---K2EINT11 -----( GPG3 )----INPUT---K3EINT19 -----( GPG11 )----INPUT---K4******************************************************************************/ #include "def.h"#include "2440addr.h"#include "2440lib.h"#include "string.h"#include "uart.h"#define LED1ON 0xFDE //LED1点亮值为0x7DE(低电平点亮)#define LED2ON 0xFBE#define LED3ON 0xF7E#define LED4ON 0xEFE#define LEDOFF 0xFFF //LED熄灭值为0xFFFvoid __irq EintHandler0(void);void __irq EintHandler2(void);void __irq EintHandler8_23(void);void Main(void){memcpy((unsigned char *)0x0,(unsigned char *)0x30000000,0x1000);SetSysFclk(FCLK_400M); //设置系统时钟400MChangeClockDivider(2, 1); //设置分频1:4:8CalcBusClk(); //计算总线频Uart_Select(0);Uart_Init(0,115200);Uart_Printf("KEY EINT TEST\n");Uart_Printf("Use Eint 0,2,11,19 falling edge\n");rGPBCON = (rGPBCON | 0xFFFFFFF) & 0xFFFd57FC; //GPB5--GPB8设置为output rGPBUP = rGPBUP & 0xFE1F; //使能GPB5 6 7 8上拉电阻rGPBDAT = 0x7FE; //GPB5 6 7 8位初始化为1/***********************************************************//GPF0 GPF2设置为EINT[0],EINT[2] 10 = EINT[2] 10 = EINT[0]//设置GPGCON的3,11为中断功能,分别对应EINT[11] EINT[19]*************************************************************/rGPFCON = (rGPFCON|0xFFFF)&0xFFFFFFEE;rGPGCON = (rGPGCON|0xFFFFFFFF)&0xFFBFFFBF;/*************************************************************** START:外部中断控制寄存器3位一个设置触发沿, 设置外部中断0 ,2下降沿触发外部中断控制寄存器3位设置一个触发沿, 设置外部中断11下降沿触发外部中断控制寄存器3位设置一个触发沿, 设置外部中断19下降沿触发01x = 下降沿触发*****************************************************************/ rEXTINT0 &= ~(7<<0 | 7<<8 );rEXTINT0 |= (2<<0 | 2<<8) ;rEXTINT1 &= ~(7<<12 );rEXTINT1 |= (2<<12) ;rEXTINT2 &= ~(7<<12 );rEXTINT2 |= (2<<12) ;/*************************************************************** END*****************************************************************//********************************************************//外部中断0~3保留为0 不用使能EINTPEND和EINTMASK rEINTPEND |= (1<<0|1<<2); //clear eint 4 rEINTMASK &= ~(1<<0|1<<2); //enable eint************************************************************//********************************************************//外部中断11,19需要对EINTPEND(外部中断挂起寄存器)清零并对EINTMASK(外部中断屏蔽寄存器)清零使能EINTPEND写1清零使能中断,EINTMASK清零使能中断************************************************************/ rEINTPEND |= (1<<11|1<<19);rEINTMASK &= ~(1<<11|1<<19);/***********************************************************清源挂起(SRCPND)寄存器和中断挂起(INTPND)寄存器,可以直接操作寄存器这两个函数在2440addr.h中定义*************************************************************/ ClearPending(BIT_EINT0);ClearPending(BIT_EINT2);ClearPending(BIT_EINT8_23);/***********************************************************pISR_EINT0,2中断的入口地址,定义在2440addr.inc中2440addr.inc文件内定义了用于汇编的s3c2440寄存器变量和地址*************************************************************/ pISR_EINT0 =(unsigned)EintHandler0;pISR_EINT2 =(unsigned)EintHandler2;pISR_EINT8_23 =(unsigned)EintHandler8_23;/*********************************************************** 使能或禁止中断,这是个宏定义,其原型为rINTMSK &= ~(bit)这里的操作就是取消了屏蔽,中断就开始了*************************************************************/ EnableIrq(BIT_EINT0);EnableIrq(BIT_EINT2);EnableIrq(BIT_EINT8_23);while(1);}//外部中断0,服务函数void __irq EintHandler0(void){if(rINTPND==BIT_EINT0){ClearPending(BIT_EINT0);Uart_Printf("KEY To LED1 ON \n");rGPBDAT = LED1ON;Delay(500);rGPBDAT = LEDOFF;}}//外部中断2,服务函数void __irq EintHandler2(void){if(rINTPND==BIT_EINT2){ClearPending(BIT_EINT2);Uart_Printf("KEY To LED2 ON \n");rGPBDAT = LED2ON;Delay(500);rGPBDAT = LEDOFF;}}//外部中断11,19服务函数void __irq EintHandler8_23(void){if(rINTPND==BIT_EINT8_23){ClearPending(BIT_EINT8_23);if(rEINTPEND&(1<<11)){Uart_Printf("KEY To LED3 ON \n");rGPBDAT = LED3ON;Delay(500);rGPBDAT = LEDOFF;rEINTPEND |= 1<< 11;//写1清零该位}if(rEINTPEND&(1<<19)){Uart_Printf("KEY To LED4 ON \n");rGPBDAT = LED4ON;Delay(500);rGPBDAT = LEDOFF;rEINTPEND |= 1<< 19;//写1清零该位}}}。
S3C2440的中断控制

1.3.中断的作用
中断在系统中具有十分重要的作用,应该说整个系统都是依靠中断驱动起来的,中断的 主要作用如下:
1) CPU 与外部设备并行工作 图 9.1 是 CPU 与一台外部设备并行工作的时间关系图。现行程序和中断服务程序都是在 同一个 CPU 上执行的,因此,他们必须串行执行。但是,外部设备工作与 CPU 执行现行程序 或执行中断服务程序可以同时进行,使各自的效率得到充分发挥。
ARM 体系结构与编程参考资料 V1.01
S3C2440 的中断控制
1. 中断体系结构
1.1.概述
CPU 在正常执行程序的过程中,CPU 运行过程中,突然发生了一些不可预期的事件,比 如某个按键按下、串口收到新数据、USB 接口插入设备。但是 CPU 如何获得这些信息?主要 有以下两种方法: � 查询方式:程序循环查询各个设备的状态并作出相应的反应。这种方式显现简单,常用
了。 采用中断方式,当出现例外事件时,就向 CPU 发出中断服务请求,CPU 可以立即停止执
行现行程序,及时处理这些例外事件,避免发生计算错误,或造成更大的损失。
3) 实现实时处理 在实时控制系统中,处理机必须及时响应外部请求,及时处理,否则,可能丢失数据或 造成无法弥补的损失。例如,在过程控制中,当出现温度过高、压力过大的情况时,处理机 只有通过中断系统才能及时响应并给予处理。
运行时间
图 9.1 CPU 与外部设备并行工作的时间关系
处理器 外设设备
系统程序
中断响应
中断返回
中断处理
系统程序
中断响应
中断返回
中断处理
中断请求
中断请求
正常工作
正常工作
正常工作
当 CPU 在执行现行程序中启动外部设备之后,不需要象程序控制方式那样反复查询外部 设备的状态,而能够与外部设备并行工作。当外部设备的数据准备就绪后,主动向 CPU 发出 中断请求。CPU 接到外部设备的中断请求后,如果没有更加紧急的任务(如 DMA 服务等), 就暂停正在执行的现行程序,转去执行中断服务程序,为外部设备服务。当中断服务完成之 后,再返回到原先的现行程序中继续执行。
ARM9(S3C2440)之一中断系统理论知识

一 ARM9(S3C2440)的中断系统——理论知识转载自:骨Zi里德骄傲概述S3C2440A 中的中断控制器接受来自60 个中断源的请求。
提供这些中断源的是内部外设,如DMA 控制器、UART、IIC 等等。
在这些中断源中,UARTn、AC97 和EINTn 中断对于中断控制器而言是“或”关系。
当从内部外设和外部中断请求引脚收到多个中断请求时,中断控制器在仲裁步骤后请求ARM920T 内核的FIQ或IRQ。
仲裁步骤由硬件优先级逻辑决定并且写入结果到帮助用户通告是各种中断源中的哪个中断发生了的中断挂起寄存器中中断控制器操作程序状态寄存器(PSR)的F 位和I 位如果ARM920T CPU 中的PSR 的F 位被置位为1,CPU 不会接受来自中断控制器的快中断请求(FIQ)。
同样的如果PSR 的I 位被置位为1,CPU 不会接受来自中断控制器的中断请求(IRQ)。
因此,中断控制器可以通过清除PSR 的F 位和I 位为0 并且设置INTMSK 的相应位为0 来接收中断。
中断模式ARM920T 有两种中断模式的类型:FIQ 或IRQ。
所有中断源在中断请求时决定使用哪种类型。
中断挂起寄存器S3C2440A 有两个中断挂起寄存器:源挂起寄存器(SRCPND)和中断挂起寄存器(INTPND)。
这些挂起寄存器表明一个中断请求是否为挂起。
当中断源请求中断服务,SRCPND 寄存器的相应位被置位为1,并且同时在仲裁步骤后INTPND 寄存器仅有1 位自动置位为1。
如果屏蔽了中断,则SRCPND 寄存器的相应位被置位为1。
这并不会引起INTPND 寄存器的位的改变。
当INTPND 寄存器的挂起位为置位,每当I 标志或F 标志被清除为0 中断服务程序将开始。
SRCPND 和INTPND 寄存器可以被读取和写入,因此服务程序必须首先通过写1 到SRCPND寄存器的相应位来清除挂起状态并且通过相同方法来清除INTPND 寄存器中挂起状态。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中断详解
1、S3C2440官方手册最权威:
手册是最芯片IP开发者最直接的描述,最准确;但对英文阅读能力要求高、因详细而繁杂;适合参考和深入研究;
另外参考网上相关短文较容易入门,并短文是有套路的:基本是围绕几个较优秀的文章(优秀短文要多研读几遍理解透作者的每个心思)。
2、支持60个中断源:
S3C2440中断控制器总共支持60个中断源(内部外设和外部管脚):详细数下表中Descriptions中的中断源个数正好60;
子中断源分解如下:
注:INT_LCD也有两个中断但没有包含在子中断源寄存器中
3、一种中断源分类方法:
1、独立的外部中断源(EINT0-EINT3):4个;
2、合并的外部中断源(EINT4-EINT23):20个,合并后对应EINT4_7和EINT8_23;
注意:对应的相关寄存器在IO模块中,手册中的做法有点特殊;
3、带子中断的内部中断源:15个中断源,体现为6个bit(INT_WDT_AC97/ INT_CAM/ INT_ADC/ INT_UART2/ INT_UART1/ INT_UART0);
4、不带子中断的内部中断源:21个;
注意:INT_LCD实际对应两个中断源但是没有作为带子中断的内部中断源(如下图手册中有提到,TMD隐蔽!);
综上理解中断过程可以总结为:
4、中断优先级解析:
优秀的SOC对外设中断的处理都比较用心,基本能照顾到用户的各种场景,和LPC2292以及作者工作期间参与开发的一款SOC相比,作者经历到的三款SOC对中断的处理各有千秋(原谅不细说,因为没有必要);
可以总结为易用和特性的平衡,如果极特殊的场景下的实时性得不到满足,那就换个SOC 呗!没有必要使用一款SOC打遍天下,也不可能,而且厂家也没有强迫你呀!
言归正传:
S3C2440A支持60种中断,多个硬件可能同时产生中断请求,由于CPU只能处理一个中断,中断控制器怎么选择出一个最佳的中断,交给ARM内核进行处理呢?中断控制器采用优先级仲裁比较的方式进行选择,找出优先级最高的中断源。
中断控制器将60种中断源分成7组,如下图所示,它类似体育赛事里的比赛方式,所有参赛选手在小组赛PK,选择出小组赛最优秀选手,然后进入决赛阶段和其它小组最优先选择再PK,最后优胜者就是总冠军。
其中ARBITER0~ARBITER5为“小组赛”阶段,中断源信号在各自小组里进行优先级仲裁,选择出最高优先级中断信号,每小组选出的中断信号送到ARBITER6,也就是决赛阶段,选择出最高优先级中断信号,交给ARM内核。
中断信号在7个分组里PK时的优先级是可编程的,通过PRIORITY寄存器进行优先级设置。
如下表(只列出PRIORITY寄存器部分位):
表3-6 中断优先级控制寄存器(PRIORITY)
如果不是极特殊场景要求,我们就让这套机制留着三星自己的开发人员慢慢研究吧!
我们使用默认模式即可!
5、中断服务函数的入口:
重点说下920T内核外中断控制器对各种中断的入口函数处理,如果读者对X86保护模式程序员模型熟悉的话,2440的机制和其有异曲同工之妙!
支持定义的总入口,根据不同中断的编号偏移取得对应的中断服务函数入口。
分享下作者中断函数管理机制:
irq_handler irq_table[IRQ_HANDLE_SIZE];
即使用一个全局变量保存32个向量,根据INTOFFSET寄存器的中断号计算偏移取得入口地址;
这种机制比官网提供的各个中断有固定地址的机制有较大的灵活性,另外要注意Cache一致性的问题(如果遇到bug就是一个隐蔽性很强的bug):注册了中断服务函数就要flushcache。
6、中断模式:
FIQ模式业内认为是鸡肋,就像thumb模式这个大鸡肋一样!
总之一句话:不管、不问、任他去!不要用arm的错误惩罚自己!。