Why stm32f103's elf file works well, but binary not?

0

I'm trying to run out my firmware inside stm32f103. So when I use opencod+gdb uploading and debugging elf file, everything is fine, my firmware is working and I can set and remove breakpoints.

But it doens't work when I try to upload this firmware (which was built together with elf file) using st-flash and writing it into 0x8000000. Although I get the message that 'the firmware was uploaded successfully'.

I can see if my code runs when my leds start blinking.

BOOT0 is connected to the DTR pin of a cp2102 via npn transistor, according to the datasheet to enable bootloader. I have to set BOOT0 to high. But my serial (cp2102) is not connected when I upload my fw via st-link. So I think that DTR pin is floating or pulled down. Where is my mistake?

I was trying to mass erase my flash before uploading, it gives the same results

schematic

here is my linker's ld file:

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
}

and sections https://pastebin.ubuntu.com/p/N32zQf9sCm/

arm
gdb
stm32
firmware
openocd
asked on Stack Overflow Oct 23, 2019 by Ilya • edited Oct 24, 2019 by Ilya

3 Answers

0

Have you tried to use the STM32CubeProgrammer?

It allows you to program the firmware using UART, SWD, JTAG and USB. Please try SWD firstly and then the UART mode to see if it is a ST bug or your UART wiring.

answered on Stack Overflow Oct 23, 2019 by Tarick Welling
0

try this

.globl _start
_start:

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

.thumb_func
reset:
    add r0,#1
    b reset

.thumb_func
loop:
    b loop

build, can use arm-whatever-whatever (arm-none-eabi, arm-linux-gnueabi, etc)

arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objcopy -O binary so.elf so.bin
arm-none-eabi-objdump -D so.elf

so.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000011    stmdaeq r0, {r0, r4}
 8000008:   08000015    stmdaeq r0, {r0, r2, r4}
 800000c:   08000015    stmdaeq r0, {r0, r2, r4}

08000010 <reset>:
 8000010:   3001        adds    r0, #1
 8000012:   e7fd        b.n 8000010 <reset>

08000014 <loop>:
 8000014:   e7fe        b.n 8000014 <loop>

Not that the vectors are odd, they are the address of the handler orred with one. If you dont see this the processor wont boot.

You have said you have openocd+gdb working so either through that path or via openocd+telnet or if you have another way using the uart bootloader for example. But use reset or a power on with boot0 set for application and then attach with openocd without resetting it, then halt and examine r0, resume, halt and examine again, is it counting, did this code load and run from flash.

If you have a blue pill then you can use this code to blink the led.

flash.s

.cpu cortex-m0
.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang

.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .

.align

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.thumb_func
.globl dummy
dummy:
    bx lr

.end

blinker01.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);
}

flash.ld

MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

build

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

examine vector table

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>

Looks good. Now program and reset.

Your schematic is not a blue pill so adjust accordingly to enable the gpio clocks and make the pin an output and so on for your led.

with either of these programs or your own, I dont use gdb have no use for it I use openocd+telnet if anything. but either should let you dump the flash with telnet

mdw 0x00000000 20
mdw 0x08000000 20

both should have the same data. If not then you have a boot0 problem.

EDIT

If DTR is high then boot0 is 0/GND yes? That is what is required to boot normally. boot0 tied low and reset tied high with a power on or low to high.

You can write a program to force DTR one way or the other.

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);

with the usual termios stuff to open the handle.

Or assuming DTR is supported by your dumb terminal (minicom, etc), attach to the uart, then power on and/or reset the board (paperclip, or whatever you have handy).

Since I often use the serial bootloader to load my stm32 parts or even if I use SWD, I always provide myself a solution to control boot0 and reset, be it pushbuttons or jumpers or pads or some combination.

answered on Stack Overflow Oct 25, 2019 by old_timer • edited Oct 25, 2019 by old_timer
0

@old_timer Thank you very much for your detailed answer. I found that the problem is in oversized firmware. My chip has only 64k of flash and fw is 68k, so eclipse didn't tell me that the firmware is oversized and tried to flash it. Also, template in which my project based uses newlib, where startup.s was replaced by C files and I guess there is some issue. So I created a new project from openstm32 tamplate (it copied all necessary files from stdperiph lib, cmsis, etc + ld), after that I added my files, optimized build by removing unused files and set -Os flag, and it seems working for me, but the firmware size is almost oversized. I will try yr explanation )

answered on Stack Overflow Oct 28, 2019 by Ilya

User contributions licensed under CC BY-SA 3.0