以下裸机程序基于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启动。
来源:https://www.cnblogs.com/lknlfy/archive/2012/08/29/2662581.html