当前位置: 首页 > news >正文

CMSIS设计的理解

一、CMSIS 是什么?

CMSIS 的全称是 Cortex Microcontroller Software Interface Standard,即 Cortex 微控制器软件接口标准

简单来说,它是由 ARM 公司制定并提供的一套标准化软件框架。它的目的是为基于 ARM Cortex-M 处理器的芯片厂商和软件开发者提供一致性的软件接口。

您可以把它理解为芯片厂商和开发者之间的“普通话”。在没有“普通话”之前,每家芯片公司(如 ST、NXP、Microchip 等)都有自己的外设寄存器定义和函数库,导致为一家公司芯片写的代码很难移植到另一家。CMSIS 的出现就是为了解决这个碎片化问题。

二、CMSIS 的组成模块(核心内容)

其中最常用和核心的组件包括:

1. CMSIS-Core (Cortex-M)

这是最基础、最核心的部分,提供了对 Cortex-M 处理器本身的标准化访问。包含:

  • 寄存器定义:对内核寄存器(如 NVIC, SCB, SysTick 等)的地址和位定义。

  • 设备头文件:由芯片厂商提供,包含该型号芯片所有的外设寄存器定义(如 GPIOA->BSRR)、中断向量表等。这个文件(如 stm32f10x.h)是您项目的基础。

  • 系统初始化函数:如 SystemInit(),用于配置时钟和初始化关键系统。

  • 内核访问函数:用于开关中断、休眠模式、内存屏障指令等。例如 __enable_irq()__WFI()

2. CMSIS-DSP

一个功能强大且高度优化的数字信号处理库。包含:

  • 数学函数:基本数学(乘、加)、快速数学(三角函数)、滤波器、矩阵运算、变换(FFT)、电机控制函数等。

  • 优势:ARM 为 Cortex-M 内核进行了手写汇编优化,性能远超开发者自己编写的 C 代码。

3. CMSIS-RTOS API

一个为实时操作系统定义的通用 API 接口。

  • 作用:应用程序通过调用 CMSIS-RTOS2 的接口(如 osThreadNewosMutexAcquire),而不是操作系统的原生接口。这使得代码可以在不同的 RTOS(如 FreeRTOS, Azure RTOS, RT-Thread)之间无缝移植,因为只需要更换底层的 RTOS 实现适配层即可。

4. CMSIS-Driver

定义了通用外设驱动(如 UART, I2C, SPI, ETH, USB)的 API 标准。

  • 目的:让中间件和应用程序可以不依赖具体的芯片型号,通过统一的驱动接口访问外设。芯片厂商或社区会提供符合此标准的驱动实现。

5. CMSIS-Pack

一个软件包分发机制。开发者可以通过 Keil MDK 的 Pack Installer 或类似的工具,一键安装芯片支持、设备驱动、中间件和示例代码,极大地简化了项目管理。

6. CMSIS-NN

专门为 Cortex-M 处理器优化的神经网络内核库。用于在微控制器上高效地运行机器学习推理模型,是 TinyML 领域的关键基础。

三、CMSIS 与MCU库的联系

拿stm32的hal库来举例,其关系如下:

核心关系概括

所以,CMSIS首先是ARM用来“约束”和“帮助”MCU设计商的工具。

2. MCU设计商(ST)的角色 & HAL库的目的

所以,HAL库是MCU设计商用来“服务”和“吸引”最终开发者的工具。


一个具体的例子:配置一个定时器中断
  • CMSIS 是 ARM 制定的基础标准。它定义了如何访问内核(如NVIC、SysTick)和芯片基本外设的通用方法。它更底层,更接近硬件。

  • HAL库 是 ST(意法半导体) 根据CMSIS标准,为自己家的STM32芯片实现的高级应用库。它基于CMSIS,但在其上构建了更易用、更抽象的一层。

  • 为了更深入理解,我们再细化一下这个分工:
    1. ARM 的角色 & CMSIS 的目的
  • ARM 只设计 Cortex-M CPU 核心(相当于设计了一个强大的“发动机和底盘平台”)。

  • 但一个完整的MCU,除了CPU核心,还有内存、中断控制器、调试接口等,这些都是CPU核心必须的“贴身部件”。

  • CMSIS 的核心作用就在这里:ARM 通过 CMSIS-Core 为这些 “CPU核心及其贴身部件” 定义了统一的软件访问标准。这确保了无论哪个厂商,只要用了Cortex-M核心,操作内核寄存器、配置中断的方式都是一样的。

  • ST 这样的公司,拿到ARM的Cortex-M核心后,围绕它添加了GPIO、UART、I2C、ADC等各种各样的外设,最终做成STM32这颗具体的MCU(相当于在“发动机底盘”上造出了完整的“汽车”)。

  • 对于开发者来说,他们面对的是成千上万个控制这些外设的寄存器,操作非常底层和复杂。

  • CMSIS层(ARM为MCU设计商提供的标准):

    • MCU设计商提供的设备头文件(如 stm32f4xx.h)中,会使用CMSIS标准定义 TIM2 外设的寄存器结构体。

    • 开发者可以使用 NVIC_EnableIRQ(TIM2_IRQn); 这个CMSIS函数来开启定时器2的中断,因为这个中断控制器是CPU核心的一部分,遵循ARM标准。

  • HAL库层(MCU设计商为开发者提供的服务):

    • 开发者调用 HAL_TIM_Base_Start_IT(&htim2); 这个HAL函数。

    • 这个HAL函数在内部帮我们做了所有事:

      • 使用CMSIS标准设置了内核的SysTick计时器。

      • 直接操作STM32独有的定时器外设寄存器(通过CMSIS定义的结构体)来配置预分频、重载值。

      • 它最终还会调用 NVIC_EnableIRQ(TIM2_IRQn); 来开启中断。

