简体   繁体   中英

Programming STM32F4x WITHOUT IDE on Debian

This is my first question on this website, and I'm not sure about my English..

I want to know if there is a way to program the Nucleo STM32F446RE (via USB, not via JTAG) WITHOUT using any IDE.

For training purpose, I want to program with only a text editor (i use kate), Makefiles and command line.

What I already found/installed:

  • gcc-arm-none-eabi (6-2017-q2-update)

It contains, i think, all we need to compile (but I don't think there is a asm compiler in there).

There is example of code in C, and makefiles (that I don't totally understand). It seems to compile well (I tried the "minimum" example).

Here is the example I used:

#ifndef __NO_SYSTEM_INIT
void SystemInit()
{}
#endif

void main()
{
    for (;;);
}

And here is the Makefile:

# Selecting Core
CORTEX_M=4

# Use newlib-nano. To disable it, specify USE_NANO=
USE_NANO=--specs=nano.specs

# Use seimhosting or not
USE_SEMIHOST=--specs=rdimon.specs
USE_NOHOST=--specs=nosys.specs

CORE=CM$(CORTEX_M)
BASE=../..

# Compiler & Linker
CC=arm-none-eabi-gcc
CXX=arm-none-eabi-g++

# Options for specific architecture
ARCH_FLAGS=-mthumb -mcpu=cortex-m$(CORTEX_M)

# Startup code
STARTUP=$(BASE)/startup/startup_ARM$(CORE).S

# -Os -flto -ffunction-sections -fdata-sections to compile for code size
CFLAGS=$(ARCH_FLAGS) $(STARTUP_DEFS) -Os -flto -ffunction-sections -fdata-sections
CXXFLAGS=$(CFLAGS)

# Link for code size
GC=-Wl,--gc-sections

# Create map file
MAP=-Wl,-Map=$(NAME).map

NAME=minimum
STARTUP_DEFS=-D__STARTUP_CLEAR_BSS -D__START=main

LDSCRIPTS=-L. -L$(BASE)/ldscripts -T nokeep.ld
LFLAGS=$(USE_NANO) $(USE_NOHOST) $(LDSCRIPTS) $(GC) $(MAP)

$(NAME)-$(CORE).axf: $(NAME).c $(STARTUP)
    $(CC) $^ $(CFLAGS) $(LFLAGS) -o $@

clean: 
    rm -f $(NAME)*.axf *.map *.o

I modified it in order to set cortex-m4 instead of cortex-m0. After running the make command I get minimum.map and minimum.axf files.

But I don't know how to load the object code in the device. ( and is it normal not to have a minimum.o file ? )

I would call something like this a minimal example with C code, the infinite loop is not necessary in this case, but is inspired by yours.

vectors.s

.thumb

.globl _start
_start:
    .word 0x20002000
    .word reset
    .word done
    .word done

.thumb_func
reset:
    bl centry
    b done
.thumb_func
done:
    b done

so.c

void centry ( void )
{
    for(;;) continue;
}

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 vectors.s -o vectors.o
arm-none-eabi-gcc -O2 -c -mthumb so.c -o so.o
arm-none-eabi-ld -T flash.ld vectors.o so.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list

examine

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

08000010 <reset>:
 8000010:   f000 f802   bl  8000018 <centry>
 8000014:   e7ff        b.n 8000016 <done>

08000016 <done>:
 8000016:   e7fe        b.n 8000016 <done>

08000018 <centry>:
 8000018:   e7fe        b.n 8000018 <centry>
 800001a:   46c0        nop         ; (mov r8, r8)

Likely not required but read the docs, folks use 0x08000000, technically it is 0x00000000, the stm32 family maps 0x08000000 to 0x00000000 as described in the documentation based on the boot pins. Inspection needs to show that the vector table is the first thing, you have told the toolchain these are thumb addresses in the vector table (lsbit is set). Could have put the C entry function (main() is not required, that is just a convention) in the vector table as the reset function. I have no .data nor .bss initialization so something like this would not allow the use of .data nor assuming .bss variables are zero, have to write before you read. Adding more code to the bootstrap (and linker script) would allow for that.

arm-none-eabi-objcopy so.elf -O binary so.bin

Will create a binary that depending on the tools you use may be used to load the program. If this is a nucleo board you can copy that file to the virtual usb drive. Clearly this program wont show anything interesting. Using openocd or other SWD debugger software (if you have a nucleo board you dont need any other hardware) you can stop and restart the program to try to see it running.

You can read the documentation to see the addresses and how to program the peripherals.

thumb2 is just extensions to thumb, you can stick with traditional thumb or add cortex-m4 or armv7m to the command line (cpu/arch) to try to reduce the number of instructions but trade off for larger instructions.

there are no doubt tools out there but it is fairly easy to write your own program to interface with the serial bootloader to download your program into the device.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM