硬件平台:JZ2440
head.s --> 启动文件,设置异常向量表
init.c --> 初始化中断
interrupt.c --> 中断处理程序
s3c2440.h --> 寄存器映射
head.s 源码:
.extern main .text .global _start _start: @ 异常向量表 @ 0x00 复位 b Reset @ 0x04 指令未定义 Undefine_instruct: b Undefine_instruct @ 0x08 软件中断 Software_interrupt: b Software_interrupt @ 0x0c 预取指中断 Prefetch_abort: b Prefetch_abort @ 0x10 数据访问中断 Data_abort: b Data_abort @ 0x14 保留 @ 0x18 外部访问中断 b Handle_irq @ 0x1c 快速中断 Fiq: b Fiq Reset: ldr sp,=4096 @ 复位自动进入超级用户模式 bl disable_watch_dog msr cpsr_c,#0xd2 @ 进入中断模式 ldr sp,=3072 msr cpsr_c,#0xd3 @ 进入超级用户模式 ldr sp,=4096 bl led_init bl interrupt_init msr cpsr_c,#0x5f @ 开中断,并进入系统模式 ldr lr,=loop_main ldr pc,=main loop_main: b loop_main Handle_irq: sub lr,lr,#4 stmdb sp!,{r0-r12,lr} ldr lr,=eint_return ldr pc,=eint_interrupt eint_return: ldmia sp!,{r0-r12,pc}^
init.c源码:
#include"s3c2440.h" /* * LED1,LED2,LED4对应GPF4、GPF5、GPF6 */ #define GPF4_out (1<<(4*2)) #define GPF5_out (1<<(5*2)) #define GPF6_out (1<<(6*2)) #define GPF4_msk (3<<(4*2)) #define GPF5_msk (3<<(5*2)) #define GPF6_msk (3<<(6*2)) /* * S2,S3,S4对应GPF0、GPF2、GPG3 */ #define GPF0_eint (0x2<<(0*2)) #define GPF2_eint (0x2<<(2*2)) #define GPG3_eint (0x2<<(3*2)) #define GPF0_msk (3<<(0*2)) #define GPF2_msk (3<<(2*2)) #define GPG3_msk (3<<(3*2)) void disable_watch_dog(void) { WTCON = 0; } void led_init(void) { // LED1,LED2,LED4对应的3根引脚设为输出 GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk); GPFCON |= GPF4_out | GPF5_out | GPF6_out; } void interrupt_init(void) { // S2,S3对应的2根引脚设为中断引脚 EINT0,ENT2 GPFCON &= ~(GPF0_msk | GPF2_msk); GPFCON |= GPF0_eint | GPF2_eint; // S4对应的引脚设为中断引脚EINT11 GPGCON &= ~GPG3_msk; GPGCON |= GPG3_eint; EINTMASK &= (~(1<<11)); INTMSK &= (~(1<<0))&(~(1<<2))&(~(1<<5)); PRIORITY = (PRIORITY&((~0x01) | (0x3 << 7))) | (0x0 << 7); }
interrupt.c 源码:
#include"s3c2440.h" void eint_interrupt(void) { unsigned long offset = INTOFFSET; switch (offset) { case 0: { GPFDAT |= (0x7<<4); GPFDAT &= ~(1<<4); break; } case 2: { GPFDAT |= (0x7<<4); GPFDAT &= ~(1<<5); break; } case 5: { GPFDAT |= (0x7<<4); GPFDAT &= ~(1 << 6); break; } defult:break; } if (offset == 5) EINTPEND = (1 << 11); SRCPND = 1 << offset; INTPND = 1 << offset; }
main.c 源码:
int main(void) { while (1); return 0; }
s3c2440.h 源码:
#ifndef _S3C2440_H_ #define _S3C2440_H_ //看门狗 #define WTCON (*(unsigned long *)0x53000000) //GPIO #define GPFCON (*(unsigned long *)0x56000050) #define GPFDAT (*(unsigned long *)0x56000054) #define GPFUP (*(unsigned long *)0x56000058) #define GPGCON (*(unsigned long *)0x56000060) #define GPGDAT (*(unsigned long *)0x56000064) #define GPGUP (*(unsigned long *)0x56000068) //interrupt #define INTMSK (*(unsigned long *)0x4a000008) #define PRIORITY (*(unsigned long *)0x4a00000c) #define SRCPND (*(unsigned long *)0x4a000000) #define INTPND (*(unsigned long *)0x4a000010) #define INTOFFSET (*(unsigned long *)0x4a000014) #define EINTMASK (*(unsigned long *)0x560000a4) #define EINTPEND (*(unsigned long *)0x560000a8) #endif
编译的Makefile:
objs:=head.o init.o main.o interrupt.o interrupt.bin:$(objs) arm-linux-ld -Ttext 0x00000000 -o interrupt_elf $^ arm-linux-objcopy -O binary -S interrupt_elf $@ arm-linux-objdump -D -m arm interrupt_elf > interrupt.dis %.o:%.c arm-linux-gcc -o $@ -c $< %.o:%.s arm-linux-gcc -o $@ -c $< clean: rm -f *.o *.dis *.bin interrupt_elf