四、CMSIS的接口设计

1. CMSIS:提供“插槽”和“命名规则”

ARM在制定CMSIS标准时,并不知道ST、NXP、TI这些公司会具体设计多少个定时器、多少个UART。因此,CMSIS所做的是:

  • 定义一个标准化的“中断编号枚举”:它知道Cortex-M内核有一个叫做NVIC的中断控制器,所以它定义了 IRQn_Type 这个枚举类型,就像预留了一排标好数字的“插槽”(例如,位置0, 1, 2...)。

  • 声明一个“设备头文件”必须提供这个枚举的具体内容:它要求芯片厂商(如ST)必须提供一个 device_name.h 的头文件,在这个文件里,必须具体化这个 IRQn_Type 枚举,给每个插槽赋予具体的意义。

2. MCU设计商:填充“插槽”

MCU设计商(如ST)根据自己芯片的实际设计,来填充CMSIS提供的“插槽”。

  • CMSIS 的“弱定义”框架(在通用头文件中):

    c

    // 这是ARM CMSIS框架定义的,一个“不完整”的枚举
    // 它相当于说:“每个芯片厂商必须在这里定义你们自己的中断号”
    typedef enum IRQn {// ... 一些Cortex-M内核标准中断(如SysTick, PendSV)是固定的MemoryManagement_IRQn = -12,// ... 其他内核中断SVCall_IRQn          = -5,DebugMonitor_IRQn    = -4,PendSV_IRQn          = -2,SysTick_IRQn         = -1,// 非内核中断从这里开始,具体是什么,由芯片决定
    } IRQn_Type;
  • ST(MCU设计商)的具体实现(在 stm32f4xx.h 中):

    c

    // ST在这里具体填充了STM32F4系列芯片的中断号
    typedef enum IRQn {// ... 内核中断部分与CMSIS框架完全一致// 非内核中断:ST根据自己芯片的设计来定义WWDG_IRQn                = 0,// ... 其他中断EXTI0_IRQn               = 6,EXTI1_IRQn               = 7,// ...TIM2_IRQn                = 28, // 您的例子:定时器2中断被分配到了28号插槽TIM3_IRQn                = 29,// ...USART1_IRQn              = 37, // 您的例子:串口1中断USART2_IRQn              = 38,// ...
    } IRQn_Type;
3. 地址映射也是同样的道理
  • CMSIS:定义了“外设寄存器应该用一个结构体来组织”这个方法

  • ST:根据自己设计的总线布局和外设寄存器地址,具体实现这个结构体。

例如,CMSIS说GPIO应该有个叫 BSRR 的寄存器。ST就在自己的头文件里,根据STM32芯片上GPIO外设的实际内存地址,定义:

c

#define GPIOA_BASE    (AHB1PERIPH_BASE + 0x0000)
#define GPIOA         ((GPIO_TypeDef *) GPIOA_BASE) // 将地址强制转换为标准结构体类型// 这个GPIO_TypeDef的结构体模板是由CMSIS标准或ST遵循该标准定义的
typedef struct {__IO uint32_t MODER;__IO uint32_t OTYPER;// ... 其他寄存器__IO uint32_t BSRR;   // 位设置/清除寄存器,位于某个特定偏移地址// ...
} GPIO_TypeDef;

http://www.dtcms.com/a/428088.html

相关文章:

  • 串扰06-近端串扰的大小
  • 哪些网站是做食品网站前台设计方案
  • 达州市网站建设wordpress文章与页面
  • Powershell维护系统管理任务(五)
  • 美团滑块-[behavior] 加密分析
  • 泉州专业建站单位网站建设实施方案
  • 动作捕捉技术与服务 | 推动人形机器人实现规模化高质量数据采集与训练
  • 网站开发软件有哪设计师网络叫法
  • 服务类网站开发中山家居企业网站建设
  • 【Android】Kotlin.flow在主线程collect为什么不阻塞主线程?
  • 数据整合展示中心
  • 阜宁网站制作哪家好我公司想做网站
  • Spring IOC源码篇七 核心方法obtainFreshBeanFactory自定义标签
  • 在哪里找做网站的客户郴州网络营销
  • 产生式规则对人工智能中自然语言处理深层语义分析的影响与启示研究
  • 南宁专业网站开发潍坊市网站制作
  • 网站后台登录密码修改自己网站做问卷调查
  • 在命令提示符页面中用pip命令行安装Python第三方库的详细步骤
  • 杭州开发网站的公司网站默认中文字体
  • 深度解析Epoch:模型训练中的“时间与泛化“博弈
  • MySQL索引特性(重点)
  • 【有序数组去重】2022-11-25
  • 【11408学习记录】考研数学线性代数精讲:矩阵方程求解与秩的深度解析
  • 专业沈阳网站制作大数据公司排名
  • 做受视频网站现在流行什么语言建设网站
  • TDengine 时序函数 STATEDURATION 用户手册
  • Java-Spring入门指南(十二)SpringAop的三种实现方式
  • 网站在线统计代码cms开发框架
  • CometD 长轮询协议及在Salesforce中的应用
  • 企术建站网站收录查询主要由哪几个网站