Arm 为什么是stm32f103';s elf文件运行良好,但二进制文件不行?

Arm 为什么是stm32f103';s elf文件运行良好,但二进制文件不行?,arm,gdb,stm32,firmware,openocd,Arm,Gdb,Stm32,Firmware,Openocd,我正在尝试运行stm32f103内的固件。所以当我使用opencod+gdb上传和调试elf文件时,一切都很好,我的固件工作正常,我可以设置和删除断点 但是当我尝试使用st flash上传这个固件(与elf文件一起构建)并将其写入0x8000000时,它不起作用。虽然我收到“固件已成功上载”的消息 当LED开始闪烁时,我可以查看代码是否运行 根据启用引导加载程序的数据表,BOOT0通过npn晶体管连接到cp2102的DTR引脚。我必须将BOOT0设置为高。但是当我通过st链接上传我的fw时,我的

我正在尝试运行stm32f103内的固件。所以当我使用opencod+gdb上传和调试elf文件时,一切都很好,我的固件工作正常,我可以设置和删除断点

但是当我尝试使用st flash上传这个固件(与elf文件一起构建)并将其写入
0x8000000
时,它不起作用。虽然我收到“固件已成功上载”的消息

当LED开始闪烁时,我可以查看代码是否运行

根据启用引导加载程序的数据表,BOOT0通过npn晶体管连接到cp2102的DTR引脚。我必须将BOOT0设置为高。但是当我通过st链接上传我的fw时,我的串行(cp2102)没有连接。所以我认为DTR引脚是浮动的或向下拉的。我的错在哪里

我试图在上传之前批量擦除我的flash,它给出了相同的结果

这是我的链接器的ld文件:

MEMORY
{
  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
  CCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 0
  FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
  FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)  : ORIGIN = 0x00000000, LENGTH = 0
}
和部分

您是否尝试过使用

它允许您使用UART、SWD、JTAG和USB对固件进行编程。请先尝试SWD,然后再尝试UART模式,看看是ST错误还是您的UART接线。

试试这个

.globl _start
_start:

.word 0x20001000
.word reset
.word loop
.word loop

.thumb_func
reset:
    add r0,#1
    b reset

.thumb_func
loop:
    b loop
构建,可以使用arm任何东西(arm none eabi、arm linux gnueabi等)

眨眼器01.c

void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void dummy ( unsigned int );

#define GPIOCBASE 0x40011000
#define RCCBASE 0x40021000

int notmain ( void )
{
    unsigned int ra;
    unsigned int rx;

    ra=GET32(RCCBASE+0x18);
    ra|=1<<4; //enable port c
    PUT32(RCCBASE+0x18,ra);
    //config
    ra=GET32(GPIOCBASE+0x04);
    ra&=~(3<<20);   //PC13
    ra|=1<<20;      //PC13
    ra&=~(3<<22);   //PC13
    ra|=0<<22;      //PC13
    PUT32(GPIOCBASE+0x04,ra);

    for(rx=0;;rx++)
    {
        PUT32(GPIOCBASE+0x10,1<<(13+0));
        for(ra=0;ra<200000;ra++) dummy(ra);
        PUT32(GPIOCBASE+0x10,1<<(13+16));
        for(ra=0;ra<200000;ra++) dummy(ra);
    }
    return(0);
}
建造

检查向量表

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000041    stmdaeq r0, {r0, r6}
 8000008:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800000c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000010:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000014:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000018:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800001c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000020:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000024:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000028:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800002c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000030:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000034:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000038:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800003c:   08000047    stmdaeq r0, {r0, r1, r2, r6}

08000040 <reset>:
 8000040:   f000 f80a   bl  8000058 <notmain>
 8000044:   e7ff        b.n 8000046 <hang>

08000046 <hang>:
 8000046:   e7fe        b.n 8000046 <hang>
两者应该有相同的数据。如果没有,那么您就有boot0问题

编辑

如果DTR高,则boot0为0/GND是吗?这就是正常启动所需的。开机时boot0处于低位,复位处于高位,或从低位到高位

您可以编写一个程序以某种方式强制DTR

