Linux环境中,使用Makefile来编译标准库STM32工程 ---- STM32F103C8T6

目录

前言

一、环境配置

 前文疑云

 环境安装

stlink驱动与make安装

  编译

  安装 

  第一种方式:回到bin的目录中安装

 第二种方式:将执行文件手动复制到指定路径

arm-none-eabi-gcc安装

 apt指令安装

离线安装

(1) 下载离线包

(2) 解压并安装

(3) 验证安装

         (4). 配置环境变量

         (5). 验证工具链完整性

      检查关键文件

      编译测试代码

openocd安装

1. 通过包管理器安装(推荐)

Ubuntu/Debian

Fedora

Arch Linux

2. 从源码编译安装(适合自定义功能或最新版本)

(1) 安装依赖

(2) 下载源码

(3) 配置和编译

(4) 安装到系统

3. 配置 udev 规则(解决权限问题)

4. 验证安装

(1) 检查版本

(2) 测试连接(以 ST-Link 和 STM32F1 为例)

5. 常见问题解决

Q1: 报错 No device found 或 Permission denied

Q2: 配置文件路径错误

Q3: 驱动冲突

6. 使用 OpenOCD 烧录/调试

(1) 烧录固件

(2) 启动 GDB 调试

7. 扩展配置

自定义配置文件

启用更多调试选项

二、标准库文件修改

三、Makefile文件修改

第一处----C源文件

第二处----启动汇编文件

第三处----宏定义

第四处----头文件路径

第五处----链接文件

第六处----清除指令

第七处----下载指令

注意事项


前言

前几天,学习了Makefile。了解到其批量编译的作用,尝试将其转移到STM32里面的过程。再不断探索的同时实现了再Window平台成功。不过我刚好有一块在咸鱼上捡漏得到的香橙派orangepiPC,里面安装的是ubantu系统,刚刚好拿来做这个实验。

本次使用的材料:

  1. Stlink-v2
  2. 香橙派orangepiPC
  3. 一台笔记本
  4. STM32F103C8T6
  5. STM32F103C6T6

一、环境配置

        这次我们需要三个编译环境arm-none-eabi-gcc,openocd,make,同时我们还需要上次在Window环境下的STM32的模板文件。这些文件,无论是在Window下还是Linux下都是互通的。

 前文疑云

        这里解答之前这两个文件的本身含义Windows环境中,脱离Keil,使用Makefile来编译标准库STM32工程 ---- STM32F103C8T6-优快云博客

        如果要脱离Keil软件,采用其它方式来编写STM32,比如这里使用GCC来编译,那么这两个文件是必不可少的。 

        这里简单过一下,我们需要一个STM32标准库函数的模板(无论是正点原子还是自己搞的,但是一定要有),然后去STM32CubeMx生成对应芯片的Make file工程模板。如果本身就有Makefile的模板,但是还是需要CubeMX的库,你可以没有软件,但是一定要有库,这点很关键!这点关系到你的这个方法能不能再其它芯片通用。

C:\Users\用户名\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\gcc 

这个库的默认安装路径一般再这里,如果你再cubemx在线下载库的话。

这是启动文件.s

这是链接文件 .ld

 

对应关系: 

