利用连续点灯定位汇编代码的错误

一般来说,串口打印是极为方便的调试方法,但是如果不能用串口怎么办?
这种尴尬的情景会出现在U-boot或kernel的初始化阶段,如果程序在串口正式初始化之前就发生了错误,并且我们还找不到错误的时候,就可以使用连续点灯定位。

  • 在启动代码中放置多个led闪烁程序,通过观察led闪烁的次数,我们便可以一步定位出错误的位置,相当方便。以s5pv210为例:
/**************** led , sjh add**********特殊的注释,方便删除****/
    ldr r4, =0x11111111         
    ldr r3, =0xE0200240         
    str r4, [r3]                

    ldr r4, =((1<<3) | (1<<4) | (1<<5))   /*先灭再亮*/
    ldr r3, =0xE0200244
    str r4, [r3]

    ldr r4, =((0<<3) | (0<<4) | (0<<5)) 
    ldr r3, =0xE0200244
    str r4, [r3]    

    bl delay_sjh    /*必须要延时,否则看不清楚*/

    ldr r4, =((1<<3) | (1<<4) | (1<<5)) 
    ldr r3, =0xE0200244
    str r4, [r3]

    bl delay_sjh    
/*******************************************************/
  • 值得注意的是,有些U-boot和kernel在默认的情况下可能led就是亮的,我们需要将led先灭再亮,再延时灭,这样才能看出效果
  • 这段代码使用了r3、r4,要注意是否r3、r4已经被用来传递一些参数了,最好用一些没有被使用的寄存器,这样比较保险
  • 此外加入一处应该都附上特殊的注释,这样通过编辑器搜索就很容易定位自己改过的地方,批量删除极为方便
/*sjh add*/
delay_sjh:
    ldr r6, =9000000
    ldr r7, =0x0
delay_loop: 
    sub r6, r6, #1              
    cmp r6, r7                  
    bne delay_loop
    mov pc, lr                  
  • 值得注意的是,这个延时函数最好取个怪名字,以免重名…..,还有注意r6、r7是否已经被用了
  • 而且延时函数最好放在点灯的文件夹内,这样非常安全,可以避免发生意外。曾经有一次将延时函数放在了U-boot的lowlevel_init.S中,结果lowlevel_init.S由于链接不合理,没有放在BL1中,导致点灯无效…..所以保险起见延时函数最好还是放在点灯的文件夹内
  • 如果延时函数实在要放在其他文件内,千万记得用 .globl 语句全局化,否则也会导致点灯无效…..

你可能感兴趣的:(【开发技巧】)