本次主要是试验独自编写Makefile来适配AT32F415RCT6在Linux 上面的开发环境,本身不是一件麻烦事,但是操作过程里面粗心在链接的时候少了一个指令导致编译出来的文件无法执行。借此机会记录一下整个搭建过程以及ISP下载脚本设置方法。
整个项目比较简单,外设初始化使用雅特力自家的AT32_WorkBench套件来自动生成,主要是初始化GPIOA1,A2->push pull output 推挽输出。然后控制A1拉高点亮一个LED。
![](https://img-blog.csdnimg.cn/direct/32641a5d629143efb5e9b61de2264046.png)
这个套件它不像STM32的CubeMX一样可以连带构建系统一起生成,所以像Makefile,CMake这些构建方式都是需要自己配置的。
生成的目录主要是关注AT32自带的库文件、启动文件还有链接文件,库文件在./libraries/drivers/src下面,链接文件在./project/AT32_IDE/ldscripts/AT32F415xC_FLASH.ld,启动文件在./project/AT32_IDE/startup_at32f415.s。
接下来就是设计makefile,在这之前默认我们已经安装好arm-none-eabi-gcc交叉编译工具链。那么makefile里面主要是设置编译参数和链接参数。这些的话一般都是比较规律的,在工具连的目录下面也能找到一些example。
首先是单个.c的文件编译,编译参数如下:
-mcpu=cortex-m4 $(INCLUDES) $(DEFINE) -mthumb -mthumb-interwork -fdata-sections -ffunction-sections -fno-common -MD -Wall -Os -mapcs-frame
比较关键的是-mcpu,-mthumb(使用thumb指令集),-mthumb-interwork允许ARM指令和thumb指令之间的跳转,-O优化等级,其它的指令是辅助指令,可以挨个百度搜
然后是链接参数:
-T$(LINKER) -mcpu=cortex-m4 -mthumb -O0 -ffunction-sections -g -Wl,-Map,$(TARGET_NAME).map -Wl,--gc-sections --specs=nano.specs --specs=nosys.specs -Xlinker
-T接链接文件,这里-mcpu是可以不要的,只要前面单个文件编译的时候带上就可以了,但是后面的-mthumb必须带上,否则编译出来的文件是无法执行的(我就是栽在这里了)
最后贴上整个Makefile文件(其实可以直接%.c:%.o的只是我那个时候比较蛋疼)
TARGET_NAME = AT32Test
WORKDIR=..
TOOLCHAINS=arm-none-eabi-
CC=$(TOOLCHAINS)gcc
CXX=$(TOOLCHAINS)g++
LD=$(TOOLCHAINS)gcc
AR=$(TOOLCHAINS)ar
AS=$(TOOLCHAINS)as
OBJCOPY=$(TOOLCHAINS)objcopy
OBJECT = \
driver_adc.o \
driver_gpio.o \
driver_timer.o \
driver_usart.o \
driver_systemClock.o \
driver_systemInit.o \
driver_systemEtc.o \
driver_flash.o \
driver_spi.o \
driver_can.o \
driver_cmp.o \
driver_i2c.o \
driver_misc.o \
driver_rtc.o \
driver_dma.o \
driver_debug.o \
driver_sdio.o \
driver_pwc.o \
wk_int.o \
wk_config.o \
main.o \
# user code start
#user code end
STARTUP=startup.o
STARTUP_PATH=$(WORKDIR)/project/AT32_IDE/
LINKER=$(WORKDIR)/project/AT32_IDE/ldscripts/AT32F415xC_FLASH.ld
ARCH=cortex-m4
FLOAT_UNIT= -mfloat-abi=hard
LD_FLAGS= -mcpu=$(ARCH) -mthumb -O0 -ffunction-sections -g -Wl,-Map,$(TARGET_NAME).map -Wl,--gc-sections --specs=nano.specs --specs=nosys.specs -Xlinker
DEFINE=-DAT32F415RCT7 \
-DUSE_STDPERIPH_DRIVER \
-DAT_START_F415_V1
ASM_OBJECT_OPTION = -mcpu=$(ARCH)
INCLUDES= \
-I$(WORKDIR)/libraries/cmsis/cm4/core_support \
-I$(WORKDIR)/libraries/cmsis/cm4/device_support \
-I$(WORKDIR)/libraries/cmsis/cm4 \
-I$(WORKDIR)/libraries/drivers/inc \
-I$(WORKDIR)/project/inc \
-I$(WORKDIR)/project/src
C_FLAGS= -mcpu=$(ARCH) $(INCLUDES) $(DEFINE) -mthumb -mthumb-interwork -fdata-sections -ffunction-sections -fno-common -MD -Wall -Os -mapcs-frame
DRIVER_SRC_PATH=$(WORKDIR)/libraries/drivers/src
DRIVER_DRC_PRIX=at32f415_
USER_SRC_PATH=$(WORKDIR)/project/src
build: $(TARGET_NAME).elf $(TARGET_NAME).hex $(TARGET_NAME).bin
echo Build succee!
$(TARGET_NAME).elf:$(OBJECT) $(STARTUP)
$(CC) -T$(LINKER) $(LD_FLAGS) $^ -o $(TARGET_NAME).elf
$(TARGET_NAME).hex:$(TARGET_NAME).elf
$(OBJCOPY) -O ihex $(TARGET_NAME).elf $(TARGET_NAME).hex
$(TARGET_NAME).bin:$(TARGET_NAME).hex
$(OBJCOPY) -O binary $(TARGET_NAME).elf $(TARGET_NAME).bin
clean:
rm -f *.o
rm -f *.d
rm -f $(TARGET_NAME).elf
rm -f $(TARGET_NAME).hex
rm -f $(TARGET_NAME).bin
rm -f $(TARGET_NAME).map
startup.o:$(STARTUP_PATH)/startup_at32f415.s
$(AS) $(ASM_OBJECT_OPTION) $(STARTUP_PATH)/startup_at32f415.s -o startup.o
driver_adc.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)adc.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)adc.c -o driver_adc.o
driver_gpio.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)gpio.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)gpio.c -o driver_gpio.o
driver_timer.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)tmr.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)tmr.c -o driver_timer.o
driver_usart.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)usart.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)usart.c -o driver_usart.o
driver_systemClock.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)crc.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)crc.c -o driver_systemClock.o
driver_systemInit.o:$(WORKDIR)/libraries/cmsis/cm4/device_support/system_at32f415.c
$(CC) $(C_FLAGS) -c $(WORKDIR)/libraries/cmsis/cm4/device_support/system_at32f415.c -o driver_systemInit.o
driver_systemEtc.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)crm.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)crm.c -o driver_systemEtc.o
# driver_iic.o:
# $(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX).c
driver_flash.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)flash.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)flash.c -o driver_flash.o
driver_spi.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)spi.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)spi.c -o driver_spi.o
driver_can.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)can.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)can.c -o driver_can.o
driver_cmp.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)cmp.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)cmp.c -o driver_cmp.o
driver_i2c.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)i2c.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)i2c.c -o driver_i2c.o
driver_misc.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)misc.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)misc.c -o driver_misc.o
driver_rtc.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)ertc.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)ertc.c -o driver_rtc.o
driver_dma.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)dma.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)dma.c -o driver_dma.o
driver_debug.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)debug.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)debug.c -o driver_debug.o
driver_sdio.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)sdio.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)sdio.c -o driver_sdio.o
driver_pwc.o:$(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)pwc.c
$(CC) $(C_FLAGS) -c $(DRIVER_SRC_PATH)/$(DRIVER_DRC_PRIX)pwc.c -o driver_pwc.o
main.o:$(USER_SRC_PATH)/main.c
$(CC) $(C_FLAGS) -c $(USER_SRC_PATH)/main.c -o main.o
wk_int.o:$(USER_SRC_PATH)/at32f415_int.c
$(CC) $(C_FLAGS) -c $(USER_SRC_PATH)/at32f415_int.c -o wk_int.o
wk_config.o:$(USER_SRC_PATH)/at32f415_wk_config.c
$(CC) $(C_FLAGS) -c $(USER_SRC_PATH)/at32f415_wk_config.c -o wk_config.o
执行make就可以完成项目编译。这里生成AT32Test.elf,AT32Test.hex,AT32Test.bin三个文件
接下来讨论ISP烧录,AT32_ISP_Console可以在官网下载到(Linux没有GUI版),接包之后里面都user manual但是这个网上都已经有很大篇幅了,我直接给出一个能用的DFU下载脚本:
./AT32_ISP_Console.sh
export LD_LIBRARY_PATH=$(pwd)
./AT32_ISP_Console -dfu -e --all -d --a 0x08000000 --fn /home/charx/Workspace/AT32Test/AT32F415RCT7_WorkBench_template/Build/AT32Test.hex --v
-d是烧录,--a指明地址,这个参数只对.bin文件有效,hex和elf文件是自带地址信息的,--fn接着-d的指令,属于-d的子指令,指明文件位置。-e 表示擦除, -e --all表示全片擦除,最后的--v表示烧录完成后校验。
直接sudo ./DFU_Download.sh即可(先chmod +x)