int dtr_bit=TIOCM_DTR;
...
dtr_bit=TIOCM_DTR;
ioctl(ser_hand,TIOCMBIC,&dtr_bit);
...
dtr_bit=TIOCM_DTR;
ioctl(ser_hand,TIOCMBIS,&dtr_bit);
用通常的termios材料打开把手

或者假设您的哑终端(minicom等)支持DTR,连接uart,然后打开电源和/或重置电路板(回形针或任何您手边的东西)


由于我经常使用串行引导加载程序加载我的stm32部件,或者即使我使用SWD,我总是为自己提供一个控制boot0和复位的解决方案,无论是按钮、跳线、焊盘还是其他组合

@非常感谢您的详细回答。我发现问题在于固件过大。我的芯片只有64k的闪存,fw是68k,所以eclipse没有告诉我固件太大,并试图闪存它。另外,我基于项目的模板使用了newlib,其中startup.s被C文件替换,我想这是有问题的。因此,我从openstm32 tamplate创建了一个新项目(它从stdperiph lib、cmsis等+ld复制了所有必要的文件),之后我添加了我的文件,通过删除未使用的文件和set-Os标志优化了构建,它似乎对我有效,但固件大小几乎过大。我将尝试您的解释)

我发现链接器和ld文件存在问题,但这是一个奇怪的问题。如果我从blink模板创建一个新项目,并将其上载到我的stm32,则一切正常,led闪烁。如果我用同一个ld文件上传我的fw,没有任何效果。如果我通过Keil uVision构建并上传它,那么一切都正常工作。你也应该能够使用openocd+telnet。通过telnet,您可以使用其他格式的文件。我怀疑这是因为elf文件包含大量关于二进制文件的位置等信息,而对于原始闪存图像,只有字节,你必须告诉工具更多,另一个可能的问题是二进制文件中的入口点错误,但是通过使用gdb,它在您定义的位置而不是应该在的位置启动程序,向量表的反汇编/转储是什么样子的?除此之外,还需要更多关于您尝试和/或尝试执行的操作、二进制文件的外观(至少在开始时)以及您尝试过的小型测试二进制文件的信息。gdb既有帮助又有伤害,所以使用gdb只能让你走到目前为止,要想在没有gdb的情况下运行,你必须弄清楚gdb为你做了什么,而不是为你做了什么。stlink与boot0无关,boot0让你进入片上引导加载程序,通常是uart,有时是其他,但不是swd/jtag——你可以随时使用它,除非你在挂起的芯片上放了一个二进制文件,否则可能无法通过swd进入(除非你使用boot0只是为了将它转换成无缺陷/挂起的代码)。如果你想在boot0中使用cp2102,你需要不同的软件,st网站上提供的信息非常容易编写你自己的程序员,而且还有很多。在尝试了其他方法后,你能回到使用openocd+gdb和elf文件吗?你有没有挂断芯片,或者能够通过这种组合重新获得成功?
MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}
arm-none-eabi-as --warn --fatal-warnings  flash.s -o flash.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mthumb -c blinker01.c -o blinker01.o
arm-none-eabi-ld -o blinker01.elf -T flash.ld flash.o blinker01.o
arm-none-eabi-objdump -D blinker01.elf > blinker01.list
arm-none-eabi-objcopy blinker01.elf blinker01.bin -O binary
Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000041    stmdaeq r0, {r0, r6}
 8000008:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800000c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000010:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000014:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000018:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800001c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000020:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000024:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000028:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800002c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000030:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000034:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000038:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800003c:   08000047    stmdaeq r0, {r0, r1, r2, r6}

08000040 <reset>:
 8000040:   f000 f80a   bl  8000058 <notmain>
 8000044:   e7ff        b.n 8000046 <hang>

08000046 <hang>:
 8000046:   e7fe        b.n 8000046 <hang>
mdw 0x00000000 20
mdw 0x08000000 20
int dtr_bit=TIOCM_DTR;
...
dtr_bit=TIOCM_DTR;
ioctl(ser_hand,TIOCMBIC,&dtr_bit);
...
dtr_bit=TIOCM_DTR;
ioctl(ser_hand,TIOCMBIS,&dtr_bit);