ARM汇编外部中断

主要是中断向量表的设置和现场保护。

调试比较久的原因:使用main: b main时调试发现,不能死循环,可能是main标签是保留的

1)在主程序中的步骤一般是:

1.关中断,并设置各主要模式的堆栈指针和容量

2写1清SRCPND,INTPND寄存器

3.配置INTMSK使能相应中断

4.开全局中断

3)中断服务程序中的流程是:

1.屏蔽中断(硬件自动关irq中断)

2.执行任务

3.写1清相应SRPND,INTPND等寄存器(可以利用SRPND=SRPND,INTPND来清零,防止出错)

4.把屏蔽的中断使能回来

5.返回

参考u-boot的start.S自己写了一个外部中断程序,mini2440的按键K1,按一下LED灭,再按一下LED亮......。硬件原理图:按键引脚对应GPIO是PG0,对应EINT8,而LED的引脚是PB8,被设计为低电平时灯亮。

.equ    NOINT,      0xc0  
.equ    DISABLE_IRQ,0x80
.equ    SYS_MOD,    0x1f
.equ    IRQ_MOD,    0x12
.equ	USR_MOD,    0x10

.equ    WTCON,    0x53000000

.equ    GPBCON,   0x56000010
.equ    GPBDAT,   0x56000014
.equ    GPBUP,    0x56000018

.equ    GPGCON,   0x56000060

.equ    EINTMASK, 0x560000a4  
.equ    EXTINT1,  0x5600008c 
.equ    EINTPEND, 0x560000a8  

.equ    INTMSK,   0x4A000008  
      
.equ    SRCPND,   0X4A000000  
.equ    INTPND,   0X4A000010  
  
.equ    USE_Stack, 4096
.equ    IRQ_Stack, 2048

.text
.code 32
.global _start
_start: 
	b reset
	ldr     pc, _undefined_instruction  
        ldr     pc, _software_interrupt  
        ldr 	pc, _prefetch_abort  
        ldr	pc, _data_abort  
        ldr 	pc, _not_used  
        ldr     pc, _irq 
        ldr     pc, _fiq


_undefined_instruction:     .word undefined_instruction  
_software_interrupt:        .word software_interrupt  
_prefetch_abort:            .word prefetch_abort  
_data_abort:                .word data_abort  
_not_used:                  .word not_used  
_irq:                       .word irq  
_fiq:                       .word fiq

.balignl 16,0xdeadbeef
reset:
	ldr r0,=WTCON
	mov r1,#0x0
	str r1,[r0] @关看门狗

	ldr r0,=GPBCON
	ldr r1,=0x10000
	str r1,[r0] @PB8输出

	ldr r0,=GPBDAT
	mov r1,#0x000
	str r1,[r0] @低电平

	msr cpsr_c,#(IRQ_MOD|NOINT)
	ldr sp,=IRQ_Stack
	msr cpsr_c,#(SYS_MOD|NOINT)
	ldr sp,=USE_Stack

 	ldr r0,=GPGCON
	mov r1,#0x02
	str r1,[r0] @使能外部中断8

	ldr r0,=EXTINT1
	mov r1,#0x03
	str r1,[r0] @下降沿触发

	ldr r0, =EINTPEND 
	ldr r1,=0x00fffff0
	str r1,[r0]@ 清EINTPEND,写1清零
	
	ldr r0,=EINTMASK
	ldr r1,=0xfffffeff
	str r1,[r0] @使能外部中断8,0为使能

	ldr r0, =SRCPND 
	ldr r1,=0xffffffff
	str r1,[r0]@ 清SRCPND,写1清零

	ldr r0, =INTPND 
	ldr r1,=0xffffffff 
	str r1,[r0]@ 清INTPND,写1清零

	ldr r0,=INTMSK
	ldr r1,=0xffffffdf
	str r1,[r0] @使能外部中断EINT8-23

	mrs r1, cpsr  
    	bic r1, r1, #DISABLE_IRQ
    	msr cpsr_c, r1 @开全局IRQ中断

loop:	b loop

irq_server:
	ldr r0, =EINTPEND
	ldr r1,[r0]
	tst r1,#0x100 @判断是否为EINT8
	beq not_handle 
	
        ldr r0,=GPBDAT
	ldr r1,[r0]
	tst r1,#0x100 @测试PB8当前是高电平还是低电平
	ldreq r1,=0x100
	movne r1,#0x0
	str r1,[r0]

not_handle:
	ldr r0, =EINTPEND 
	ldr r1,[r0] @ldr r1,=0x100
	str r1,[r0] @清EINTPEND

	ldr r0, =SRCPND 
	ldr r1,[r0] @ldr r1,=0x20
	str r1,[r0] @清SRCPND

	ldr r0, =INTPND 
	ldr r1,[r0] @ldr r1,=0x20
	str r1,[r0] @清INTPND

	mov pc,lr

undefined_instruction:  
            nop  
software_interrupt:  
            nop  
prefetch_abort:   
            nop  
data_abort:  
            nop  
not_used:  
            nop  
irq:  
    	sub     lr,lr,#4  
    	stmfd   sp!,{r0-r12,lr}  
    	bl irq_server  
    	ldmfd  sp!,{r0-r12,pc}^
fiq:  
            nop

链接脚本命名为“int.lds”:

    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 
    OUTPUT_ARCH(arm)
    ENTRY(_start)  
      
    SECTIONS{  
        . = 0x00000000;  
        .text : { 
            *(.text)   
        }  
      
        .data ALIGN(4): {  
            *(.data)  
        }  
      
        .bss ALIGN(4): {  
            *(.bss)  
        }  
    }  

Makefile是:

led_off.bin : led_off.S
	arm-linux-gcc -nostdlib -nostartfiles -g -c -o led_off.o led_off.S
	arm-linux-ld -Tint.lds led_off.o -o led_off_elf
	arm-linux-objcopy -O binary -S led_off_elf led_off.bin
clean:
	rm -f  led_off.bin led_off_elf *.o


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值