- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
原文链接: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,[r1]'
- C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s:414: Error: registers may not be the same -- `strexh r0,r0,[r1]'
- make: *** [CMSIS/CM3/CoreSupport/core_cm3.o] 错误 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_StdPeriph_Driver_Compile.zip
(425.78 KB, 下载次数: 1, 售价: 1 个宅币)
描述:已编译好的坑爹的STM32F10x外设驱动
参考资料:
http://www.cesareriva.com/fix-re ... -be-the-same-error/
https://www.0xaa55.com/thread-10968-1-1.html |
|