STM32F429入门(八):初识固件库

一、什么是固件库?

  1. 固化到EEPROM或者是芯片的FLASH中。

  2. 操作的是最底层的设备

按照我的理解就是,它就是一个封装好的函数库,跟前几次自己写库差不多。

二、CMSIS标准及库层次关系

因为基于 Cortex 系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异, 这些差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的 Cortex 微控制器软件 的兼容性问题,ARM 与芯片厂商建立了 CMSIS 标准(Cortex MicroController Software Interface Standard)。 所谓 CMSIS 标准,实际是新建了一个软件抽象层。

CMSIS 标准中最主要的为 CMSIS 核心层,它包括了:

  • 内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由 ARM 公司提供。

  • 设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提供。

可见 CMSIS 层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件抽象层,可以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽了硬件差异, 这对软件的移植是有极大的好处的。

三、固件库文件分析

打开固件库文件,我们可以看到这几个文件:

 打开Libraries--CMSIS--Device--ST,里面这个文件就是代表你所要开发的芯片的厂商,点开后点进Source--Templates,会看到很多开发环境,我们点开arm,里面就是我们启动时所需要的启动文件。

 

在CMSIS中,以上圈出的两个文件是较为重要的。

  1. Include文件夹

    在 Include 文件夹中包含了 的是位于 CMSIS 标准的核内设备函数层的 Cortex-M 核通用的头文件,它们的作用是为那些采用 Cortex-M 核设计 SOC 的芯片商设计的芯片外设提供 一个进入内核的接口,定义了一些内核相关的寄存器(类似我们前面写的 stm32f4xx.h 文件, 但定义的是内核部分的寄存器)。

    我们写 STM32F4 的工程,必须用到其中的四个文件:core_cm4.h、core_cmFunc.h、 corecmInstr.h、core_cmSimd.h,其它的文件是属于其它内核的,还有几个文件是 DSP 函数 库使用的头文件。

    core_cm4.c 文件有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异。里 面包含了一些跟编译器相关的信息,如:“CC_ARM ”(本书采用的 RVMDK、KEIL), “GNUC__ ”(GNU 编译器)、“ICC Compiler” (IAR 编译器)。这些不同的编译器对于 C 嵌入汇编或内联函数关键字的语法不一样,这段代码统一使用“ASM、INLINE”宏 来定义,而在不同的编译器下,宏自动更改到相应的值,实现了差异屏蔽。

  较重要的是在 core_cm4.c 文件中包含了“stdint.h” 这个头文件,这是一个 ANSI C 文 件,是独立于处理器之外的,就像我们熟知的 C 语言头文件 “stdio.h” 文件一样。位于 RVMDK 这个软件的安装目录下,主要作用是提供一些类型定义

1. /* exact-width signed integer types */
2. typedef signed 			char int8_t; 
3. typedef signed short 	int int16_t; 
4. typedef signed 			int int32_t; 
5. typedef signed 			__int64 int64_t; 
6.
7. /* exact-width unsigned integer types */
8. typedef unsigned 		char uint8_t; 
9. typedef unsigned short 	int uint16_t; 
10.typedef unsigned 		int uint32_t; 
11.typedef unsigned 		__int64 uint64_t;

这些新类型定义屏蔽了在不同芯片平台时,出现的诸如 int 的大小是 16 位,还是 32 位 的差异

2.Device文件夹

在 Device 文件夹下的是具体芯片直接相关的文件,包含启动文件、芯片外设寄存器定义、系统时钟初始化功能的一些文件,这是由 ST 公司提供的。

  • system_stm32f4xx.c 文件

这个文件包含了 STM32 芯片上电后初始化系统时钟、扩展外部存储器用的函数,例如 我们前几天提到供启动文件调用的“SystemInit”函数,用于上电后初始化时钟,该函数的 定义就存储在 system_stm32f4xx.c 文件。STM32F429 系列的芯片,调用库的这个 SystemInit 函数后,系统时钟被初始化为 180MHz,如有需要可以修改这个文件的内容,设 置成自己所需的时钟频率。

