这次我们来聊聊CMSIS。之前在Kile环境下创建STM32工程的时候,对有些文件的加入总不是很了解,书上或网上建立工程的教程对于这些文件的加入也是一笔带过,或者直接不说。对于类似名叫core_cm3.h,system_stm32f4xx.c的文件的作用感到比较困惑。在阅读了《ARM Cortex-m3与Conrtex-m4权威指南》之后,对CMSIS才有了一个比较清楚的了解,也知道为什么工程中需要加入这些文件了。

以下内容节选自《ARM Cortex-m3与Conrtex-m4权威指南》第三版,Joseph Yiu著,清华大学出版社出版。根据这些描述我将创建一个典型的STM32F4的工程,以便更好的来理解我们对CMSIS的阐述。如果你想深入了解Cortex-m3或Cortex-m4而不是停留在简单的函数调用的话,我非常建议阅读本书,它会很好的解答你在学习过程中遇到的很多问题。

1.CMSIS简介

CMSIS由ARM开发,它使得微控制器和软件供应商可以使用一致的软件结构来开发Cortex微控制器的软件,许多Cortex-M微控制器的软件产品都是符合CMSIS的。

由于当前庞大的生态系统,对软件结构进行某种形式的标准化已经非常必要,这样可以确保多种开发工具和不同软件解决方案的兼容性。同时,嵌入式系统也变得越来越复杂,开发和软件测试的工作量也显著增加了。为了减少开发时间并且降低产品中存在缺陷的风险,软件重用已经越来越普遍。另外,嵌入式系统的复杂度也增加了对第三方软件解决方案的依赖。例如,一个嵌入式软件工程可能会涉及各方面的软件部件:

·内部开发者开发的软件
·重用的其他项目的软件
·微控制器供应商的设备驱动库
·嵌入式OS
·通信协议栈等其他的第三方软件产品

在这种情况下,各种软件产品间的配合已经非常关键。由于所有这些原因,ARM同各家微控制器供应商、工具供应商和软件解决方案提供商一道开发了CMSIS——一个涵盖了大多数Cortex-M处理器和Cortex-M微控制器产品的软件框架。CMSIS项目仍在不断更新。

CMSIS项目有CMSIS-Core、CMSIS-DSP、CMSIS-SVD、CMSIS-RTOS、CMSIS-DAP。我们最能直观感受到的就是CMSIS-Core。这些项目所做的工作都是对Contex-M芯片的使用进行一个标准化。下面我们来看看CMSIS-Core进行了哪些标准化。

2.CMSIS-Core所做的标准化

(1)处理器外设的标准化定义。

这里注意区分处理器外设和微控制器的外设的区别,微控制器就像STM32,处理器就像STM32中的Cortex-M,我们知道处理器也是有自己的私房外设的,其中包括嵌套向量中断控制器(NVIC)中的寄存器、处理器中的系统节拍定时器(SysTick)、可选的存储器保护单元(MPU)、系统控制块(SCB)中的多个可编程寄存器以及一些和调试特性相关的软件可编程寄存器。注意:有些Cortex-M4中的寄存器在Cortex-M3中是不可用的,类似地,Cortex-M3和Cortex-M4中的一些寄存器在Cortex-M0中也是不可用的。

(2)访问处理器特性的标准化函数。

其中包括使用NVIC进行中断控制的多个函数以及访问处理器中特殊寄存器的函数。若需要的话,也可以直接访问寄存器,而使用这些函数(有时也被称作应用编程接口,或者叫API)进行编程有助于提高软件可移植性。实际上,你可以回忆在core_cm4.h中看到的很多“奇怪”的函数,这里的函数指的就是他们。你可以放心的使用他们而不必担心这些代码在其他cortex系列的处理上无法运行,当然前提是代码得符合CMSIS标准。​​​​​​​

(3)操作特殊指令的标准化函数。

