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/

Ilya
  • 61
  • 1
  • 10
  • you should be able to use openocd + telnet as well. and with the telnet you can use other format files. I suspect it is because the elf file contains a lot of information about where the binary goes, etc, and with a raw flash image just the bytes, you have to tell the tool more, even though you perhaps did. – old_timer Oct 24 '19 at 02:06
  • the other possible problem is you have the entry point wrong in the binary but by using gdb it started the program where you defined it instead of where it should be, what does the disassembly/dump of the vector table look like? – old_timer Oct 24 '19 at 02:06
  • other than that there is a considerable amount more information needed about what you have tried and/or are trying to do and what your binary looks like at least the start of it, and what tiny test binaries you have tried. gdb hurts as much as it helps so working on gdb only gets you so far, to run without it you have to figure out what gdb is doing for you and not doing for you. – old_timer Oct 24 '19 at 02:09
  • stlink is unrelated to boot0, boot0 gets you into the on chip bootloader which is generally uart and sometimes other, but not swd/jtag you use that anytime unless you have put a binary on the chip that hangs then it might not be possible to get in via swd (unless you use boot0 simply to get it into non-buggy/hanging code). if you want to come in with the cp2102 in boot0 you need different software, information available at st's website pretty easy to write your own programmer plus there are quite a few out there. – old_timer Oct 24 '19 at 02:11
  • after trying this other way are you able to go back to using openocd+gdb and an elf file? have you hung the chip or able to go back to success with that combination? – old_timer Oct 24 '19 at 02:13
  • you generally want to be careful with mass erases, the stm32 parts are probably fine but there are other vendors and their parts that have calibrated chip specific items that a mass erase will destroy, something you dont want to do as you cant replace it once erased. generally stick to the application flash area in sections. – old_timer Oct 24 '19 at 02:14
  • @old_timer wow, thanks for your replies :) I found out that boot0, st-link are ok. The problem with linker, do not why, but the example with blink (I use the latest eclipse with arm's plugin) is working fine. But when I use my own firmware, the address starts from 0x00000000, not from 0x08000000 (btw, blink.hex starts from this 0x00000000 address too) and there is no startup_xxxx.s file to remap binary. mem.ld and sections.ld are looked fine. flash 0x20000000 and 64k, ram 0x08000000 and 20k. ENTRY (_start) – Ilya Oct 24 '19 at 06:30
  • when the boot pin(s) are set to boot into application flash both 0x00000000 and 0x08000000 point to the same flash, you can link for either if the image is small enough not all of application flash is mapped to 0x00000000. But a dump of the first few words of your binary will tell if it will boot or not and a bit of a disassembly up there to see where the entry point is will also tell if it will boot or not. – old_timer Oct 24 '19 at 12:39
  • thank you, I will check it. Also I'll try to build project using openstm32 template for my chip. Looks like it has a different linker – Ilya Oct 24 '19 at 12:53

3 Answers3

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.

Tarick Welling
  • 3,119
  • 3
  • 19
  • 44
  • I found the issue with linker and ld file, but it's strange issue. If I create a new project from blink template, and upload it into my stm32 then everything is ok, the led is blinking. If I upload my fw using the same ld file nothin is working. If I build and upload it via Keil uVision, then everything is ok and working. – Ilya Oct 23 '19 at 20:35
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 don't see this the processor won't 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 don't 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 push-buttons or jumpers or pads or some combination.

halfer
  • 19,824
  • 17
  • 99
  • 186
old_timer
  • 69,149
  • 8
  • 89
  • 168
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 )

Ilya
  • 61
  • 1
  • 10