:link_to_translation:`en:[English]`

===================
系统调试
===================

BK7238系统异常重启案例分析
============================


当系统异常发生时会打印如下日志:

::

    data abort
    Current regs:
    r00:0x0040df91 r01:0x00001122 r02:0x00000000 r03:0x0000000a
    r04:0x00000001 r05:0x0040bc00 r06:0x0007cb81 r07:0x0040bba0
    r08:0x08080808 r09:0x09090909 r10:0x10101010
    fp :0x11111111 ip :0x00001868
    sp :0x004003d0 lr :0x0007cb5e pc :0x0007cb5e
    SPSR:0x0000003f
    CPSR:0x00000097
    
    separate regs:
    SYS:cpsr r8-r14
    0x0000009f
    0x08080808
    0x09090909
    0x10101010
    0x11111111
    0x00001868
    0x0041cd20
    0x0007cb7f
    
    IRQ:cpsr spsr r8-r14
    0x00000092
    0x6000001f
    0x08080808
    0x09090909
    0x10101010
    0x11111111
    0x00001868
    0x00401c08
    0x003f0fb4
    
    FIQ:cpsr spsr r8-r14
    0x00000091
    0x00000010
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00400c18
    0x00e862ac
    
    ABT:cpsr spsr r8-r14
    0x00000097
    0x0000003f
    0x08080808
    0x09090909
    0x10101010
    0x11111111
    0x00001868
    0x004003c8
    0x0007cb5e
    
    UND:cpsr spsr r8-r14
    0x0000009b
    0x00000010
    0x08080808
    0x09090909
    0x10101010
    0x11111111
    0x00001868
    0x00400418
    0x9ec700a0
    
    SVC:cpsr spsr r8-r14
    0x00000093
    0x6000001f
    0x08080808
    0x09090909
    0x10101010
    0x11111111
    0x00001868
    0x004023d8
    0x00016e94
    
    shutdown...


首先要保留固件版本对应的 bk7231_bsp.elf 文件,通过ARM toolchain 工具dump成 asm 文件,使用如下指令:
::
  
  arm-none-eabi-objdump -d out/bk7231_bsp.elf >out/bk7231_bsp.asm



从异常log 中找到比较关键的几个点:


1.  SPSR寄存器:0x0000003f,查看ARM模式表可知异常前是 SYS mode
------------------------------------------------------------------------------

.. figure:: ../../_static/arm_mode.png
    :align: center
    :alt: arm_mode
    :figclass: align-center

    图1 ARM 模式表


2.  PC寄存器:0x7cb5e
--------------------------------------

PC寄存器是一个通用寄存器,用于存储异常处理程序的地址。当发生异常(如中断或异常)时,处理器会将当前的指令地址保存到PC寄存器中,然后跳转到异常处理程序。


查看上面dump 出的bk7231_bsp.asm,0x7cb5e附近反汇编代码

::

  0007cb50 <printf_data_data_abort>:
     7cb50: b510        push  {r4, lr}
     7cb52: 4903        ldr r1, [pc, #12] ; (7cb60 <printf_data_data_abort+0x10>)
     7cb54: 3001        adds  r0, #1
     7cb56: 8001        strh  r1, [r0, #0]
     7cb58: 4802        ldr r0, [pc, #8]  ; (7cb64 <printf_data_data_abort+0x14>)
     7cb5a: f79c f85d   bl  18c18 <bk_printf>
     7cb5e: bd10        pop {r4, pc}
     7cb60: 00001122  .word 0x00001122
     7cb64: 000a37c5  .word 0x000a37c5

  0007cb68 <data_abort_test>:
     7cb68: 200a        movs  r0, #10
     7cb6a: b510        push  {r4, lr}
     7cb6c: f023 ffd4   bl  a0b18 <__os_malloc_from_thumb>
     7cb70: 2300        movs  r3, #0
     7cb72: 54c3        strb  r3, [r0, r3]
     7cb74: 3301        adds  r3, #1
     7cb76: 2b0a        cmp r3, #10
     7cb78: d1fb        bne.n 7cb72 <data_abort_test+0xa>
     7cb7a: f7ff ffe9   bl  7cb50 <printf_data_data_abort>
     7cb7e: bd10        pop {r4, pc}

.. important::
  由于ARM指令执行方式是流水线操作,即在对第1条指令开始执行的时候,可以同时对第2条指令进行译码操作,对第3条指令进行取指操作。
  所以问题出错在 0x7cb58 这条ldr指令.


从异常log看 r0=0x0040df91 是一个非四字节对齐的地址,进行字(word)读操作,导致出现非对齐异常访问。



3. SYS mode 对应r14(LR)寄存器:0x7cb7f
--------------------------------------

- LR 用于辅助PC 指针定位问题的。
- LR寄存器是一个通用寄存器,用于存储函数调用的返回地址。当一个函数调用另一个函数时,当前函数的返回地址会被保存到RA寄存器中,以便在子函数执行完毕后,能够正确返回到调用函数的下一条指令。
- 在函数调用过程中,LR寄存器的值通常是由调用方保存的,而在被调用的函数中,它被用于保存返回地址。当函数执行返回指令时,会从LR寄存器中读取返回地址,跳转到相应的位置继续执行。