Cortex-M处理器支持几个用于特殊目的的指令(例如,等待中断WFI,用于进入休眠模式),这些指令无法用普通的IEC/ISOC语言生成。CMSIS实现了一组函数,C程序代码可以利用这些函数实现特殊指令。若没有这些函数,用户必须得使用工具链相关的解决方案,如内在函数或内联汇编,才能将特殊指令插入应用程序中,这样会降低软件的可重用性,而且为了避免出现错误,可能还需要对工具链的深入了解。CMSIS为这些特性提供了一种标准的API,这样应用程序开发者就可以轻松使用了。它们也存在于类似core_cm4.h的文件中。

(4)系统异常处理的标准化命名。

多个系统异常类型在Cortex-M处理器的架构中有所体现,通过赋予这些系统异常处理标准化的命名,开发适用于多种Cortex-M产品的软件也就更加容易。这对嵌入式OS开发者尤其重要,因为嵌入式OS需要使用一些系统异常。​​​​​​​

(5)系统初始化的标准函数。

对于多数具有丰富特性的现代微控制器产品,在应用程序开始前都需要配置时钟电路和电源管理寄存器。在符合CMSIS的设备驱动库中,这些配置过程由Systemlnit()实现。很显然,该函数的实际实现是设备相关的,而且可能需要适应多种工程需求。不过,由于有了标准的函数名、函数的标准使用方式以及函数的标准位置,设计者就能很容易地开始使用Cortex-M微控制器。​​​​​​​

(6)描述时钟频率的标准化的变量。

这个看起来必要性不是很大,不过有时应用程序代码需要知道系统当前运行的时钟频率。例如,在设置UART波特率分频器或初始化嵌人式OS使用的SysTick定时器时可能需要这种信息。CMSIS-Core中定义了一个软件变量SystemCoreClock(用于CMSIS的1.3或者更新的版本,之前的版本为SystemFreq)。

另外,CMSIS-Core还提供了设备驱动库的通用平台。每个设备驱动库看起来都是一样的,这样初学者使用设备就更加容易,而且软件开发人员也可以很轻松地开发出用于多种Cortex-M微控制器产品的软件。

3.CMSIS-Core的组织结构

CMSIS文件被集成在微控制器供应商提供的设备驱动库软件包中,设备驱动库中的有些文件是ARM准备的,对于各家微控制器供应商都是一样的,其他文件则取决于供应商/设备。一般来说,可以将CMSIS定义为以下几层:

1、内核外设访问层。名称定义、地址定义以及访问内核寄存器和内核外设的辅助函数,这是处理器相关的,由ARM提供。
2、设备外设访问层。名称定义、外设寄存器的地址定义以及包括中断分配、异常向量定义等的系统设计,这是设备相关的(注意:同一家供应商的多个设备可能会使用同一组文件)。
3、外设访问函数。访问外设的驱动代码,这是供应商相关的,而且是可选的。在开发应用程序时,可以选择使用微控制器供应商提供的外设驱动代码,或者有必要,也可以直接访问外设。

对于外设访问还提出了另外一层:中间件访问层。该层在当前的CMSIS版本中不存在,现在的设想为,开发一组用于访问UART、SPI以及以太网等常见外设的API。若该层存在,中间件开发人员可以基于该层开发自己的应用程序,这样软件在设备间移植也就更加容易。各层角色如下图所示

注意在有些情况下,设备驱动库中可能会包含用于微控制器供应商设计的NVIC的函数(例如可能大部分人都使用过的misc.c文件中的函数),它们是供应商定义的。CMSIS的目标为提供一个共同的起点,微控制器供应商也可以根据自己的意愿添加其他的函数。不过若软件需要在另外一个微控制器产品上重用,就需要移植。

4、如何使用CMSIS-Core

CMSIS文件位于微控制器供应商提供的设备驱动软件包中,因此,在使用微控制器供应商提供的设备驱动库时,就已经在使用CMSIS了。

一般来说,需要做到以下几点。

