Debugging 由于启动ROM,在LPC4088上上载和调试二进制文件时出现问题

Debugging 由于启动ROM,在LPC4088上上载和调试二进制文件时出现问题,debugging,gcc,embedded,lpc,Debugging,Gcc,Embedded,Lpc,我正在尝试上载此简单的汇编程序: .global _start .text reset: b _start undefined: b undefined software_interrupt: b software_interrupt prefetch_abort: b prefetch_abort data_abort: b data_abort

我正在尝试上载此简单的汇编程序:

    .global _start
    .text

reset:                  b _start
undefined:              b undefined
software_interrupt:     b software_interrupt
prefetch_abort:         b prefetch_abort
data_abort:             b data_abort
                        nop
interrupt_request:      b interrupt_request
fast_interrupt_request: b fast_interrupt_request

_start:

    mov r0, #0
    mov r1, #1

increase:

    add r0, r0, r1
    cmp r0, #10
    bne increase

decrease:

    sub r0, r0, r1
    cmp r0, #0
    bne decrease
    b increase 


stop:   b stop
通过SEGGER的JLink连接到我的LPC4088(我使用的是嵌入式艺术家LPC4088 QSB),以便以后可以使用GDB调试它


首先,我使用GCC工具链编译了带有所有调试符号的源代码:

  • arm none eabi as-g-gdwarf-2-o program.o program.s
  • arm none eabi ld-Ttext=0x0-o program.elf program.o
  • arm none eabi objcopy-O binary program.elf program.bin
  • 但将二进制
    program.bin
    上载到LPC4088失败。然后user@old_timer在评论中提醒我,LPC4088的引导ROM在每次重置后都会进行校验和测试,如第876页所述,共页:

    因此,我确信我的二进制文件将通过以下步骤描述的校验和测试。所以我首先创建了一个C源文件
    checksum.C

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main(int argc, char **argv) {
        int fw, count, crc;
        char buf[28];
    
        fw = open(argv[1], O_RDWR);
        // read fist 28 bytes
        read(fw, &buf, 28);
    
        // find 2's complement of entries 0 to 6
        for (count=0, crc=0; count < 7; count++) {
                crc += *((int*)(buf+count*4));
        }
        crc = (~crc) + 1;
    
        // write it at offset 0x0000001C 
        lseek(fw, 0x0000001C, SEEK_SET);
        write(fw, &crc, 4);
        close(fw);
    
        return 0;
    }
    
    因此,该代码一定来自某个地方,可能是LPC4088的引导ROM,该ROM在引导时被重新映射到
    0x0
    ,如本手册第907页所述:


    您知道如何克服这个启动ROM和校验和问题,以便我可以正常调试程序吗?


    过了一会儿,我发现了这个警告:

    **************************
    WARNING: T-bit of XPSR is 0 but should be 1. Changed to 1.
    **************************
    
    实际上是说,我正在尝试在Cortex-M4上执行ARM指令,它只是拇指!警告中提到的T位在第100页(共页)中有说明:


    这正是user@old_timer所说的。

    您正试图在cortex-m4上运行arm指令(0xEXXXXXXX是一个很大的赠品,更不用说异常表有很多0xEAxxxxxx指令)。cortex-m的引导方式不同(向量表而非可执行指令),并且仅限于thumb(armv7-m中的thumb2扩展也是……thumb,不要被这一点弄糊涂了,thumb2扩展的作用是什么,但早期/原始thumb在所有这些扩展中都是可移植的)。因此,无论您是否需要像基于ARM7TDMI的旧NXP芯片那样的附加校验和,以便引导加载程序允许用户/应用程序代码运行,您首先需要在cortex-m4上运行的东西

    从这个开始,是的,我知道你现在有一个cortex-m4使用cortex-m0

    那么,s

    建造

    检查so.list以确保向量表是正确的

    00000000 <_start>:
       0:   20001000    andcs   r1, r0, r0
       4:   0000000f    andeq   r0, r0, pc
       8:   0000000d    andeq   r0, r0, sp
    
    0000000c <hang>:
       c:   e7fe        b.n c <hang>
    
    0000000e <reset>:
       e:   2100        movs    r1, #0
    
    00000010 <outer>:
      10:   20ff        movs    r0, #255    ; 0xff
    
    00000012 <inner>:
      12:   46c0        nop         ; (mov r8, r8)
      14:   46c0        nop         ; (mov r8, r8)
      16:   3101        adds    r1, #1
      18:   3801        subs    r0, #1
      1a:   d1fa        bne.n   12 <inner>
      1c:   46c0        nop         ; (mov r8, r8)
      1e:   46c0        nop         ; (mov r8, r8)
      20:   e7f6        b.n 10 <outer>
    
    并使用-Ttext=0x20000000链接,然后下载到sram并在0x20000000处使用调试器开始执行


    你应该看到r0计数一些,r1应该永远保持计数,然后滚动并继续计数,因此如果你停止它,检查寄存器、恢复、停止等,你应该看到该活动。

    我没有看你的芯片,但一些NXP芯片需要向量/异常表中的校验和,这可能与基于ARM7TDMI的芯片一起消失,但也许这个计划仍然存在。如果引导加载程序在应用程序闪存中没有看到有效的程序,那么它将保持映射为零,并且不会运行您的程序。看看是否有关于这个主题的文本…是的,如果找到了有效的用户程序,就会有讨论。所以也许你的程序不是这样出现的。如果您进行0x000内存转储,您是否看到与您的程序类似的内容?您是否尝试先在ram中运行以查看其是否有效?如果处理器留下了映射的引导加载程序,则可能这就是您无法写入它的原因。先试试ram。@old_timer我修改了校验和值,现在有点奇怪。。。我也试着把我的代码复制到RAM中,但它在那里不起作用……我不理解你答案中的很多东西。有没有可能重新组织一下,因为它看起来有点忙。所以你是说我的指令是手臂而不是拇指?我不太理解这一点,因为我使用了UAL(统一汇编语言),我的程序中使用的所有指令都可以在ARMv7-M架构参考手册中找到。。。只是我的编译参数错了还是怎么了?我是否应该像在汇编程序中那样,在编译时只使用参数
    -mcpu=cortex-m0
    -mthumb
    ?如果你问我的话,我还会添加
    -mfpu=fpv4-sp-d16
    -mfloat abi=softfp
    。。。这行得通吗?我正在取得一点进展。我使用前面提到的标志编译了我的程序,然后打开JLinkExe,连接到LPC4088,停止MCPU,擦除闪存,将我的program.bin上传到FLASH
    0x0
    ,并将我的电脑设置为
    0x0
    。到目前为止看起来还不错!唯一的问题是,它不会自动启动,因为我不关心校验和值。。。关于这个。。如果我的UAL(通用汇编语言)是用拇指编码编译的,那么校验和值是否仍然需要在偏移量
    0x1C
    上?我尝试了你的代码,但它不起作用。。。当我开始单步执行程序时,我在第一步得到:
    00000000:ASRS R0,R0,#32
    ,然后在第二步:
    00000002:MOVS R0,#0
    ,第三步:
    00000004:MOVS R7,R1
    第四步:
    00000006:MOVS R0,R0
    等等。。。这不是您提供的代码。您误解了mbed注释。我已经从所有主要厂商启动了cortex ms和其他处理器。我可以启动lpc并控制工具,可以启动swd/jtag等。有很多步骤,很多陷阱,其中一个出错。这是把问题一分为二,如果你能继续把问题一分为二。我也不想支持/使用mbed,但如果我根本无法让某些东西发挥作用,那么你就捂住鼻子,在他们的沙箱中坐上足够长的时间,看看你的问题是什么。
    .cpu cortex-m0
    .thumb
    .thumb_func
    .globl _start
    _start:
    stacktop: .word 0x20001000
    .word reset
    .word hang
    @ ...
    
    .thumb_func
    hang: b hang
    .thumb_func
    reset:
       mov r1,#0
    outer:
       mov r0,#0xFF
    inner:
       nop
       nop   
       add r1,#1
       sub r0,#1
       bne inner
       nop
       nop
       b outer
    
    arm-none-eabi-as so.s -o so.o
    arm-none-eabi-ld -Ttext=0 so.o -o so.elf
    arm-none-eabi-objdump -D so.elf > so.list
    arm-none-eabi-objcopy so.elf -O binary so.bin
    
    00000000 <_start>:
       0:   20001000    andcs   r1, r0, r0
       4:   0000000f    andeq   r0, r0, pc
       8:   0000000d    andeq   r0, r0, sp
    
    0000000c <hang>:
       c:   e7fe        b.n c <hang>
    
    0000000e <reset>:
       e:   2100        movs    r1, #0
    
    00000010 <outer>:
      10:   20ff        movs    r0, #255    ; 0xff
    
    00000012 <inner>:
      12:   46c0        nop         ; (mov r8, r8)
      14:   46c0        nop         ; (mov r8, r8)
      16:   3101        adds    r1, #1
      18:   3801        subs    r0, #1
      1a:   d1fa        bne.n   12 <inner>
      1c:   46c0        nop         ; (mov r8, r8)
      1e:   46c0        nop         ; (mov r8, r8)
      20:   e7f6        b.n 10 <outer>
    
    .cpu cortex-m0
    .thumb
    .thumb_func
    reset:
       mov r1,#0
    outer:
       mov r0,#0xFF
    inner:
       nop
       nop   
       add r1,#1
       sub r0,#1
       bne inner
       nop
       nop
       b outer