Linux下开发stm32 ④ | 标准固件库工程开发

2020-07-16 10:05:56 浏览数 (1)

st官方固件库是在寄存器操作之上的,但是使用寄存器操作的话,需要注意的地方很多,需要对照参考手册一个一个赋值,稍有不慎便会出错,所以固件库将外设的初始化封装成初始化结构体,将外设的操作封装在函数中,将寄存器赋值的操作都封装起来,我们只需要调用API就可以,这样一来既提高了开发效率,也减少了代码量,如果还不能在MDK里熟练使用固件库编程,建议先补基础~接下来,我们在上一节寄存器工程的基础上,添加固件库,使用固件库进行开发。

1.创建固件库工程

将上一节的寄存器工程复制过来,改名为03-template-lib,然后再其中创建如下目录结构,便于工程管理:

  • startup:存放启动文件
  • cmsis:stm32固件库中的cmsis支持库
  • libraries:stm32固件库中的外设驱动库
  • user:存放用户自己的文件
  • doc:存放说明文档

然后就开始从固件库中复制文件了:

  • startup:直接将工程中的已有启动文件startup_stm32f10x_hd移动进去即可;
  • cmsis:将工程中已有的内核支持文件core_cm3.h(不要从固件库中添加core_cm3.c进去,添加后编译会出错), 时钟配置文件system_stm32f10x.hsystem_stm32f10x.c(从固件库中复制),以及stm32头文件stm32f10x.h
  • libraries:这个直接将固件库中STM32F10X_StdPeriph_Driver中的内容拷贝过来即可:
  • user:因为使用了固件库,所以将固件库配置头文件stm32f10x_conf.h,中断服务程序文件stm32f10x_it.hstm32f10x_it.c都复制进去,这些文件从固件库的project/STM32F10X_StdPeriph_Template中复制,最后将我们工程中已有的main文件复制进去:

到这里,我们的工程模板就建好了,然后就是编写makefile来编译整个工程了:

2.编译固件库工程

固件库编译的时候有几点需要注意两点:

  1. 文件和makefile不是同一个目录时,如何告诉makefile找到头文件呢?
  2. 固件库中如此多的c文件,如何添加依赖关系呢?

首先来解决第一个问题——如何告诉编译器找到这些头文件?

其实这个问题在讲使用gcc的时候有讲:当头文件不和源文件在一个目录时,需要使用-I(大写i)参数给编译器添加头文件搜索目录,所以修改一下makefile:

在这里插入图片描述

然后来解决第二个问题 —— 如何添加大量的源文件及其依赖到makefile?

其实文件虽然多,但是仔细理一下会发现可以分为以下几步:

  1. 找到全部的c文件;
  2. 将每个c文件编译为目标文件,不进行链接;
  3. 将所有的目标文件一起链接,生成可执行文件;

下面一步一步来~ 首先如何找到所有的c文件呢?可以在c文件全部使用相对于makefile的相对路径,显然这是最笨的办法,因为这么多文件,不可能一步一步添加,但是,在linux下可以使用find命令来寻找目录下的文件,所以我们使用find ./ -name '*.c'来寻找当前目录下所有的c文件,如图:

修改makefile,添加所有的c源文件:

接下来解决第二个小问题,如何将这些源文件分别编译为对应的目标文件呢? 当然是不可能一个一个写的,这里使用makfile的静态模式,它的语法是这样的:

代码语言:javascript复制
<targets>:<target-pattern>:<prereq-patterns>
    <commands>

这里面targets定义了一系列目标文件,可以有通配符,是目标的一个集合;target-pattern指明了targets的模式,prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义: 首先我们需要一个目标集合,也就是使用刚刚的静态模式将上一步所有搜索到的.c文件换为同名.o文件:

最后将目标文件添加到链接中:

这个时候,我们基本的两个大问题就解决完了,接下来编译器参数,一个是添加宏定义,首先是芯片型号宏定义STM32F10X_HD,然后是USE_STDPERIPH_DRIVER,表明我们使用了标准外设驱动库;另一个是添加我们之前的头文件路径:

还有一点需要注意,启动文件也需要修改:

最后修改clean:

这里我们的makefile就完成了,如果可以的话,还可以使用#添加必要的注释进去,最后进行一下优化,让它默认生成bin文件和hex文件:

接下来还不能直接make,之前我们配置时钟是在main.c里配置,这里引入了固件库中的system_stm32f10x.c,时钟配置在这里面已经完成,默认配置为72M,所以可以将main.c中的时钟初始化去了,然后使用make指令即可编译。

0 人点赞