(1)将源文件添加到工程中,其中包括:
·设备相关,工具链相关的启动代码,C或汇编。
·设备相关的设备初始化代码(如system_stm32f1xx.c)。
·用于外设访问功能的其他供应商相关的源文件,这是可选的(如GPIO,USART等外设的.c文件)。
·对于CMSIS-Core库的CMSIS2.00或者之前版本,为了访问内核寄存器,可能还需要将一个处理器相关的C程序文件(如core_cm3.c)添加到工程中,从CMSIS-Core版本2.10开始就不再需要了(只需要添加core_cm3.h即可)。
(2)将头文件添加到搜索路径中,其中包括:
·用于外设寄存器定义和中断分配定义的设备相关的头文件(如stm32f1xx.h)。
·用于设备初始化代码的设备相关的头文件(如system_stm32f1xx.h)。
·多个处理器相关的头文件(如core_cm3.h、core_cm4.h,它们对于所有的微控制器供应商都是相同的)。
·其他可选的用于外设访问的供应商相关的头文件(如GPIO,USART等外设的.h文件)。
·有些情况下,开发组件中可能会包含一些预安装的CMSIS支持文件。

有些情况下,在创建一个新的工程时,集成开发环境(IDE)会自动设置启动代码,要不然,还需要手动将设备驱动库中的启动代码(如startup_stm32f401xx.s)添加到工程中。处理器的启动流程需要启动代码,它包括中断处理所需的异常向量表定义。

具体如下图所示:


下面我将利用我下载得到的STM32F4xx_DSP_StdPeriph_Lib_V1.8.0标准库根据上面第4条如何使用CMSIS-Core的说明来构建一个基于标准库的STM32F4开发环境。在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS目录下有一个叫index的html文件,对其中的CMSIS文件作用做了说明:

从中我们可以看出我们要使用的CMSIS-Core文件在Include文件夹中。我们可以看到这里还有CMSIS-DSP项目,日后如果要用微控制器进行DSP之类的,可以来使用这其中的文件,可以看到它甚至还为ARMCC和GCC开发工具做好了相应的库,如GCC就是一个集成的.a文件,非常方便,也比较高效,那么下面就开始动手吧。

1、首先在桌面新建一个文件夹stm32f4_TestProject。
2、打开并在其中建立一个名叫CMSIS的文件夹,专门存放我们的CMSIS文件;建立MDK文件夹,用来存放工程文件;建立USER文件夹,用来存放应用代码;建立StdPeriph_Lib文件夹,用来存放外设标准库函数。
3、在CMSIS中建立Include目录,加入core_cm4.h、core_cmSimd.h、core_cmInstr.h、core_cmFunc.h、stm32f4xx.h、stm32f4xx.h。继续在CMSIS目录中加入启动文件startup_stm32f401xx.s。加入system_stm32f4xx.c文件
4、在StdPeriph_Lib目录中视需要加入标准外设启动库函数,在USER目录添加自己的工程文件,和一个stm32f4xx_conf.h控制引入的头文件即可。
5、打开kile5,新建工程,设备选择STM32F4RE,而后添加文件到工程,添加头文件路径就不再说了。
6,添加宏定义 USE_STDPERIPH_DRIVER,STM32F40XX
7,编译运行, 0 Error(s), 0 Warning(s).

实际上可以看到,这就是按照上图的工程结构来进行搭建的,只有对每一个文件的加入理解了,才能更好的组织工程代码,使我们的工作更有条理。

