mini2440+jlink+mkd 裸机按键中断调试心得体会(2013.11.17已更新)
2013-11-14 23:04
597 查看
开发板:友善之臂mini2440,仿真器:jlink v8,开发环境:RealView mdk 4.54
需要阅读的文档:S3C2440A_UserManual,mini2440开发手册,其他
实验目标:按下开发板上的key1,触发外部中断EINT8,开发板进入中断程序运行点亮或灭掉LED1
分析:
为了方便理解,我按照信号的走向,分为几个环节,逐个说明。
环节1.先说说,按下key1是如何触发外部中断信号。阅读mini2440的开发手册后发现key1是和s3c2440芯片上的GPG0管脚相连,这个IO口除了能作输入输出用,还可以功能复用为EINT8,即2440众多的外部中断源之一。也就是说,我们把这个GPG0的功能配置为EINT8后(相应的寄存器为GPGCON),它就把key1的信号当做中断信号了。
key1按下时是低电平,那这个时候就有一个问题了,cpu怎么知道你是按键抬起来表示想触发中断,还是按下去时想触发中断,这里就要配置一个叫做EXTINTn(具体可参考S3C2440A_UserManual)的寄存器把这件事确定下来,开发板上电后这个寄存器默认EINT8是低电平触发。
这里还要介绍两个寄存器EINTPEND和EINTMASK,EINTPEND是用来显示有哪个外部中断源触发了(比如当你按下按键后,发现EINTPEND没变化,那你就得琢磨是不是你的按键坏了,还是刚才那个EXTINTn的寄存器没配置好),EINTMASK是来决定中断信号是否能进入中断控制器的(说白了,就是你这个中断信号能不能进入下一环节)。
环节1总结:涉及的寄存器:GPG0,EXTINTn,EINTPEND,EINTMASK
由于有些寄存器上电后的默认配置就能满足我们的需要,所以这一环节只要配置GPG0,EINTMASK
环节1完成的任务:EIN8成功触发,进入中断控制器。
环节2:
![](https://img-blog.csdn.net/20131114214804593?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjU0MTEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
图1
我们看图1,中断信号从左面一直流向右面,这其中,中断信号每向右走一步都会涉及到一些寄存器的配置,我们一一分析下。
接环节1,图中红字外部中断信号EINT8出现在Request sources的位置,成功进入了中断控制器里,可能有人会问,为什么要有中断控制器?这个中断控制器是干什么的?因为,CPU在同一时刻只能处理一个中断信号,而在同一时刻可能有很多中断信号源被触发,所以得有个“机构”帮CPU挑一个中断信号处理,好让cpu去处理别的事情。这就是中断控制器的存在意义和任务了。
我们看图1,EINT8属于下面那个中断源,它进入中断控制器后马上进入SRCPND这个寄存器,这个寄存器可以告诉我们目前都有哪些中断源请求中断处理了。
接下来,我们需要配置两个寄存器:INTMOD和INTMASK,INTMOD用来选择中断信号是进入IRQ模式还是FIQ模式,当中断信号选择IRQ模式时,信号会进入MASK环节,当选择FIQ模式时,信号直接流向右下端的FIQ,让CPU进入FIQ模式,跳转到FIQ中断程序。
继续把中断信号选择IRQ模式后要走的环节说完,寄存器INTMASK决定中断信号是否能进入Priority(优先级判断)环节,前面提到过,同一时刻可能会有很多歌中断信号触发进入中断控制器,因此我们需要一个机制判断哪一个信号最终能获得CPU的处理,那么这个机制也是通过配置一个叫PRIORITY的寄存器完成的。
我们看到图中还有一个叫INTPND的寄存器,它显示了谁最终获得了让CPU处理它的权利。
环节2总结:涉及的寄存器:SRCPND,INTMOD,INTMASK,,PRIORITY,INTPND
实际需要的配置的寄存器:无。都默认配置
环节2完成的任务:让CPU进入IRQ模式或者FIQ模式
环节3:此时,CPU已经进入IRQ模式或者FIQ模式了。pc会指向位于地址0x00000000的异常向量表的0x00000018(这里注意必须用全速模式才能让cpu进入IRQ模式,pc跳转到0x00000000,单步调试cpu不会进入IRQ模式,pc也不会跳转到0x00000000,),接着进入中断程序(这里涉及怎么用代码实现跳转,后面还是把代码放出来吧)。
进到中断程序后,要做如下几件事:1.点亮或者关灭LED1,2.清中断请求(这里涉及3个寄存器,按顺序依次将EINTPEND,SRCPND,INTPND清零,清零的方式是向EINT8对应的那位写1)3.防抖动:防抖动主要是实现按一次key1,只触发一次中断请求。方法是先检测按键是不是回到高电平了,再延时一定时间,再检测是不是高电平,如果还是高电平,那我们99%可以确定按键已经抬起了,把这段代码循环执行,就可以实现按一次key1,只触发一次中断请求的目标了。4.把lr的值给pc(回到执行中断程序之前程序运行的地方继续执行,这里注意lr的值是cpu在进入IRQ模式前自动把当前的pc值存入lr里的,实际上根据不同的模式,你还要在lr上加一个偏移量,我理解为的是为了不漏掉执行进入IRQ模式前的指令,详情看芯片手册)
大总结:
1.还是贴出代码了,有些细节用文字说得不够明白,直接贴代码研究比较方便
2.如果调试程序的话,程序运行在0x30000000处,异常向量表在0x00000000,所以你得在程序里写一个中断向量表,然后copy到0x00000000处。而且注意只能给PC一个绝对地址。不能是相对地址,因为你的指令已经经过编译器了,指令里的偏移量肯定是不适合0x00000000处的异常向量表的。
3.还有一点是别忘了在CPSR里把IRQ或者FIQ的使能位清零,这样CPU才能进入相应的工作模式,
4.学习arm9也近两个星期了,跟大家分享下心得:一个大目标要分解成很多的小目标,一个目标,一个目标的去完成,这样思路才容易清晰,包括写程序是这样,调试也是这样,这是最基本的学习思路了
5.ARM官网的文档,s3c2440芯片和mini2440的手册都很重要,我基本上就是看这些学习和解决问题,当然也要善用百度,网上的文章,主要是看个知识框架,对某个知识点有一个宏观的认识,细节的东西还要自己去啃文档,文档才是最全面的。多动手,多实践
6.代码里防抖动的延时时间太短,如果中断请求为低电平触发,效果不是很好,所以采用下降沿触发了,如果低电平触发,要把延时时间弄得长一点
代码:mini2440+jlink v8+mkd4.54调试通过
需要阅读的文档:S3C2440A_UserManual,mini2440开发手册,其他
实验目标:按下开发板上的key1,触发外部中断EINT8,开发板进入中断程序运行点亮或灭掉LED1
分析:
为了方便理解,我按照信号的走向,分为几个环节,逐个说明。
环节1.先说说,按下key1是如何触发外部中断信号。阅读mini2440的开发手册后发现key1是和s3c2440芯片上的GPG0管脚相连,这个IO口除了能作输入输出用,还可以功能复用为EINT8,即2440众多的外部中断源之一。也就是说,我们把这个GPG0的功能配置为EINT8后(相应的寄存器为GPGCON),它就把key1的信号当做中断信号了。
key1按下时是低电平,那这个时候就有一个问题了,cpu怎么知道你是按键抬起来表示想触发中断,还是按下去时想触发中断,这里就要配置一个叫做EXTINTn(具体可参考S3C2440A_UserManual)的寄存器把这件事确定下来,开发板上电后这个寄存器默认EINT8是低电平触发。
这里还要介绍两个寄存器EINTPEND和EINTMASK,EINTPEND是用来显示有哪个外部中断源触发了(比如当你按下按键后,发现EINTPEND没变化,那你就得琢磨是不是你的按键坏了,还是刚才那个EXTINTn的寄存器没配置好),EINTMASK是来决定中断信号是否能进入中断控制器的(说白了,就是你这个中断信号能不能进入下一环节)。
环节1总结:涉及的寄存器:GPG0,EXTINTn,EINTPEND,EINTMASK
由于有些寄存器上电后的默认配置就能满足我们的需要,所以这一环节只要配置GPG0,EINTMASK
环节1完成的任务:EIN8成功触发,进入中断控制器。
环节2:
图1
我们看图1,中断信号从左面一直流向右面,这其中,中断信号每向右走一步都会涉及到一些寄存器的配置,我们一一分析下。
接环节1,图中红字外部中断信号EINT8出现在Request sources的位置,成功进入了中断控制器里,可能有人会问,为什么要有中断控制器?这个中断控制器是干什么的?因为,CPU在同一时刻只能处理一个中断信号,而在同一时刻可能有很多中断信号源被触发,所以得有个“机构”帮CPU挑一个中断信号处理,好让cpu去处理别的事情。这就是中断控制器的存在意义和任务了。
我们看图1,EINT8属于下面那个中断源,它进入中断控制器后马上进入SRCPND这个寄存器,这个寄存器可以告诉我们目前都有哪些中断源请求中断处理了。
接下来,我们需要配置两个寄存器:INTMOD和INTMASK,INTMOD用来选择中断信号是进入IRQ模式还是FIQ模式,当中断信号选择IRQ模式时,信号会进入MASK环节,当选择FIQ模式时,信号直接流向右下端的FIQ,让CPU进入FIQ模式,跳转到FIQ中断程序。
继续把中断信号选择IRQ模式后要走的环节说完,寄存器INTMASK决定中断信号是否能进入Priority(优先级判断)环节,前面提到过,同一时刻可能会有很多歌中断信号触发进入中断控制器,因此我们需要一个机制判断哪一个信号最终能获得CPU的处理,那么这个机制也是通过配置一个叫PRIORITY的寄存器完成的。
我们看到图中还有一个叫INTPND的寄存器,它显示了谁最终获得了让CPU处理它的权利。
环节2总结:涉及的寄存器:SRCPND,INTMOD,INTMASK,,PRIORITY,INTPND
实际需要的配置的寄存器:无。都默认配置
环节2完成的任务:让CPU进入IRQ模式或者FIQ模式
环节3:此时,CPU已经进入IRQ模式或者FIQ模式了。pc会指向位于地址0x00000000的异常向量表的0x00000018(这里注意必须用全速模式才能让cpu进入IRQ模式,pc跳转到0x00000000,单步调试cpu不会进入IRQ模式,pc也不会跳转到0x00000000,),接着进入中断程序(这里涉及怎么用代码实现跳转,后面还是把代码放出来吧)。
进到中断程序后,要做如下几件事:1.点亮或者关灭LED1,2.清中断请求(这里涉及3个寄存器,按顺序依次将EINTPEND,SRCPND,INTPND清零,清零的方式是向EINT8对应的那位写1)3.防抖动:防抖动主要是实现按一次key1,只触发一次中断请求。方法是先检测按键是不是回到高电平了,再延时一定时间,再检测是不是高电平,如果还是高电平,那我们99%可以确定按键已经抬起了,把这段代码循环执行,就可以实现按一次key1,只触发一次中断请求的目标了。4.把lr的值给pc(回到执行中断程序之前程序运行的地方继续执行,这里注意lr的值是cpu在进入IRQ模式前自动把当前的pc值存入lr里的,实际上根据不同的模式,你还要在lr上加一个偏移量,我理解为的是为了不漏掉执行进入IRQ模式前的指令,详情看芯片手册)
大总结:
1.还是贴出代码了,有些细节用文字说得不够明白,直接贴代码研究比较方便
2.如果调试程序的话,程序运行在0x30000000处,异常向量表在0x00000000,所以你得在程序里写一个中断向量表,然后copy到0x00000000处。而且注意只能给PC一个绝对地址。不能是相对地址,因为你的指令已经经过编译器了,指令里的偏移量肯定是不适合0x00000000处的异常向量表的。
3.还有一点是别忘了在CPSR里把IRQ或者FIQ的使能位清零,这样CPU才能进入相应的工作模式,
4.学习arm9也近两个星期了,跟大家分享下心得:一个大目标要分解成很多的小目标,一个目标,一个目标的去完成,这样思路才容易清晰,包括写程序是这样,调试也是这样,这是最基本的学习思路了
5.ARM官网的文档,s3c2440芯片和mini2440的手册都很重要,我基本上就是看这些学习和解决问题,当然也要善用百度,网上的文章,主要是看个知识框架,对某个知识点有一个宏观的认识,细节的东西还要自己去啃文档,文档才是最全面的。多动手,多实践
6.代码里防抖动的延时时间太短,如果中断请求为低电平触发,效果不是很好,所以采用下降沿触发了,如果低电平触发,要把延时时间弄得长一点
代码:mini2440+jlink v8+mkd4.54调试通过
AREA KEY,CODE,READONLY ENTRY exception_vector b start nop nop nop nop nop b irq nop irq mov r0,#0x30000000 add r0,r0,#0x2c mov pc,r0 eint5 ;进入调试模式,查看该地址是0x3000002c mov r0,#0x56000000 ;reverse gpb5 add r0,r0,#0x14 ldr r1,[r0] eor r1,r1,#0x20 mov r0,#0x56000000; add r0,r0,#0x14 str r1,[r0] 1 mov r0,#0x56000000 ;防抖动 add r0,r0,#0x64 ldr r1,[r0] mov r0,#0x1 and r1,r1,r0 cmp r1,#0x1 bne %b1 nop nop nop mov r0,#0x56000000; add r0,r0,#0x64 ldr r1,[r0] mov r0,#0x1 and r1,r1,r0 cmp r1,#0x1 bne %b1 mov r0,#0x56000000 ;clear eint8-23 request in EINTPND register add r0,r0,#0xa8 mov r1,#0x1<<8 str r1,[r0] mov r0,#0x4a000000 ;clear eint8-23 request in SRCPND register add r0,r0,#0x0 mov r1,#0x20 str r1,[r0] mov r0,#0x4a000000 ;clear eint8-23 request in INTPND register add r0,r0,#0x10 mov r1,#0x20 str r1,[r0] subs pc,r14,#4 start mov r0,#0x56000000 ;set GPG0 as EINT8 add r0,r0,#0x60 mov r1,#0x2 str r1,[r0] mov r0,#0x56000000 ;set EINT8 falling edge triggered add r0,r0,#0x8c mov r1,#0x4 str r1,[r0] mov r0,#0x56000000 ;clear EINT8 mask in EINTMASK register add r0,r0,#0xa4 mov r1,#0xfffffeff str r1,[r0] mov r0,#0x4a000000 ;clear EINT8 mask in INTMASK register add r0,r0,#0x8 mov r1,#0xffffffdf str r1,[r0] mov r0,#0x56000000 ;set gpb5 as out add r0,r0,#0x10 mov r1,#0x400 str r1,[r0] mov r0,#0x56000000 ;light led1 add r0,r0,#0x14 mov r1,#0x0 str r1,[r0] mrs r1,cpsr ;enable IRQ in cpsr bic r1,r1,#0x80 msr cpsr_c,r1 init_excpvct1 ldr r0,=exception_vector ;copy the exception_vector to 0x00000000 ldr r1,=0x00000000 add r2,r0,#48 ;这里的数字要大于44,是因为要把异常向量表和下面IRQ那三条一共11条指令都拷过去 0 ;由于r3-r6一共4个寄存器,所以还得是16的倍数,因此选48 ldmia r0!,{r3-r6} stmia r1!,{r3-r6} cmp r0,r2 bne %b0 l b l end
相关文章推荐
- mini2440+jlink v8+mkd4.54 uart串口通信调试心得体会(11.20补完中断部分)
- max11311驱动调试心得体会(一)
- jrtplib3.7.1编译调试心得体会
- 裸机调试-led,蜂鸣器,按键
- 大牛的调试程序心得体会
- msyql使用心得体会(陆续更新)
- 裸机调试----中断
- 裸机程序按键中断问题,求解
- 裸机调试------定时器中断
- ok6410按键中断编程,linux按键裸机
- C++语言学习的一点心得(蜻蜓点水,后面会不断更新学习体会)
- 六、mini2440裸机程序之中断控制器(2)外部按键中断
- 关于mini2440的一个裸机程序——LED与按键中断
- 用龙芯1c库在裸机编程中实现外部中断(GPIO中断、按键中断)
- 按键中断---那些年我们一起玩mini2440(arm9)裸机
- S3C6410中断控制,基于OK6410A裸机按键中断程序(转)
- S5PV210系列 (裸机十)之按键和CPU的中断系统(二)
- OK2440的KEIL裸机调试心得
- 关于调试过程中单片机复位的几点心得与体会
- 按键中断---那些年我们一起玩mini2440(arm9)裸机