0xAA55 发表于 2018-1-5 09:08:46

【嵌入式】编译坑爹的STM32F10x外设驱动

原文链接:https://www.0xaa55.com/thread-14843-1-1.html
转载请保留出处。

为啥要说“坑爹的”呢?因为CMSIS给STM32F10x提供的硬件支持的core_cm3.c源码有个N年老BUG没修了。

注:CMSIS全称是“Cortex Microcontroller Software Interface Standard”(相关资料:https://developer.arm.com/embedded/cmsis)

接上文(此处传送门)所说的“STM32F10x的官方头文件声明定义”(下载页面在此)里面提供了STM32F10x系列单片机的外设“驱动”——也就是把PDF所说的功能,用C语言封装成函数给你用。它提供的教程都是基于它这个驱动的,自己啃PDF写寄存器太麻烦,如果想要快速上手的话用它的驱动比较好。
而如果你要使用它的驱动的话,你首先得先办法编译它的那一票源码文件。misc.c
stm32f10x_adc.c
stm32f10x_bkp.c
stm32f10x_can.c
stm32f10x_cec.c
stm32f10x_crc.c
stm32f10x_dac.c
stm32f10x_dbgmcu.c
stm32f10x_dma.c
stm32f10x_exti.c
stm32f10x_flash.c
stm32f10x_fsmc.c
stm32f10x_gpio.c
stm32f10x_i2c.c
stm32f10x_iwdg.c
stm32f10x_pwr.c
stm32f10x_rcc.c
stm32f10x_rtc.c
stm32f10x_sdio.c
stm32f10x_spi.c
stm32f10x_tim.c
stm32f10x_usart.c
stm32f10x_wwdg.c除了以上这些以外,你还需要编译system_stm32f10x.c和core_cm3.c,这两个是CMSIS提供的,被STM32F10x外设驱动依赖。

然而在编译core_cm3.c的时候,你会发现它报了个错:C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s: Assembler messages:
C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s:395: Error: registers may not be the same -- `strexb r0,r0,'
C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s:414: Error: registers may not be the same -- `strexh r0,r0,'
make: *** 错误 1我用谷歌搜了一下,这是个BUG,目测粗心所致。

修改的方法:打开core_cm3.c(打开之前先去掉它的“只读”属性),找到第736行:

__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );

把"=r" 改成 "=&r",如下:

__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );

然后找到第753行,改法相同:

__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );

改成

__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );

保存,然后恢复它的只读属性。

这样就可以编译通过了。

我的makefile脚本如下:GCC_PREFIX ?= arm-none-eabi-

CC = $(GCC_PREFIX)gcc
LD = $(GCC_PREFIX)ld
AR = $(GCC_PREFIX)ar
RANLIB = $(GCC_PREFIX)ranlib
RM = del /f /q

STDPERIPH_PATH=STM32F10x_StdPeriph_Driver/
CMSIS_CORE_PATH=CMSIS/CM3/CoreSupport/
CMSIS_DEVICE_PATH=CMSIS/CM3/DeviceSupport/ST/STM32F10x/

INCLUDES += -I$(CURDIR)/
INCLUDES += -I$(STDPERIPH_PATH)inc/
INCLUDES += -I$(CMSIS_CORE_PATH)
INCLUDES += -I$(CMSIS_DEVICE_PATH)

CFLAGS=-Wall -Wno-main -mcpu=cortex-m3 -mthumb -Os $(INCLUDES) -DSTM32F10X_MD -DUSE_SWD_JTAG -DUSE_STDPERIPH_DRIVER -DRELEASE_BUILD

OBJS += $(STDPERIPH_PATH)src/misc.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_adc.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_bkp.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_can.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_cec.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_crc.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_dac.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_dbgmcu.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_dma.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_exti.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_flash.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_fsmc.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_gpio.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_i2c.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_iwdg.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_pwr.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_rcc.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_rtc.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_sdio.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_spi.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_tim.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_usart.o
OBJS += $(STDPERIPH_PATH)src/stm32f10x_wwdg.o

OBJS += $(CMSIS_CORE_PATH)core_cm3.o

OBJS += $(CMSIS_DEVICE_PATH)system_stm32f10x.o

stm32f10x.a: $(OBJS)
        $(AR) rcu $@ $+
        $(RANLIB) $@
       
.PHONY: clean
clean: deleter.bat
        $^
        $(RM) $^

deleter.bat:
        echo set "del_list=stm32f10x.a $(OBJS)" > $@
        echo set "del_list=%%del_list:/=\%%" >> $@
        echo $(RM) %%del_list%% >> $@注意clean那里我遇到了Windows下del命令不认正斜杠的路径的问题——它认为正斜杠是用来表示命令参数的,而不是路径。但为了能跨平台编译,我写makefile都用正斜杠。

我的解决办法是先让makefile生成一个“删除器”,然后在删除器里用批处理命令把斜杠替换一下,再调用del命令删除文件。最后删除这个“删除器”。

在CMSIS提供的文件里,CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup里面有STM32F10x的启动部分的代码,包括中断表的弱符号等。这些启动部分的代码是用汇编写的,但有些地方它多余了——明明都是死循环,只用一个B .就可以了啊,为啥要写多个呢?所以我自己写了一个自己的启动部分的代码,是C的。请看上一篇文章。

附件:
描述:已编译好的坑爹的STM32F10x外设驱动

参考资料:
http://www.cesareriva.com/fix-registers-may-not-be-the-same-error/
https://www.0xaa55.com/thread-10968-1-1.html

Golden Blonde 发表于 2018-1-5 13:28:03

虽然看不懂,还是顶一下。

大能猫 发表于 2018-1-25 20:17:24

学习一波写启动文件
不过话说大多写32的好像还是keil用的多
PS:什么时候出个HAL的吧(逃)
页: [1]
查看完整版本: 【嵌入式】编译坑爹的STM32F10x外设驱动