在 Debian 上不用 IDE 编程 STM32F4x

Programming STM32F4x WITHOUT IDE on Debian

这是我在这个网站上的第一个问题,我不确定我的英语..

我想知道是否有一种方法可以在不使用任何 IDE 的情况下对 Nucleo STM32F446RE 进行编程(通过 USB,而不是通过 JTAG)。

出于培训目的,我只想使用文本编辑器(我使用 kate)、Makefile 和命令行进行编程。

我已经found/installed:

我认为它包含我们需要编译的所有内容(但我认为其中没有 asm 编译器)。

有 C 代码示例和 makefile(我不完全理解)。它似乎编译得很好(我尝试了 "minimum" 示例)。

这是我使用的示例:

#ifndef __NO_SYSTEM_INIT
void SystemInit()
{}
#endif

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

这是 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

我修改了它以设置 cortex-m4 而不是 cortex-m0。 在 运行 make 命令之后,我得到 minimum.mapminimum.axf 文件。

但我不知道如何在设备中加载目标代码。 (没有 minimum.o 文件是否正常?)

我会把这样的东西称为 C 代码的最小示例,在这种情况下无限循环不是必需的,但会受到您的启发。

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
}

建造

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

检查

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)

可能不需要,但请阅读文档,人们使用 0x08000000,技术上它是 0x00000000,stm32 系列将 0x08000000 映射到 0x00000000,如文档中基于引导引脚的描述。检查需要显示向量 table 是第一件事,您已经告诉工具链这些是向量 table 中的拇指地址(已设置 lsbit)。可以将 C 入口函数(不需要 main(),这只是一个约定)放在向量 table 中作为重置函数。我没有 .data 也没有 .bss 初始化,所以像这样的东西不允许使用 .data 也不假设 .bss 变量为零,必须先写再读。向 bootstrap(和链接描述文件)添加更多代码将允许这样做。

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

将创建一个二进制文件,根据您使用的工具,该二进制文件可用于加载程序。如果这是一块核板,您可以将该文件复制到虚拟 USB 驱动器。显然这个程序不会显示任何有趣的东西。使用 openocd 或其他 SWD 调试器软件(如果你有一个 nucleo 板你不需要任何其他硬件)你可以停止并重新启动程序来尝试查看它 运行.

您可以阅读文档以查看地址以及如何对外围设备进行编程。

thumb2 只是对 thumb 的扩展,您可以坚持使用传统的 thumb 或将 cortex-m4 或 armv7m 添加到命令行 (cpu/arch) 以尝试减少指令数量但权衡更大的指令.

毫无疑问,那里有工具,但编写自己的程序与串行引导加载程序接口以将程序下载到设备中是相当容易的。