实现按键中断
文件:
head.S,main.c,out.lds,makefile
编译环境gcc-3.4.5-glibc-2.3.6
makefile
<span style="color:#000000;">out.bin : head.S main.c
arm-linux-gcc -c -o head.o head.S
arm-linux-gcc -c -o main.o main.c
arm-linux-ld -Tout.lds head.o main.o -o out_elf
arm-linux-objcopy -O binary -S out_elf out.bin
arm-linux-objdump -D -m arm out_elf > out.dis
#rm -f out.dis out_elf *.o
clean:
rm -f out.dis out.bin out_elf *.o</span>
head.S
<span style="color:#000000;">.text
.global _start
_start:
b Reset
HandleUndef:
b HandleUndef
HandleSWI:
b HandleSWI
HandlePrefetchAbort:
b HandlePrefetchAbort
HandleDataAbort:
b HandleDataAbort
HandleNotUsed:
b HandleNotUsed
b HandleIRQ
HandleFIQ:
b HandleFIQ
Reset:
ldr r0, =0x53000000
mov r1, #0x0
str r1, [r0] @disable watchdog
msr cpsr_c, #0xd2
ldr sp, =3072
msr cpsr_c, #0xd3
ldr sp, =1024*4 @set up stack,4K
msr cpsr_c, #0x53
ldr lr, =halt_loop
ldr pc, =main
halt_loop:
b halt_loop
HandleIRQ:
sub lr, lr, #4
stmdb sp!, {r0-r12,lr}
ldr lr, =int_return
ldr pc, =EINT_Handle
int_return:
ldmia sp!, { r0-r12,pc }^
</span>
main.c
<span style="color:#000000;">/*
led1 f4,led2 f5,led3 f6,int0 f0
*/
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPF0_IN (2<<(0*2))
#define GPF4_OUT (1<<(4*2))
#define GPF5_OUT (1<<(5*2))
#define GPF6_OUT (1<<(6*2))
#define GPF0_CON_MSK (3<<(0*2))
#define GPF4_CON_MSK (3<<(4*2))
#define GPF5_CON_MSK (3<<(5*2))
#define GPF6_CON_MSK (3<<(6*2))
#define GPF4_DAT_MSK (1<<(4))
#define GPF5_DAT_MSK (1<<(5))
#define GPF6_DAT_MSK (1<<(6))
#define SRCPND (*(volatile unsigned long *)0X4A000000)
#define INTMSK (*(volatile unsigned long *)0X4A000008)
#define PRIORITY (*(volatile unsigned long *)0x4A00000C)
#define INTPND (*(volatile unsigned long *)0X4A000010)
#define INTOFFSET (*(volatile unsigned long *)0x4A000014)
void init_eint0()
{
SRCPND=0x0;
INTMSK=0xfffffffe;
INTPND=0x0;
}
void led_set_out()
{
GPFCON&=~(GPF4_CON_MSK|GPF5_CON_MSK|GPF6_CON_MSK|GPF0_CON_MSK);
GPFCON|=GPF4_OUT|GPF5_OUT|GPF6_OUT|GPF0_IN;
GPFDAT&=~(GPF4_DAT_MSK);
GPFDAT&=~(GPF5_DAT_MSK);
GPFDAT&=~(GPF6_DAT_MSK);
GPFDAT|=(1<<4);
GPFDAT|=(1<<5);
GPFDAT|=(1<<6);
}
void led_reset(int ledn)
{
if(ledn==1)
{
GPFDAT|=(1<<4);
}
else if(ledn==2)
{
GPFDAT|=(1<<5);
}
else
{
GPFDAT|=(1<<6);
}
}
void led_set(int ledn)
{
if(ledn==1)
{
GPFDAT&=~(GPF4_DAT_MSK);
}
else if(ledn==2)
{
GPFDAT&=~(GPF5_DAT_MSK);
}
else
{
GPFDAT&=~(GPF6_DAT_MSK);
}
}
void EINT_Handle()
{
int i;
led_set(1);
for(i=0;i<30000;i++);
led_reset(1);
SRCPND=1<<INTOFFSET;
INTPND=1<<INTOFFSET;
}
int main()
{
int i;
led_set_out();
init_eint0();
while(1)
{
led_reset(3);
for(i=0;i<30000;i++);
led_set(3);
for(i=0;i<30000;i++);
}
return 0;
}
</span>
out.lds
SECTIONS {
. = 0x00;
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata)}
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}