链接脚本文件启动文件芯片类型Flash大小RAM大小
STM32F100XB_FLASH.ldstartup_stm32f100xb.sSTM32F100xB 系列(如 STM32F100C4, STM32F100R6)16KB - 128KB4KB - 8KB
STM32F100XE_FLASH.ldstartup_stm32f100xe.sSTM32F100xE 系列(如 STM32F100RC, STM32F100ZE)256KB - 512KB24KB - 32KB
STM32F101X6_FLASH.ldstartup_stm32f101x6.sSTM32F101x6 系列(如 STM32F101C4, STM32F101R6)16KB - 32KB4KB - 6KB
STM32F101XB_FLASH.ldstartup_stm32f101xb.sSTM32F101xB 系列(如 STM32F101C8, STM32F101RB)64KB - 128KB10KB - 16KB
STM32F101XE_FLASH.ldstartup_stm32f101xe.sSTM32F101xE 系列(如 STM32F101RC, STM32F101RE)256KB - 512KB32KB - 48KB
STM32F101XG_FLASH.ldstartup_stm32f101xg.sSTM32F101xG 系列(如 STM32F101RG, STM32F101VG)512KB - 1MB48KB - 80KB
STM32F102X6_FLASH.ldstartup_stm32f102x6.sSTM32F102x6 系列(如 STM32F102C4, STM32F102R6)16KB - 32KB4KB - 6KB
STM32F102XB_FLASH.ldstartup_stm32f102xb.sSTM32F102xB 系列(如 STM32F102C8, STM32F102RB)64KB - 128KB10KB - 16KB
STM32F103X6_FLASH.ldstartup_stm32f103x6.sSTM32F103x6 系列(如 STM32F103C6, STM32F103R6)32KB6KB
STM32F103XB_FLASH.ldstartup_stm32f103xb.sSTM32F103xB 系列(如 STM32F103C8, STM32F103RB)
(包含 STM32F103C8T6)
64KB - 128KB20KB
STM32F103XE_FLASH.ldstartup_stm32f103xe.sSTM32F103xE 系列(如 STM32F103RC, STM32F103RE)256KB - 512KB48KB - 64KB
STM32F103XG_FLASH.ldstartup_stm32f103xg.sSTM32F103xG 系列(如 STM32F103RG, STM32F103VG)512KB - 1MB64KB - 96KB
STM32F105XC_FLASH.ldstartup_stm32f105xc.sSTM32F105xC 系列(如 STM32F105R8, STM32F105VC)
(互联型,带 USB OTG)
64KB - 256KB64KB
STM32F107XC_FLASH.ldstartup_stm32f107xc.sSTM32F107xC 系列(如 STM32F107RB, STM32F107VC)
(互联型,带以太网)
256KB64KB

这里贴出我使用的Makefile文件,作为模板使用

##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.3.0-B58] date: [Fri Mar 14 19:48:43 CST 2025]
##########################################################################################################################

# ------------------------------------------------
# Generic Makefile (based on gcc)
#
# ChangeLog :
#	2017-02-10 - Several enhancements + project update mode
#   2015-07-22 - first version
# ------------------------------------------------

######################################
# target
######################################
TARGET = make_again


######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og


#######################################
# paths
#######################################
# Build path
BUILD_DIR = build

