Chinaunix首页 | 论坛 | 博客
  • 博客访问: 366556
  • 博文数量: 135
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 599
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-19 21:10
文章分类
文章存档

2014年(3)

2013年(79)

2012年(53)

分类: 嵌入式

2013-08-28 22:12:17

         
                    OK6410中断分析
       

1:当异常发生时硬件自动处理的事情有:

(1):切换到异常处理模式,比如IRQ

(2):把当前模式下的cpsr保存到异常模式下的spsr

(3):使用异常模式的R13R14

(4):把发生异常模式时的下一条指令保存lr寄存器中。

(5):跳转到异常模式处理的地址。

2:当异常发生时软件需要做的事情:

(1):保护现场,在保护现场前先执行sub lr, lr, #4,因为arm处理器在执行每条指令前先判断当前是否有异常发生,若有则去处理异常,当前指令并没有执行;而当异常发生时,硬件会自动把下一条指令保存到lr中,但是异常处理完返回时是需要去执行发生异常导致没执行的指令,所以lr必须减4

(2):跳转中断处理入口地址执行。

(3):恢复现场

3:处理异常需要做的一些初始化:

(1):设置源头,触发方式

(2):使能中断

(3):使能总中断

(4):ok6410开发板的按键中断为例:

1):通过看ok6410的原理图,按键key1~key4接入的GPIO管脚为GPION0~GPION3,所以首先设置GPION0~GPION3的管脚功能EXT_INT(GPNCON)

2):GPION0~GPION3管脚接电源默认输入高电平,当有按键按下时相当于直接接地即低电平。需要设置触发方式:低电平触发,下降沿触发或是上升沿触发。(EINT0CON)

3):中断过滤功能(EINT0FLTCON0 )这里设置滤波方式,可以去毛刺。

4):使能中断(EINT0MASK ):写零使能中断,写1禁止中断。

5):检查是否发生中断(EINT0PEND ),当被设置为1时表示有bit相对应的中断发生,

写入1清除中断。

6):VIC中断向量:

7):VICXVECTADDR,设置中断处理程序的地址(6410共有64个这样的寄存器)

8):VICXADDRESS,矢量地址寄存器,写入任意数据清除中断

9):VICxINTENABLE,使能GPIO传过来的中断信号。


    下面贴上源代码,在ok6410上调试通过:按键按下触发中断,key1对应led1,把led1对应的gpio管脚取反,所以看到的效果是:第一次按下led1被点亮,
    第二次按下led1熄灭,第三次按下led1又点亮,第四次按下led1熄灭。总共有4个按键,keyn对应ledn。
       
.global _start

#define GPMCON 0x7f008820
#define GPMDAT 0x7f008824
#define GPNCON 0x7f008830
#define GPNDAT 0x7f008834

#define EINT0CON  0x7f008900
#define EINT0FLTCON0 0x7f008910
#define EINT0MASK 0x7f008920
#define EINT0PEND 0x7f008924

#define VIC0VECTADDR_0  0x71200100
#define VIC0INTENABLE 0x71200010
#define VIC0ADDRESS 0x71200F00


_start:
 stmfd sp!, {r0-r12, lr}
 
 //enable vic port
        mrc p15,0,r0,c1,c0,0
        orr r0,r0,#(1 << 24)
        mcr p15,0,r0,c1,c0,0
 
 @svc -> irq
 mrs r0, cpsr
 bic r0, r0, #0x1f
 orr r0, r0, #0x12
 msr cpsr, r0
 @set irq stack
 mov sp, #0x2000
 @irq -> svc
 bic r0, r0, #0x1f
 orr r0, r0, #0x13
 msr cpsr, r0
 @enable I(irq)
 bic r0, r0, #(1 << 7)
 msr cpsr, r0

 bl gpio_led_init
 bl irq_init
 bl vic_init
 @return 
 ldmfd sp!, {r0-r12, pc}

gpio_led_init:
 ldr r0, =GPMCON
 ldr r1, =0x1111 @output
 str r1, [r0]
 
 ldr r0, =GPMDAT
 mov r1, #0xf
 str r1, [r0] @all led off
 
 mov pc, lr

irq_init:
 ldr r0, =GPNCON
 ldr r1, =0xaa   @gpiopin for EXT_INT fun
 str r1, [r0]
 
 ldr r0, =EINT0CON
 mov r1, #0x22  @falling trigger
 str r1, [r0]    
 
 ldr r0, =EINT0FLTCON0
 ldr r1, =0xffff @digital filter
 str r1, [r0]

 ldr r0, =EINT0MASK
 ldr r1, [r0]
 bic r1, r1, #0xf @enable irq
 str r1, [r0]

 mov pc, lr

vic_init:
 ldr r0, =VIC0VECTADDR_0
 ldr r1, =interrupt @irq_isr function
 str r1, [r0]

 ldr r0, =VIC0INTENABLE
 ldr r1, [r0]
 orr r1, r1, #0x1  @enable vic0
 str r1, [r0]
 
 ldr r0, =VIC0ADDRESS
 mov r1, #0   @clean irq
 str r1, [r0]
 
 mov pc, lr
 
interrupt:
 sub lr, lr, #4
 stmfd sp!, {r0-r12, lr}
 bl irq_isr
 ldmfd sp!, {r0-r12, pc}^

irq_isr:
 ldr r0, =GPMDAT
 ldr r1, [r0]
 ldr r2, =EINT0PEND  @get irq source
 ldr r3, [r2]
 mov r4, r3
 @judge which irq occur
 ands r3, r3, #(1 << 0)
 bne key1_occur
 mov r3, r4
 ands r3, r3, #(1 << 1)
 bne key2_occur
 mov r3, r4
 ands r3, r3, #(1 << 2)
 bne key3_occur
 mov r3, r4
 ands r3, r3, #(1 << 3)
 bne key4_occur
 b   isr_out
 
 @irq_isr
key1_occur:
 eor r1, r1, #(1 << 0)
 str r1, [r0]
 b isr_out
key2_occur:
 eor r1, r1, #(1 << 1)
 str r1, [r0]
 b isr_out
key3_occur:
 eor r1, r1, #(1 << 2)
 str r1, [r0]
 b isr_out
key4_occur:
 eor r1, r1, #(1 << 3)
 str r1, [r0]
 b isr_out
 
isr_out:
 ldr r0, =EINT0PEND
 ldr r1, [r0]
 str r1, [r0] @clean EINT0PEND bit
 ldr r0, =VIC0ADDRESS
 mov r1, #0 @clean VIC0ADDRESS
 str r1, [r0]
 mov pc, lr


    

阅读(1999) | 评论(0) | 转发(0) |
0

上一篇:start_armboot分析

下一篇:mips 寄存器理解

给主人留下些什么吧!~~