技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 304|回复: 2
收起左侧

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

[复制链接]

991

主题

2181

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16053 个
贡献
31093 次
宅之契约
0 份
在线时间
1532 小时
注册时间
2014-1-26
发表于 2018-1-5 09:08:46 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
原文链接: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写寄存器太麻烦,如果想要快速上手的话用它的驱动比较好。
而如果你要使用它的驱动的话,你首先得先办法编译它的那一票源码文件。
  1. misc.c
  2. stm32f10x_adc.c
  3. stm32f10x_bkp.c
  4. stm32f10x_can.c
  5. stm32f10x_cec.c
  6. stm32f10x_crc.c
  7. stm32f10x_dac.c
  8. stm32f10x_dbgmcu.c
  9. stm32f10x_dma.c
  10. stm32f10x_exti.c
  11. stm32f10x_flash.c
  12. stm32f10x_fsmc.c
  13. stm32f10x_gpio.c
  14. stm32f10x_i2c.c
  15. stm32f10x_iwdg.c
  16. stm32f10x_pwr.c
  17. stm32f10x_rcc.c
  18. stm32f10x_rtc.c
  19. stm32f10x_sdio.c
  20. stm32f10x_spi.c
  21. stm32f10x_tim.c
  22. stm32f10x_usart.c
  23. stm32f10x_wwdg.c
复制代码
除了以上这些以外,你还需要编译system_stm32f10x.c和core_cm3.c,这两个是CMSIS提供的,被STM32F10x外设驱动依赖。

然而在编译core_cm3.c的时候,你会发现它报了个错:
  1. C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s: Assembler messages:
  2. C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s:395: Error: registers may not be the same -- `strexb r0,r0,[r1]'
  3. C:\Users\0xAA55\AppData\Local\Temp\ccW3bJEk.s:414: Error: registers may not be the same -- `strexh r0,r0,[r1]'
  4. 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脚本如下:
[Plain Text] 纯文本查看 复制代码
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 个宅币)

34

主题

129

帖子

6810

积分

用户组: 管理员

UID
77
精华
11
威望
112 点
宅币
6273 个
贡献
129 次
宅之契约
0 份
在线时间
83 小时
注册时间
2014-2-22
发表于 2018-1-5 13:28:03 | 显示全部楼层
虽然看不懂,还是顶一下。

1

主题

16

帖子

87

积分

用户组: 小·技术宅

UID
2054
精华
0
威望
2 点
宅币
67 个
贡献
0 次
宅之契约
0 份
在线时间
9 小时
注册时间
2016-11-10
发表于 2018-1-25 20:17:24 | 显示全部楼层
学习一波写启动文件
不过话说大多写32的好像还是keil用的多
PS:什么时候出个HAL的吧(逃)

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-6-22 13:43 , Processed in 0.103562 second(s), 18 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表