注:本文参考正点原子《STM32F4开发指南-库函数版本V1.1》改写
1. CKS32 固件库与 CMSIS 标准
ARM 公司为了能让不同的芯片公司生产的 Cortex-M 芯片能在软件(包括函数命名风格)上基本兼容,和芯片生产商共同提出了一套标准 CMSIS 标准(Cortex Microcontroller Software Interface Standard) ,翻译过来是“ARM Cortex™ 微控制器软件接口标准”。
CMSIS 分为 3 个基本功能层:
1) 核内外设访问层:ARM 公司提供的访问,定义处理器内部寄存器地址以及功能函数。
2) 中间件访问层:定义访问中间件的通用 API。由 ARM 提供,芯片厂商根据需要更新。
3) 外设访问层:定义硬件寄存器的地址以及外设的访问函数。
从图中可以看出,CMSIS 层在整个系统中是处于中间层,向下负责与内核和各个外设直接打交道,向上提供实时操作系统用户程序调用的函数接口。如果没有 CMSIS 标准,那么各个芯片公司就会设计自己喜欢的风格的库函数,而 CMSIS 标准就是要强制规定,芯片生产公司设计的库函数必须按照 CMSIS 这套规范来设计。其实不用这么讲这么复杂的,一个简单的例子,我们在使用 STM32 芯片的时候首先要进行系统初始化,CMSIS 规范就规定,系统初始化函数名字必须为 SystemInit,所以各个芯片公司写自己的库函数的时候就必须用SystemInit 对系统进行初始化。CMSIS 还对各个外设驱动文件的文件名字规范化,以及函数名字规范化等等一系列规定。上一节讲的函数GPIO_ResetBits 这个函数名字也是不能随便定义的,是要遵循 CMSIS 规范的。
2. 文件夹介绍
2.1 CMSIS
CMSIS文件夹存放的是符合CMSIS规范的一些文件。
2.2 Libraries
Libraries 文件夹下面有 CMSIS 和 CKS32F0xx_StdPeriph_Driver 两个目录,这两个目录包含固件库核心的所有子文件夹和文件。
2.2.1 CKS32F0xx_StdPeriph_Driver
CKS32F0xx_StdPeriph_Driver 放的是 CKSF0xx 标准外设固件库源码文件和对应的头文件。
2.2.2 inc
inc 目录存放的是 cks32f0xx_ppp.h 头文件,无需改动。src 目录下面放的是 cks32f0xx_ppp.c 格式的固件库源码文件。每一个.c 文件和一个相应的.h 文件对应。这里的文件也是固件库外设的关键文件,每个外设对应一组文件。
Libraries 文件夹里面的文件在我们建立工程的时候都会使用到。
3. 关键文件介绍
3.1 core_cm0.h
位于Libraries\CMSIS\Include目录下。
CMSIS Cortex-M0 Core Peripheral Access Layer Header File(CMSIS Cortex-M0核心外围设备访问层头文件)。包括寄存器定义、函数定义以及操作指南。
3.2 system_cks32f0xx.h
位于Libraries\CMSIS\Device\Include目录下。
system_cks32f0xx.h 是片上外设接入层系统头文件。主要是申明设置系统及总线时钟相关的函数。与其对应的源文件 system_cks32f0xx.c 在目录Libraries\CMSIS\Device\Source 可以找到。这个里面有一个非常重要的 SystemInit()函数申明,这个函数在我们系统启动的时候都会调用,用来设置系统的整个系统和总线时钟。
3.3 cks32f0xx.h
位于Libraries\CMSIS\Device\Include目录下。
cks32f0xx.h 是 CKS32F0 片上外设访问层头文件。这个文件就相当重要了,只要你做CKS32F0 开发,你几乎时刻都要查看这个文件相关的定义。这个文件打开可以看到,里面非常多的结构体以及宏定义。这个文件里面主要是系统寄存器定义申明以及包装内存操作,对于这里是怎样申明以及怎样将内存操作封装起来的。同时该文件还包含了一些时钟相关的定义,FPU 和 MPU 单元开启定义,中断相关定义等等。
3.4 startup_cks32f0xx.s
位于Libraries\CMSIS\Device\Source目录下。
启动文件到底什么作用,其实我们可以打开启动文件进去看看。启动文件主要是进行堆栈之类的初始化,中断向量表以及中断函数定义。启动文件要引导进入main 函数。Reset handler routine 中断函数是唯一实现了的中断处理函数,其他的中断函数基本都是死循环。
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP