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
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/
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.
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.