您的位置:首页 > 其它

jz2440平台中断测试及分析

2015-03-18 17:32 225 查看
head.S文件及源码分析:

.extern main

.text

.global _start

_start:

b Reset

HandleUndef: @0x04未定义指令中止模式的向量地址

b HandleUndef

HandleSWI: @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式

b HandleSWI

HandlePrefetchAbort:@ 0x0c: 指令预取终止导致的异常的向量地址

b HandlePrefetchAbort

HandleDataAbort:@ 0x10: 数据访问终止导致的异常的向量地址

b HandleDataAbort

HandleNotUsed: @ 0x14: 保留

b HandleNotUsed

b HandleIRQ @ 0x18: 中断模式的向量地址

HandleFIQ: @ 0x1c: 快中断模式的向量地址

b HandleFIQ

Reset:

ldr sp,=4096

bl disable_watch_dog

msr cpsr_c,#0xd2

ldr sp,=3072

msr cpsr_c,#0xd3

ldr sp,=4096

bl init_led

bl init_irq

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} @arm中stm指令 用于将寄存器列表所指示的多个寄存器中的值存入由基址寄存器指示的一片@连续存储器中。db表示每次传送前地址减 。这条指令就将r0-r12和lr寄存器中的数值压入栈(中断模式下的sp)中

@”!“表示数据压入栈后,基址寄存器的值更新。

ldr lr,=int_return @给lr寄存器赋值int_return段的地址,是的下面调用中断服务函数的适合 返回地址是int_return函数

ldr pc,=EINT_Handle

int_return:

ldmia sp!,{r0-r12,pc}^ @arm中ldm指令用于从基址寄存器所指示的一片连续存储器中读取数据到寄存器列表所指示@的多个寄存器中 此条指令是将先前压入栈的寄存器的数据传入寄存器中,pc寄存器的值就是中断模式的向量地

@址。供下次中断使用。“^”表示还将SPSR复制到CPSR,同时还表示传入和传出的是用户模式下的寄存器而不是当@前模式下的寄存器。



init.c文件及分析:

#include"s3c2440.h"

void disable_watch_dog()

{

WTCON=0;

}

void init_led()

{

GPFCON &=~(GPF4_msk|GPF5_msk|GPF6_msk);

GPFCON |=GPF4_out|GPF5_out|GPF6_out;

}

void init_irq()

{

GPFCON &=~(GPF0_msk|GPF2_msk);

GPFCON |=GPF0_int|GPF2_int;



GPGCON &=~(GPG3_msk);

GPGCON |=GPG3_int;



EINTMASK &=~(1<<11);//外部中断屏蔽寄存器 写1清零 只有EINT11



SRCPND |=(1<<0)|(1<<2)|(1<<5);//中断源挂起寄存器写1清零



INTMOD &=~((0<<0)|(0<<2)|(0<<5));//中断模式寄存器 中断模式



PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;//将ARB_MODE0设置为0,及不反转

INTPND=0xFFFFFFFF;//中断挂起寄存器写1清零



INTMSK &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));//写零清零

}

int.c文件及分析:

#include"s3c2440.h"

void EINT_Handle()

{

unsigned long oft=INTOFFSET;//中断偏移寄存器 值表示对应的中断号

switch( oft )

{

// S2被按下

case 0:

{

GPFDAT |= (0x7<<4); // 所有LED熄灭

GPFDAT &= ~(1<<4); // LED1点亮

break;

}



// S3被按下

case 2:

{

GPFDAT |= (0x7<<4); // 所有LED熄灭

GPFDAT &= ~(1<<5); // LED2点亮

break;

}

// K4被按下

case 5:

{

GPFDAT |= (0x7<<4); // 所有LED熄灭

GPFDAT &= ~(1<<6); // LED4点亮

break;

}

default:

break;

}

if(oft==5)

{

EINTPEND=(1<<11); //写1清除外部中断挂起寄存器,在该例只有EINT11是的

}

SRCPND=1<<oft;//写1 清除中断源挂起寄存器

INTPND=1<<oft;//写1清除中断挂起寄存器

}

main文件及分析:

int main()

{

while(1);

return 0;

}//是一个死循环

Makefile文件及分析:

int.bin: head.S init.c int.c main.c

arm-linux-gcc -c -o head.o head.S //-c表示编译不连接 -o表示生成head.o文件

arm-linux-gcc -c -o init.o init.c

arm-linux-gcc -c -o int.o int.c

arm-linux-gcc -c -o main.o main.c

arm-linux-ld -Ttext 0x00000000 head.o init.o int.o main.o -o int_elf//指定代码段起始地址为0地址

arm-linux-objcopy -O binary -S int_elf int.bin //-O binary使用二级制格式输出文件 -S不从源文件复制重定位信息和符号到目标文件

arm-linux-objdump -D -m arm int_elf > int.dis //-D 进行反汇编-m arm 指定反汇编所指定的架构为arm 就会生成arm下的汇编

clean:

rm -f int.bin int_elf int.dis *.o


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: