ARM裸机开发(二)中断编程

       以下裸机程序基于GT2440,编译器为arm-linux-gcc-4.4.3。

     程序布局:源代码由interrupt.S和led.c两个文件组成,interrupt负责初始化工作,led.c里定义了中断处理程序。

     程序流程:首先安装异常向量表,在复位异常里关闭看门狗,然后进入普通中断模式,设置普通中断的栈指针(为C语言写的中断处理程序做准备),接着设为特权模式,初始化中断(设置IO管脚,开启中断),最后CPU一直死循环等待外部中断触发。当外部中断到来时,先保护现场,跳到led.c里的handle_irp()函数,在该函数里将四个LED点亮,接着返回,最后恢复现场,返回到死循环。

 

interrupt.S:

 1 //寄存器物理地址宏定义
 2 #define WTCON  0x53000000
 3 
 4 #define GPFCON 0x56000050 
 5 #define nGPF_INT2 (0x02<<4)
 6 #define nGPF_INT0 (0x02<<0)
 7 #define EXINT0 0x56000088 
 8 
 9 #define SRCPND 0X4A000000 
10 #define INTMOD 0X4A000004 
11 #define INTMSK 0x4A000008
12 #define PRIORITY 0x4A00000C 
13 #define INTPND 0X4A000010 
14 #defind INTOFFSET 0x4A000014 
15 
16 
17 .section .text
18 .global _start
19 _start:
20 @异常向量表
21     b reset
22     b underfinded_instruction
23     b soft_interrupt
24     b abort_prefetch
25     b abort_data
26     b reserved
27     b irq
28     b fiq
29 
30 
31 @复位异常
32 reset:
33     bl disable_watchdog  @跳到关闭看门狗程序
34     msr cpsr_c,#0xd2  @进入普通中断模式
35     ldr sp,=3072     @设置栈指针
36     msr cpsr_c,#0xdf  @设为特权模式
37 
38     bl init_int      @跳到中断初始化程序
39 loop:
40     b loop   @死循环
41 
42     
43 @关闭看门狗
44 disable_watchdog:
45     ldr r0,=WTCON    
46     bic r1,r0,#0x20
47     str r1,[r0]
48 
49     mov pc,lr
50 
51     
52 @中断初始化
53 init_int:
54     @开启EXINT2
55     ldr r0,=INTMSK    
56     ldr r1,[r0]
57     bic r1,r1,#0x04
58     str r1,[r0]
59     @GPF2设为外部中断功能
60     ldr r0,=GPFCON
61     ldr r1,=nGPF_INT2
62     str r1,[r0]
63     @EXINT2下降沿触发中断
64     ldr r0,=EXINT0
65     mov r1,#0x0200
66     str r1,[r0]
67     msr cpsr_c,#0x5f    @打开cpu中断
68     
69     mov pc,lr
70 
71 
72 @普通中断异常入口
73 irq:
74     sub lr,lr,#4    @修正返回地址
75     stmdb sp!,{r0-r12,lr} @寄存器入栈
76     ldr lr,=int_return @设置中断处理程序返回地址
77     ldr pc,=handle_irq @跳到中断处理程序(led.c里)
78 int_return:
79     ldmia sp!,{r0-r12,pc}^ @中断异常返回,寄存器出栈和恢复cpsr寄存器
80 
81     
82 
83 underfinded_instruction:
84     b underfinded_instruction
85 soft_interrupt:
86     b soft_interrupt
87 abort_prefetch:
88         b abort_prefetch
89 abort_data:
90         b abort_data
91 reserved:
92         b reserved
93 fiq:
94     b fiq

led.c:

 1 #define GPBCON (*(volatile unsigned long *)0x56000010) 
 2 #define GPBDAT (*(volatile unsigned long *)0x56000014)
 3 #define GPBUP  (*(volatile unsigned long *)0x56000018)
 4 
 5 #define nGPB_OUTPUT ((1<<10)|(1<<12)|(1<<14)|(1<<16))
 6 
 7 #define SRCPND (*(volatile unsigned long *)0X4A000000)
 8 #define INTPND (*(volatile unsigned long *)0X4A000010)
 9 
10 void handle_irq()
11 {
12     GPBCON = nGPB_OUTPUT;//IO设为输出
13     GPBDAT = 0x0;//输出低电平
14 
15     //清中断源
16     SRCPND = 0x04;
17     INTPND = 0x04; 
18 }

Makefile:

1 interrupt.bin:
2     arm-linux-gcc -c -o interrupt.o interrupt.S
3     arm-linux-gcc -c -o led.o led.c
4     arm-linux-ld -Ttext 0x00000000 interrupt.o led.o -o interrupt_elf
5     arm-linux-objcopy -O binary -S interrupt_elf interrupt.bin
6     rm -f interrupt_elf interrupt.o led.o
7 
8 clean:
9     rm -f interrupt.bin

      执行make之后通过BIOS下载到nand flash,从nand flash启动。

 

posted @ 2012-08-29 19:33  lknlfy  阅读(1203)  评论(0编辑  收藏  举报