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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3022|回复: 2

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

[复制链接]
发表于 2018-1-5 09:08:46 | 显示全部楼层 |阅读模式

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

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

×
原文链接: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脚本如下:
  1. GCC_PREFIX ?= arm-none-eabi-

  2. CC = $(GCC_PREFIX)gcc
  3. LD = $(GCC_PREFIX)ld
  4. AR = $(GCC_PREFIX)ar
  5. RANLIB = $(GCC_PREFIX)ranlib
  6. RM = del /f /q

  7. STDPERIPH_PATH=STM32F10x_StdPeriph_Driver/
  8. CMSIS_CORE_PATH=CMSIS/CM3/CoreSupport/
  9. CMSIS_DEVICE_PATH=CMSIS/CM3/DeviceSupport/ST/STM32F10x/

  10. INCLUDES += -I$(CURDIR)/
  11. INCLUDES += -I$(STDPERIPH_PATH)inc/
  12. INCLUDES += -I$(CMSIS_CORE_PATH)
  13. INCLUDES += -I$(CMSIS_DEVICE_PATH)

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

  15. OBJS += $(STDPERIPH_PATH)src/misc.o
  16. OBJS += $(STDPERIPH_PATH)src/stm32f10x_adc.o
  17. OBJS += $(STDPERIPH_PATH)src/stm32f10x_bkp.o
  18. OBJS += $(STDPERIPH_PATH)src/stm32f10x_can.o
  19. OBJS += $(STDPERIPH_PATH)src/stm32f10x_cec.o
  20. OBJS += $(STDPERIPH_PATH)src/stm32f10x_crc.o
  21. OBJS += $(STDPERIPH_PATH)src/stm32f10x_dac.o
  22. OBJS += $(STDPERIPH_PATH)src/stm32f10x_dbgmcu.o
  23. OBJS += $(STDPERIPH_PATH)src/stm32f10x_dma.o
  24. OBJS += $(STDPERIPH_PATH)src/stm32f10x_exti.o
  25. OBJS += $(STDPERIPH_PATH)src/stm32f10x_flash.o
  26. OBJS += $(STDPERIPH_PATH)src/stm32f10x_fsmc.o
  27. OBJS += $(STDPERIPH_PATH)src/stm32f10x_gpio.o
  28. OBJS += $(STDPERIPH_PATH)src/stm32f10x_i2c.o
  29. OBJS += $(STDPERIPH_PATH)src/stm32f10x_iwdg.o
  30. OBJS += $(STDPERIPH_PATH)src/stm32f10x_pwr.o
  31. OBJS += $(STDPERIPH_PATH)src/stm32f10x_rcc.o
  32. OBJS += $(STDPERIPH_PATH)src/stm32f10x_rtc.o
  33. OBJS += $(STDPERIPH_PATH)src/stm32f10x_sdio.o
  34. OBJS += $(STDPERIPH_PATH)src/stm32f10x_spi.o
  35. OBJS += $(STDPERIPH_PATH)src/stm32f10x_tim.o
  36. OBJS += $(STDPERIPH_PATH)src/stm32f10x_usart.o
  37. OBJS += $(STDPERIPH_PATH)src/stm32f10x_wwdg.o

  38. OBJS += $(CMSIS_CORE_PATH)core_cm3.o

  39. OBJS += $(CMSIS_DEVICE_PATH)system_stm32f10x.o

  40. stm32f10x.a: $(OBJS)
  41.         $(AR) rcu $@ $+
  42.         $(RANLIB) $@
  43.        
  44. .PHONY: clean
  45. clean: deleter.bat
  46.         $^
  47.         $(RM) $^

  48. deleter.bat:
  49.         echo set "del_list=stm32f10x.a $(OBJS)" > $@
  50.         echo set "del_list=%%del_list:/=\%%" >> $@
  51.         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
回复

使用道具 举报

发表于 2018-1-5 13:28:03 | 显示全部楼层
虽然看不懂,还是顶一下。
回复 赞! 靠!

使用道具 举报

发表于 2018-1-25 20:17:24 | 显示全部楼层
学习一波写启动文件
不过话说大多写32的好像还是keil用的多
PS:什么时候出个HAL的吧(逃)
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-23 19:48 , Processed in 0.034662 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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