######################################
# source
######################################
#第一处需要修改的地方
# C sources
C_SOURCES =  \
$(wildcard ./CMSIS/*.c) \
$(wildcard ./Library/src/*.c) \
$(wildcard ./Library/inc/*.c) \
$(wildcard ./Start/*.c) \
$(wildcard ./User/*.c)

# ASM sources
#如果更换芯片,这里需要更换对应的芯片类型
ASM_SOURCES =  \
startup_stm32f103xb.s

# ASM sources
ASMM_SOURCES = 


#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
 
#######################################
# CFLAGS
#######################################
# cpu
CPU = -mcpu=cortex-m3

# fpu
# NONE for Cortex-M0/M0+/M3

# float-abi


# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# macros for gcc
# AS defines
AS_DEFS = 

# C defines
#第二处需要修改的地方
C_DEFS = \
-DSTM32F10X_MD\
-DUSE_STDPERIPH_DRIVER 



# AS includes
AS_INCLUDES = 

# C includes
#第三处需要修改的地方
C_INCLUDES =  \
-ICMSIS\
-ILibrary/inc\
-ILibrary/src\
-IStart\
-IUser


# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif


# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"


#######################################
# LDFLAGS
#######################################
#如果更换芯片,这里需要换对应的类型
# link script
LDSCRIPT = STM32F103C8Tx_FLASH.ld

# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin


#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMM_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@
	
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@	
	
$(BUILD_DIR):
	mkdir $@		

#######################################
# clean up
#######################################
#第四处需要修改的地方
ifeq ($(OS),Windows_NT)
    RM = rmdir /S /Q
else
    RM = rm -rf
endif

clean:
	-$(RM) $(BUILD_DIR)


#######################################
# download
#######################################
download:
	openocd -f "/usr/share/openocd/scripts/interface/stlink-v2.cfg" -f "/usr/share/openocd/scripts/target/stm32f1x.cfg" -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).hex verify reset" -c shutdown
  
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***

 环境安装

我们需要在Linux环境中安装三个主要的环境:

arm-none-eabi-gcc        ----        编译STM32的必要编译器

openocd                         ----        使用Stlink烧入的工具

make                                ----        批量编译文件的工具

在这里介绍Stlink驱动如何在Linux环境下编译安装

stlink驱动与make安装

这里stlink驱动与make同时安装是因为,在安装stlink要使用make或者cmake工具,所以这里一起下载。闲言到此,我们开始吧!这里使用的是ubantu环境。

        编译

        首先我们简单安装一下必要的依赖。按照下面顺序开始复制粘贴,如果提示某些软件并没有安装,那么就apt install xxx安装它。

sudo apt update  
sudo apt install git  cmake make gcc 
sudo apt install libusb-1.0-0-dev  libgtk-3-dev build-essential

        然后爬取stlink官方的源码,编译安装。当然如果自己有源码,那么你可以上传到ubantu上面然后编译安装,本质都是一样的。

git clone https://github.com/stlink-org/stlink

        爬完之后,简单看一下里面有什么。并且我们为什么要这样操作。 cd进去

cd stlink
ls -1

看到没,这里有一个Makefile文件哦,这里也就意味着,我们在本机使用make编译,然后生成stlink驱动,然后安装这个生成的驱动。如果有能力,你甚至可以自己去自定义自己的stlink驱动,这就是开源软件的魅力!好了,闲话少说,开始下一步,编译。

cmake .
make

编译完成之后,得看情况。有些正在这里会生成bin文件,有些人会生成build文件。这要根据你编译的文件有关,不过共同点是,在这个新生成的文件里面一直进去,一定有下面的文件

 这里面的bin有我们需要的东西。这些st开头的可执行文件。

        安装 

这里应该有两个安装方式,两个方法都可以试试。

        第一种方式:回到bin的目录中安装

        因为在生成的文件夹里面,也有一个Makefile文件,我们可以利用这个文件来操作。

sudo make install

 检验是否安装成功,在ubantu主机中插入stlink,然后执行

lsusb

如果显示如下,则代表安装成功。

 第二种方式:将执行文件手动复制到指定路径

cd bin
sudo cp st-* /usr/local/bin
cd ../lib
#这里个人认为,得看文件目录里面有没有lib64,如果没有,复制到lib路径试试
sudo cp *.so* /lib64

观察上面,它把*.so*文件复制到如下路径:

-- Up-to-date: /usr/local/lib/libstlink.so.1.8.0
-- Up-to-date: /usr/local/lib/libstlink.so.1
-- Up-to-date: /usr/local/lib/libstlink.so

 具体怎么解读,各位如果有知道的,可以告诉我。

最后判断是否安装成功的逻辑是一样的。

lsusb

到达这里,我们完成了stlink驱动的安装,还有make等工具安装。 

arm-none-eabi-gcc安装

arm-none-eabi-gcc有两种安装方式,apt指令安装,根据自己的情况,选择其中一个即可。

apt指令安装

如果直接输入

apt install arm-none-eabi-gcc

,可能系统或者软件源的关系,可能不能马上安装。

可以按照下面流程来安装:

apt search arm-gcc

这个命令可以找到对应本系统可以安装的软件,所以输入之后,找到对应的软件。然后安装

apt install arm-none-eabi-gcc

除了这个还要安装对应的库,建议直接执行下面的指令。一般就不会少东西了。

sudo apt update
sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi

这是卸载指令

sudo apt remove --purge gcc-arm-none-eabi
sudo rm -rf /usr/lib/arm-none-eabi /usr/lib/gcc/arm-none-eabi

离线安装

(1) 下载离线包

从其他设备访问 Arm GNU Toolchain Downloads,选择适合的版本:

  • Linux 64-bit: gcc-arm-none-eabi-<版本>-x86_64-linux.tar.bz2

  • Linux ARM 32-bit: gcc-arm-none-eabi-<版本>-aarch64-linux.tar.bz2(需要根据实际架构选择)

(2) 解压并安装

将下载的包复制到目标设备,解压并安装:

# 解压到 /opt
sudo tar -xjf gcc-arm-none-eabi-*.tar.bz2 -C /opt

# 创建符号链接
sudo ln -s /opt/gcc-arm-none-eabi-*/bin/* /usr/local/bin/

# 复制库文件到系统路径
sudo cp -r /opt/gcc-arm-none-eabi-*/arm-none-eabi/lib /usr/lib/arm-none-eabi/
(3) 验证安装
arm-none-eabi-gcc --version
# 输出应显示版本信息

ls /usr/lib/arm-none-eabi/lib/libc.a /usr/lib/arm-none-eabi/lib/crt0.o
# 确认标准库和启动文件存在

(4). 配置环境变量

将工具链路径添加到 PATH 中(如果未自动配置):

echo 'export PATH="/opt/gcc-arm-none-eabi/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

(5). 验证工具链完整性

检查关键文件
/usr/lib/arm-none-eabi/lib/libc.a       # C 标准库
/usr/lib/arm-none-eabi/lib/libm.a       # 数学库
/usr/lib/arm-none-eabi/lib/libnosys.a   # 裸机系统调用库
/usr/lib/arm-none-eabi/lib/crt0.o       # 启动文件
 编译测试代码

创建一个简单的测试程序 test.c

int main() 
{
    return 0;
}

编译并验证:

arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -specs=nosys.specs -TSTM32F103C8Tx_FLASH.ld test.c -o test.elf

如果编译成功且无报错,说明工具链安装完整。

openocd安装

1. 通过包管理器安装(推荐)

Ubuntu/Debian
sudo apt update
sudo apt install openocd
Fedora
sudo dnf install openocd
Arch Linux
sudo pacman -S openocd

2. 从源码编译安装(适合自定义功能或最新版本)

(1) 安装依赖
# Ubuntu/Debian
sudo apt install build-essential autoconf libtool pkg-config libusb-1.0-0-dev git

# Fedora
sudo dnf install gcc automake autoconf libtool pkgconfig libusb1-devel git

# Arch Linux
sudo pacman -S base-devel autoconf automake pkgconf libusb git
(2) 下载源码
git clone https://git.code.sf.net/p/openocd/code openocd
cd openocd
./bootstrap  # 生成配置脚本
(3) 配置和编译
./configure --enable-stlink --enable-jlink --enable-cmsis-dap
make -j$(nproc)
(4) 安装到系统
sudo make install

3. 配置 udev 规则(解决权限问题)

创建文件 /etc/udev/rules.d/90-openocd.rules,添加以下内容:

# ST-Link
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="0666", GROUP="plugdev"

# J-Link
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0101", MODE="0666", GROUP="plugdev"

# CMSIS-DAP(如 Raspberry Pi Pico)
ATTRS{idVendor}=="2e8a", MODE="0666", GROUP="plugdev"

重新加载规则:

sudo udevadm control --reload-rules
sudo udevadm trigger
sudo usermod -aG plugdev $USER  # 将当前用户加入 plugdev 组

4. 验证安装

(1) 检查版本
openocd --version
# 输出示例:Open On-Chip Debugger 0.12.0
(2) 测试连接(以 ST-Link 和 STM32F1 为例)
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

成功连接后输出类似:

Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

5. 常见问题解决

Q1: 报错 No device found 或 Permission denied
  • 检查权限

    lsusb | grep "ST-Link\|J-Link"  # 确认设备识别
    groups  # 确认用户是否在 plugdev 组
  • 重新加载 udev 规则

    sudo udevadm control --reload
    sudo udevadm trigger
Q2: 配置文件路径错误
  • 查找配置文件路径

    find /usr -name "stlink-v2.cfg"  # 包管理器安装的路径
    find /usr/local -name "stlink-v2.cfg"  # 源码安装的路径
  • 指定完整路径

    openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f target/stm32f1x.cfg
Q3: 驱动冲突
  • 禁用 ModemManager(部分系统会占用 USB 设备):

    sudo systemctl stop ModemManager
    sudo systemctl disable ModemManager

6. 使用 OpenOCD 烧录/调试

(1) 烧录固件
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
  -c "program firmware.bin exit 0x08000000"
(2) 启动 GDB 调试
arm-none-eabi-gdb firmware.elf
(gdb) target extended-remote :3333
(gdb) monitor reset halt
(gdb) load
(gdb) continue

7. 扩展配置

自定义配置文件

创建自定义配置文件(如 my_board.cfg),定义接口和目标:

# my_board.cfg
source [find interface/stlink-v2.cfg]
source [find target/stm32f1x.cfg]

运行:

openocd -f my_board.cfg
启用更多调试选项

在配置命令中添加参数:

# 启用详细日志
openocd -d3 -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

# 指定自定义端口
openocd -c "gdb_port 3334" -c "telnet_port 4445" -f ...

通过以上步骤,你可以在 Linux 上完成 OpenOCD 的安装和基础配置,支持 STM32 等设备的调试与烧录。

二、标准库文件修改

这里的情况与前文在Window下的环境遇到的问题类似,

Windows环境中,脱离Keil,使用Makefile来编译标准库STM32工程 ---- STM32F103C8T6-优快云博客这里依然需要采用换函数的办法。因为我目前除了把那两个函数删掉,就是换函数。

找到你的STM32的工程模板,然后找到core_cm3。然后再大概730多行的地方,把这两个函数换掉。

//换完之后
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
    uint32_t result;
    register uint8_t *tmp_addr asm("r1") = addr;
    register uint8_t tmp_value asm("r2") = value;

    __ASM volatile (
        "strexb %0, %2, [%1]"
        : "=r" (result)
        : "r" (tmp_addr), "r" (tmp_value)
        : // No clobbered registers
    );
    return result;
}

uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
    uint32_t result;
    register uint16_t *tmp_addr asm("r1") = addr;
    register uint16_t tmp_value asm("r2") = value;

    __ASM volatile (
        "strexh %0, %2, [%1]"
        : "=r" (result)
        : "r" (tmp_addr), "r" (tmp_value)
        : // No clobbered registers
    );
    return result;
}

换掉之后,这里的任务就完成了。 

三、Makefile文件修改

Makefile文件,修改。这里有些细节还是必须修改的。这里主要有7处必须改的地方,我会一一指出。其中4个与前文是类似的。Windows环境中,脱离Keil,使用Makefile来编译标准库STM32工程 ---- STM32F103C8T6-优快云博客

那么开始吧!

如果文件结构与我一样,就按照我的规则来。改成我们模式,这里可以以点带面,你可以模仿我来改自己的makefile文件!

第一处----C源文件

全部路径加入,不过里面有没有.C文件。两个字:省事!

# C sources
C_SOURCES =  \
$(wildcard ./CMSIS/*.c) \
$(wildcard ./Library/src/*.c) \
$(wildcard ./Library/inc/*.c) \
$(wildcard ./Start/*.c) \
$(wildcard ./User/*.c)

第二处----启动汇编文件

这个没有技巧,只能去找自己芯片适配的启动文件。这里这个启动文件刚好适配STM32F103C8T6.

链接脚本文件启动文件芯片类型Flash大小RAM大小
STM32F100XB_FLASH.ldstartup_stm32f100xb.sSTM32F100xB 系列(如 STM32F100C4, STM32F100R6)16KB - 128KB4KB - 8KB
STM32F100XE_FLASH.ldstartup_stm32f100xe.sSTM32F100xE 系列(如 STM32F100RC, STM32F100ZE)256KB - 512KB24KB - 32KB
STM32F101X6_FLASH.ldstartup_stm32f101x6.sSTM32F101x6 系列(如 STM32F101C4, STM32F101R6)16KB - 32KB4KB - 6KB
STM32F101XB_FLASH.ldstartup_stm32f101xb.sSTM32F101xB 系列(如 STM32F101C8, STM32F101RB)64KB - 128KB10KB - 16KB
STM32F101XE_FLASH.ldstartup_stm32f101xe.sSTM32F101xE 系列(如 STM32F101RC, STM32F101RE)256KB - 512KB32KB - 48KB
STM32F101XG_FLASH.ldstartup_stm32f101xg.sSTM32F101xG 系列(如 STM32F101RG, STM32F101VG)512KB - 1MB48KB - 80KB
STM32F102X6_FLASH.ldstartup_stm32f102x6.sSTM32F102x6 系列(如 STM32F102C4, STM32F102R6)16KB - 32KB4KB - 6KB
STM32F102XB_FLASH.ldstartup_stm32f102xb.sSTM32F102xB 系列(如 STM32F102C8, STM32F102RB)64KB - 128KB10KB - 16KB
STM32F103X6_FLASH.ldstartup_stm32f103x6.sSTM32F103x6 系列(如 STM32F103C6, STM32F103R6)32KB6KB
STM32F103XB_FLASH.ldstartup_stm32f103xb.sSTM32F103xB 系列(如 STM32F103C8, STM32F103RB)
(包含 STM32F103C8T6)
64KB - 128KB20KB
STM32F103XE_FLASH.ldstartup_stm32f103xe.sSTM32F103xE 系列(如 STM32F103RC, STM32F103RE)256KB - 512KB48KB - 64KB
STM32F103XG_FLASH.ldstartup_stm32f103xg.sSTM32F103xG 系列(如 STM32F103RG, STM32F103VG)512KB - 1MB64KB - 96KB
STM32F105XC_FLASH.ldstartup_stm32f105xc.sSTM32F105xC 系列(如 STM32F105R8, STM32F105VC)
(互联型,带 USB OTG)
64KB - 256KB64KB
STM32F107XC_FLASH.ldstartup_stm32f107xc.sSTM32F107xC 系列(如 STM32F107RB, STM32F107VC)
(互联型,带以太网)
256KB64KB

所以这里选择startup_stm32f103xb.s,如果你的文件不在User、CMSIS外层,那么你也应该加入对应的路径,比如:它再User里面的话,这里就要改成:

./User/startup_stm32f103xb.s

这里其实可以以点带面去找到其它芯片对应的文件,进而再理论上来说,所有的STM32应该都可以通过这种方式去编译!

# ASM sources
ASM_SOURCES =  \
startup_stm32f103xb.s

第三处----宏定义

编译STM32修改定义对应的宏,这里定义了两个宏。如果是其它系列的芯片,这里也是要更改的。这里务必注意。

STM32F10X_MD        表明本次使用的是F10X系列的芯片,中等规格

USE_STDPERIPH_DRIVER        表明使用标准库函数来编译

# C defines
#第二处需要修改的地方
C_DEFS = \
-DSTM32F10X_MD\
-DUSE_STDPERIPH_DRIVER 

第四处----头文件路径

全部路径加入,不过里面有没有.H文件。两个字:省事!

# C includes
#第三处需要修改的地方
C_INCLUDES =  \
-ICMSIS\
-ILibrary/inc\
-ILibrary/src\
-IStart\
-IUser

第五处----链接文件

这个没有技巧,只能去找自己芯片适配的链接文件。这里这个启动文件刚好适配STM32F103C8T6.这个与启动文件是息息相关的,相互存在。至少再gcc环境下编译,这两个文件缺一不可。

#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = STM32F103C8Tx_FLASH.ld

第六处----清除指令

封装一下清除指令,提高一下再Window与Linux系统的兼容性。

执行时,只需要:

make clean
#######################################
# clean up
#######################################
#第四处需要修改的地方
ifeq ($(OS),Windows_NT)
    RM = rmdir /S /Q
else
    RM = rm -rf
endif

clean:
	-$(RM) $(BUILD_DIR)

第七处----下载指令

 每次执行下载,都要输入长长的一段openocd的指令,那么我们封装起来,不是更好。

执行命令:

make download

这是烧录二进制文件,要指定起始地址烧录,一般地址是0x08000000

#######################################
# download
#######################################
download:
	openocd -f "/usr/share/openocd/scripts/interface/stlink-v2.cfg" -f "/usr/share/openocd/scripts/target/stm32f1x.cfg" -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).bin 0x08000000 verify reset" -c shutdown

下面为烧录十六进制文件,不用指定起始地址。

#######################################
# download
#######################################
download:
	openocd -f "/usr/share/openocd/scripts/interface/stlink-v2.cfg" -f "/usr/share/openocd/scripts/target/stm32f1x.cfg" -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).hex verify reset" -c shutdown

这里也是贴出完整的配置的Make file文件,这个和前面那个基本差不多。

##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.3.0-B58] date: [Fri Mar 14 19:48:43 CST 2025]
##########################################################################################################################

# ------------------------------------------------
# Generic Makefile (based on gcc)
#
# ChangeLog :
#	2017-02-10 - Several enhancements + project update mode
#   2015-07-22 - first version
# ------------------------------------------------

######################################
# target
######################################
TARGET = make_again


######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og


#######################################
# paths
#######################################
# Build path
BUILD_DIR = build

######################################
# source
######################################
#第一处需要修改的地方
# C sources
C_SOURCES =  \
$(wildcard ./CMSIS/*.c) \
$(wildcard ./Library/src/*.c) \
$(wildcard ./Library/inc/*.c) \
$(wildcard ./Start/*.c) \
$(wildcard ./User/*.c)

# ASM sources
ASM_SOURCES =  \
startup_stm32f103xb.s

# ASM sources
ASMM_SOURCES = 


#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
 
#######################################
# CFLAGS
#######################################
# cpu
CPU = -mcpu=cortex-m3

# fpu
# NONE for Cortex-M0/M0+/M3

# float-abi


# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# macros for gcc
# AS defines
AS_DEFS = 

# C defines
#第二处需要修改的地方
C_DEFS = \
-DSTM32F10X_MD\
-DUSE_STDPERIPH_DRIVER 



# AS includes
AS_INCLUDES = 

# C includes
#第三处需要修改的地方
C_INCLUDES =  \
-ICMSIS\
-ILibrary/inc\
-ILibrary/src\
-IStart\
-IUser


# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif


# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"


#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = STM32F103C8Tx_FLASH.ld

# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin


#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMM_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@
	
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@	
	
$(BUILD_DIR):
	mkdir $@		

#######################################
# clean up
#######################################
#第四处需要修改的地方
ifeq ($(OS),Windows_NT)
    RM = rmdir /S /Q
else
    RM = rm -rf
endif

clean:
	-$(RM) $(BUILD_DIR)


#######################################
# download
#######################################
download:
	openocd -f "/usr/share/openocd/scripts/interface/stlink-v2.cfg" -f "/usr/share/openocd/scripts/target/stm32f1x.cfg" -c init -c halt -c "program $(BUILD_DIR)/$(TARGET).hex verify reset" -c shutdown
  
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***

注意事项

1.对应的芯片,对应的启动文件与链接文件。不能弄混,不然跑的程序即便烧录也可能无法显示出理想的状况。不过貌似同系列更高规格的程序兼容低规格的程序,比如:STM32F103C8T6兼容STM32F103C6T6的程序,不过低规格无法兼容高规格。

2.用apt安装arm-none-eabi-gcc时,一定要把对应的库也安装。工具链一定要完整,否则会出现各种问题让你无法通过编译。

3.目前只在STM32F103C8T6与STM32F103C6T6上实现,不过理论上,这套方法应该可以兼容全系列的芯片。受限于环境,各位可以勇敢的去尝试。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值