基于CMSIS创建典型STM32F4工程相关推荐

  1. Win7 搭建NodeJs、Vue2、Vue3,基于 vue-cli 创建建vue工程及相关问题解决思路

    Win7 搭建NodeJs.Vue2.Vue3,基于 vue-cli 创建建vue工程及相关问题解决思路 安装NodeJs NodeJs 相关配置 安装vue和vue脚手架 安装 webpack 打包 ...

  2. CDR插件开发之Addon插件008 - 在VS中下载安装Addons插件模板并基于模板创建Addon插件工程

    本文介绍了Addons插件模板的由来,演示如何在VS 2022中安装Addon插件模板(扩展),并基于Addons模板创建CDR插件工程,演示了在CDR 2020中加载和运行自己创建的Addon插件. ...

  3. 基于STM32CubeMX创建STM32L496ZGTx的工程

    创建项目New Project,选择STM32L496ZGTx 选择管脚PB7, PB14,设置为GPIO_Output 设置时钟为80MHz 设置PB7, PB14为推挽输出模式, 初始电平为高 生 ...

  4. STM32G070RBT6基于STM32CubeMX创建EXTI外部中断工程

    STM32G070RBT6基于STM32CubeMX创建外部中断工程 相关篇<[硬件开源电路]STM32G070RBT6开发板>

  5. 基于eclipse创建android的helloworld工程

    基于eclipse创建android的helloworld工程 之前用过Android studio感觉很慢,决定采用eclipse来学习Android开发.下面来看是怎么创建的. 选择File--- ...

  6. STM32G070RBT6基于STM32CubeMX创建ADC DMA多通道采样工程

    STM32G070RBT6基于STM32CubeMX创建ADC DMA多通道采样工程 -

  7. 基于Tcl脚本生成Vivado工程及编译

    Tcl脚本简介 Tcl--Tool Command Language(读作tickle),诞生于80年代的加州大学伯克利分校,作为一种简单高效可移植性好的脚本语言,目前已经广泛应用在几乎所有的EDA工 ...

  8. 使用keil软件创建一个STM32工程

    使用keil软件创建一个STM32工程 ----------------芯片:STM32F429IGT6 创建一个STM32F429IGT6的工程,其他型号的单片机也大同小异.因为最近开始学习STM3 ...

  9. Vue-cli创建Vue项目工程步骤详解

    Vue-cli 即:Vue脚手架.官方网址:vue-cli官网 本篇文章以我经常创建Vue项目工程的步骤为例,带着大家一步一步创建一个全新的vue项目工程.文章会详细讲解Vue脚手架创建项目的每一个步 ...

最新文章

  1. 盘点六大在中国复制失败的O2O案例
  2. 如何培养自己奇特的创意设计思维?
  3. jzoj5353-村通网【最小生成树】
  4. 1.3 编程基础之算术表达式与顺序执行(20题)
  5. 电商大厂面试都有哪些套路?
  6. abrtd:Executable ‘some execution‘ doesn‘t belong to any package and ProcessUnpackaged is set to ‘no‘
  7. C#网络编程示例(note)
  8. 关于mapper接口与mapper.xml文件在同包运行找不到问题解决
  9. java的关闭钩子(Shutdown Hook)
  10. Nginx PHP Apache 隐藏版本号/禁止显示版本号
  11. Python使用matplotlib可视化模拟正弦余弦在子图显示
  12. 用文华财经软件编写埃尔德动力系统
  13. 熊去氧胆酸的药物行业调研报告 - 市场现状分析与发展前景预测
  14. 0x50 动态规划(练习)20:干草堆(题解)
  15. Framer:开源原型设计工具,巨头们的心头好
  16. 关于sentinel LDK加密war包实现应用加密的使用方法
  17. hihocoder 1246 王胖浩与环
  18. matlab 画xos函数,振荡积分的数值计算与Matlab实现
  19. 部署LVS-DR集群
  20. 电脑系统重装篇2:使用软碟通软件制作U盘系统安装盘(UltraISO)

热门文章

  1. python Day5
  2. 解决[warn] _default_ VirtualHost overlap on port 80, the first has precedence问题
  3. STL体系结构与内核分析-2-STL体系结构基础介绍(侯捷)--笔记
  4. fastjson与net.sf.json区别
  5. 无监督学习:从基本概念到四种实现模型
  6. 码教授告诉你面试不要骄傲自负,也不妄自菲薄
  7. php的filesystem基本函数的学习(1)
  8. MathType公式保存后为什么字体会变化
  9. SQL server 2005中无法新建作用(Job)的问题
  10. Cacti 插件中setup.php 文件的编写