如果想弄懂看门狗定时器中断,要掌握下面两个知识点:
1懂寄存器
CortexA9采用的是ARM官方规定的中断处理机制
有两大类寄存器决定了中断工作状态
1)exynos4412特有的寄存器(在第26章)
2)CortexA9规定的工作寄存器(在第9章和第10章)
2懂中断处理过程
1)Arm启动先执行一段启动代码(),这段代码是用汇编写的
2)然后,汇编代码再执行到c的main函数
讲解
.text
.global_start@@@@_start是一个全局标号(表示在其他函数可以调用_start)
_start:@@@@通常被指定为0x00000000地址
breset@@@@此段代码放在0x00000000地址处,命令功能是跳转到reset处去执行
ldrpc,_undefined_instruction
ldrpc,_software_interrupt
ldrpc,_prefetch_abort
ldrpc,_data_abort
ldrpc,_not_used
ldrpc,_irq@@@@将_irq地址处的指令地址给PC,相当于一条跳转命令,这条指令回放在0x00000018处
ldrpc,_fiq
_undefined_instruction:.word_undefined_instruction
_software_interrupt:.word_software_interrupt
_prefetch_abort:.word_prefetch_abort
_data_abort:.word_data_abort
_not_used:.word_not_used
_irq:.wordirq_handler@@@@.word是一条伪指令,相当于定义一个4字节的变量_irq,值为irq_handler
@@@@等价于int_irq=irq_handler
_fiq:.word_fiq
@@@@伪指令:不是一条实际的汇编指令,变量定义,宏定义,数组定义
reset:
@@@@初始化协处理器
ldrr0,=0x40008000
mcrp15,0,r0,c12,c0,0@VectorBaseAddressRegister
@@@@设置cpsr的值,为0xd3
mrsr0,cpsr
bicr0,r0,0xd3@@@@0xd311010011禁止FIQ,IRQ,处于ARM状态,模式为管理模式SVC
msrcpsr,r0@Enablesvcmodeofcpu
init_stack:@@@@初始化堆栈,svc,irq,fiq.每种模式的堆栈大小为512字节
ldrr0,stacktop/*getstacktoppointer*/
/********svcmodestack********/
movsp,r0
subr0,0xd2
movsp,r0
subr0,0xd1
movsp,r0
subr0,0xd7
movsp,r0
subr0,0xdb
movsp,r0
subr0,0x10
movsp,r0/*1024byteforusermodeofstack*/
@@@此处可以添加自己的初始化代码
bmain@@@@跳转到main函数,不会回来了
.align4
/****swi_interrupthandler****/
/****irq_handler****/
irq_handler:@@@@一旦IRQ中断会跳转到这
sublr,lr,include
*@briefIRQInterruptServiceRoutineprogrambody
*@param[in]None
*@returnNone
intflag=0;
voiddo_irq(void)
{
intirq_num;
irq_num=();//获取中断编号
printf("\n*******WDTinterrupt!!********\n");
if(flag==0)
{
//点亮
flag=1;
}
else
{
//点灭
flag=0;
}
//换成点亮或点灭LED3GPX1_0
=1;//清exynos4412中断标志位
//ofinterrupt
=(~(0x1FF))|irq_num;//清cpu0中断标志位
}
voidwdt_init()
{
=6000;//initialvalue,,延时大概有两秒
=6000;//initialvalue,,延时大概有两秒
=0xff8|15|33|12;
}
voidmydelay_ms(inttime)
{
inti,j;
while(time--)
{
for(i=0;i5;i++)
for(j=0;j514;j++);
}
}
intmain(void)
{
/*
*GICinterruptcontroller:
**/
//EnablesthecorrespondinginterruptSPI43,WDT
|=111;//ICDISER2:spi32[bit0]~63[bit31],43-32=[bit11]
|=0x1;//Globalenableforsignalingofinterrupts
=0xFF;//
ICDDCR=1;//Bit1:GICmonitorstheperipheralinterruptsignalsand
//forwardspinginterruptstotheCPUinterfaces2
//ICDIPTR18:SPI40~SPI43;SPI43interruptsaresenttoprocessor0
=(~(0xFF24))|124;
wdt_init();
printf("\n****************WDTInterrupttest!!***************\n");
while(1)
{
mydelay_ms(200);
mydelay_ms(200);
printf("working\n");
}
return0;
}