s3c2440中断体系

发布时间:2024-07-15  

一、S3C2440的中断系统

1.1 S3C2440的7种模式

用户模式(usr):ARM处理器正常的程序执行状态 快速中断模式(fiq):用于高速数据传输或通道处理 中断模式(irq):用于通用的中断处理 管理模式(svc):操作系统使用的保护模式 数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护 系统模式(sys):运行具有特权的操作系统任务 未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真 除用户模式外,其他6种工作模式都属于特权模式,大多数程序运行于用户模式,进入特权模式是为了处理中断、异常,或者访问被保护的系统资源。

s3c2440中断体系

s3c2440中断体系

1.2 CPSR(current program state register,当前程序状态寄存器)

s3c2440中断体系

s3c2440中断体系

s3c2440中断体系

s3c2440中断体系

代码语言:javascript

ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈

bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启

    

msr cpsr_c, #0xd2       @ 进入中断模式 0xd2=1101 0010ldr sp, =3072           @ 设置中断模式栈指针


msr cpsr_c, #0xd3       @ 进入管理模式 0xd3=1101 0011ldr sp, =4096           @ 设置管理模式栈指针,

                        @ 其实复位之后,CPU就处于管理模式,

                        @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略


1.3 S3C2440的中断过程

s3c2440中断体系

s3c2440中断体系

首先,当有中断请求时,SUBSRCPND或者SRCPND中的相应位会被置1 然后,根据SUBMASK和MASK寄存器的设置值进行相应的屏蔽,如果一个中断请求发生但被屏蔽了,中断信号传递停止 最后,根据MODE寄存器判断该中断源的模式,如果是快中断模式(系统只有一个中断源为快中断其他的都为普通中断)直接执行,如果是普通中断则跟其他普通中断角逐出一个优先级最高的送到INTPND寄存器

二、S3C2440中断寄存器

s3c2440的中断系统一共需要设置5个寄存器,中断源寄存器SRCPND、SUBSRCPND,中断模式寄存器INTMOD,中断屏蔽寄存器INTMASK、INTSUBMASK,中断优先级寄存器PRIORITY,中断待决寄存器INTPND

2.1 中断源寄存器

s3c2440支持60个中断源,部分是子中断源(比如串口接收中断、串口发送中断、串口错误中断都属于串口中断)

SRCPND中断源寄存器地址为0X4A000000,它一共32位,每一位都代表一个中断源,相应的中断置1就表示有中断请求,置0就表示无中断请求(中断的置1系统自动完成,清0需要用户手动)。

清0的方法就是向SRCPND或者SUBSRCPND的相应位写1即可,清0的位置由用户决定。如果在中断处理程序结束处清0,那么在执行中断程序过程中即便该中断源又有中断请求,程序也无法响应。如果中断处理程序的开始处清0,那么在执行中断处理程序的过程中该中断源又有中断请求程序也能响应。

SRCPND寄存器中每位代表的中断源如下:

s3c2440中断体系

s3c2440中断体系

SUBSRCPND子中断源寄存器地址为0X4A000018,每位代表的中断源如下:

s3c2440中断体系

s3c2440中断体系

2.2 中断模式寄存器

INTMOD中断模式寄存器的地址为0X4A000004,一共32位,每位代表的中断源和SRCPND中一致。如果置1则相应位的中断源就为快中断,否则就为普通中断。(32个中断源中只有一个能设为快中断)

2.3 中断屏蔽寄存器

INTMSK中断屏蔽寄存器的地址为0X4A000008,一共32位,每位代表的中断源和SRCPND中一致。如果置1则相应的中断源将不被响应,否则可以响应相应的中断源。(中断屏蔽不影响:有中断请求SRCPND相应位置1)

2.4 中断优先级寄存器

s3c2440优先级仲裁模块示意图如下:

s3c2440中断体系

s3c2440中断体系

s3c2440优先级逻辑由7个仲裁器构成。每个仲裁器中REQ0优先级最高,REQ5优先级最低。余下的REQ1、REQ2、REQ3、REQ4优先级则由ARB_MODE(1位)和ARB_SEL(2位)来决定。

仲裁器的ARB_SEL位和各输入信号优先级对应关系表

s3c2440中断体系

s3c2440中断体系

当某个仲裁器的ARB_MODE被设置为0时,它的ARB_SEL位是不会自动变化的,此时该仲裁器的输入引脚的优先级固定不变。(当然可以通过软件修改ARB_SEL的值来改变它们的优先级)当ARB_MODE的值设置为1时,ARB_SEL会随着已被服务的IRQx(x为1~4)值而自动改变。

中断优先级仲裁器的ARB_SEL变化规则

s3c2440中断体系

s3c2440中断体系

s3c2440的优先级寄存器PRIORITY 的位置为0x4A00000C,为32位,7组仲裁器,每组使用3位,共使用21位,其寄存器每位的分布如下:

s3c2440中断体系

s3c2440中断体系

2.5 中断待决寄存器

中断待决寄存器INTPND地址为0X4A000010,一共32位,每位代表的中断源和SRCPND中一致。如果相应位置1则中断请求被受理。同一时间只允许一个中断源被受理。(INTPND置1系统自动,清0用户手动,在SRCPND清0后才清除)

INTOFFSET中断偏移寄存器地址为 0X4A000014,一共32位,表示INTPND中的置1位的位序号(0~31),它在INTPND和SRCPND清0后自动清0。


三.中断实例程序


3.1 外部中断实例


代码语言:javascript


@初始化的代码                                                                

@ File:head.S

@ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数

@******************************************************************************       

.extern     main

.text 

.global _start 

_start:

@******************************************************************************       

@ 异常向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用

@******************************************************************************       

    b   Reset


@ 0x04: 未定义指令中止模式的向量地址

HandleUndef:

    b   HandleUndef 

 

@ 0x08: 管理模式的向量地址,通过SWI指令进入此模式

HandleSWI:

    b   HandleSWI


@ 0x0c: 指令预取终止导致的异常的向量地址

HandlePrefetchAbort:

    b   HandlePrefetchAbort


@ 0x10: 数据访问终止导致的异常的向量地址

HandleDataAbort:

    b   HandleDataAbort


@ 0x14: 保留

HandleNotUsed:

    b   HandleNotUsed


@ 0x18: 中断模式的向量地址

    b   HandleIRQ


@ 0x1c: 快中断模式的向量地址

HandleFIQ:

    b   HandleFIQ


Reset:                  

    ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈

    bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启

    

    msr cpsr_c, #0xd2       @ 进入中断模式

    ldr sp, =3072           @ 设置中断模式栈指针


    msr cpsr_c, #0xd3       @ 进入管理模式

    ldr sp, =4096           @ 设置管理模式栈指针,

                            @ 其实复位之后,CPU就处于管理模式,

                            @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略

    bl  init_led            @ 初始化LED的GPIO管脚

    bl  init_irq            @ 调用中断初始化函数,在init.c中

    msr cpsr_c, #0x53       @ 设置I-bit=0,开IRQ中断

    

    ldr lr, =halt_loop      @ 设置返回地址

    ldr pc, =main           @ 调用main函数

halt_loop:

    b   halt_loop


HandleIRQ:

    sub lr, lr, #4                  @ 计算返回地址

    stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器

                                    @ 注意,此时的sp是中断模式的sp

                                    @ 初始值是上面设置的3072

    

    ldr lr, =int_return             @ 设置调用ISR即EINT_Handle函数后的返回地址  

    ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中

int_return:

    ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr,此处将返回到主函数执行

代码语言:javascript


/*中断相关寄存器的初始化*/

#include "s3c24xx.h"


/*

 * LED1,LED2,LED4对应GPB5、GPB6、GPB7、GPB8

 */

#define GPB5_out (1<<(5*2))

#define GPB6_out (1<<(6*2))

#define GPB7_out (1<<(7*2))

#define GPB8_out (1<<(8*2))


#define GPB5_msk (3<<(5*2))

#define GPB6_msk (3<<(6*2))

#define GPB7_msk (3<<(7*2))

#define GPB8_msk (3<<(8*2))


/*

 * K1,K2,K3,K4对应GPF1、GPF4、GPF2、GPF0

 */

#define GPF0_int     (0x2<<(0*2))

#define GPF1_int     (0x2<<(1*2))

#define GPF2_int     (0x2<<(2*2))

#define GPF4_int     (0x2<<(4*2))


#define GPF0_msk    (3<<(0*2))

#define GPF1_msk    (3<<(1*2))

#define GPF2_msk    (3<<(2*2))

#define GPF4_msk    (3<<(4*2))


/*

 * 关闭WATCHDOG,否则CPU会不断重启

 */

void disable_watch_dog(void)

{

    WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可

}


void init_led(void)

{

// LED1,LED2,LED3,LED4对应的4根引脚设为输出

GPBCON &= ~(GPB5_msk | GPB6_msk | GPB7_msk | GPB8_msk);

GPBCON |= GPB5_out | GPB6_out | GPB7_out | GPB8_out;

}


/*

 * 初始化GPIO引脚为外部中断

 * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)

 */ 

void init_irq( )

{

// K1,K2,K3,K4对应的4根引脚设为中断功能

GPFCON &= ~(GPF0_msk | GPF1_msk | GPF2_msk | GPF4_msk);

GPFCON |= GPF0_int | GPF1_int | GPF2_int | GPF4_int;


    // 对于EINT4,需要在EINTMASK寄存器中使能它

    EINTMASK &= ~(1<<4);

            

    /*

     * 设定优先级:

     * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ2 > REQ3,即EINT0 > EINT1 > EINT2

     * 仲裁器1、6无需设置

     * 最终:

     * EINT0 > EINT1> EINT2 > EINT4 即K4 > K1 > K3 > K2

     */

    PRIORITY = (PRIORITY & ((~0x01) | ~(0x3<<7)));


    // EINT0、EINT1、EINT2、EINT4_7使能

    INTMSK   &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<4));

}

代码语言:javascript


/*中断处理函数*/

#include "s3c24xx.h"

void EINT_Handle()

{

    unsigned long oft = INTOFFSET;

    unsigned long val;

/*

* K1,K2,K3,K4对应GPF1、GPF4、GPF2、GPF0

*            即 EINT1, ETIN4, EINT2, EINT0

*            oft为 1, 4, 2, 0 (对应INTMSK寄存器)

*/  

    switch( oft )

    {

        // K1被按下

        case 1: 

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<5);      // LED1点亮

            break;

        }       

        // K2被按下

        case 4:

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<6);      // LED2点亮

            break;

        }

        // K3被按下

        case 2:

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<7);      // LED3点亮

            break;

        }

        // K4被按下

        case 0:

        {   

            GPBDAT |= (0xF<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<8);      // LED4点亮

            break;

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>