作用:初始化系统环境,配置系统时钟。

  • 启动文件

    在这个目录下,还有很多文件夹,如“ARM”、“gcc_ride7”、“iar”等,这些文件 夹下包含了对应编译平台的汇编启动文件,在实际使用时要根据编译平台来选择。我们使 用的 MDK 启动文件在“ARM”文件夹中。其中的“strartup_stm32f429_439xx.s”即为 STM32F429 芯片的启动文件,工程中使用的启动文件就是从这里复制过去的。如果使用其它型号的芯片,要在此处选择对应的启动文件。

  • stm32f4xx.h 文件

    stm32f4xx.h 这个文件非常重要,是一个 STM32 芯片底层相关的文件。它是我们前几次自己定义的“stm32f4xx.h”文件的完整版,包含了 STM32 中所有的外设寄存器地址和结构体类型定义,在使用到 STM32 标准库的地方都要包含这个头文件。打开后就可以看到前几次学习寄存器时所配置的地址,非常的亲切...T T

3.STM32F10x_StdPeriph_Driver 文件夹

  • 打开\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\STM32F4xx_StdPeriph_Driver\src中的misc.c文件,这个文件是非常重要的中断文件。这个文件提供了外设对内核中的 NVIC(中断向量控制器)的访问函数,在配置中断时,我们必须把这个文件添加到工程中。

  • STM32F4xx_StdPeriph_Driver 文件夹下有 inc(include 的缩写)跟 src(source 的简写) 这两个文件夹,这里的文件属于 CMSIS 之外的的、芯片片上外设部分。

  • 在 src 和 inc 文件夹里的就是 ST 公司针对每个 STM32 外设而编写的库函数文件,每个 外设对应一个 .c 和 .h 后缀的文件。昨天在自己写库函数的stm32f4xx_gpio.c 及 stm32f4xx_gpio.h 文件,就属于这一类。

 

4.stm32f4xx_it.c、 stm32f4xx_conf.h 文件

打开\STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates,里面有stm32f4xx_it.c、stm32f4xx_it.h、stm32f4xx_conf.h这三个文件。

  • stm32f4xx_it.c:编写中断服务函数。

  • stm32f4xx_conf.h:使用这个配置文件根据芯片 型号增减 ST 库的外设文件,通过宏来指定芯片的型号,还可配置是否使用“断言”编译选项。

#if defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
#include "stm32f4xx_cryp.h"
#include "stm32f4xx_hash.h"
#include "stm32f4xx_rng.h"
#include "stm32f4xx_can.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_dcmi.h"
#include "stm32f4xx_dma2d.h"
#include "stm32f4xx_fmc.h"
#include "stm32f4xx_ltdc.h"
#include "stm32f4xx_sai.h"
#endif /* STM32F429_439xx || STM32F446xx || STM32F469_479xx */

#if defined(STM32F427_437xx)
#include "stm32f4xx_cryp.h"
#include "stm32f4xx_hash.h"
#include "stm32f4xx_rng.h"
#include "stm32f4xx_can.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_dcmi.h"
#include "stm32f4xx_dma2d.h"
#include "stm32f4xx_fmc.h"
#include "stm32f4xx_sai.h"
#endif /* STM32F427_437xx */

 在 ST 标准库的函数中,一般会包含输入参数检查,即上述代码中的“assert_param” 宏,当参数不符合要求时,会调用“assert_failed”函数,这个函数默认是空的。 实际开发中使用断言时,先通过定义 USE_FULL_ASSERT 宏来使能断言,然后定义 “assert_failed”函数,通常我们会让它调用 printf 函数输出错误说明。使能断言后,程序运行时会检查函数的输入参数,当软件经过测试,可发布时,会取消 USE_FULL_ASSERT 宏来去掉断言功能,使程序全速运行。

#ifdef  USE_FULL_ASSERT
/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param  expr: If expr is false, it calls assert_failed function
  *   which reports the name of the source file and the source
  *   line number of the call that failed. 
  *   If expr is true, it returns no value.
  * @retval None
  */
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
  void assert_failed(uint8_t* file, uint32_t line);
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */

#endif /* __STM32F4xx_CONF_H */

5.最后,我们按照开机的流程来理一理以上的文件:

那明天就学学如何新建固件库工程吧! 

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑烯烃快去学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值