1.什么是CMSIS?
CMSIS(Cortex Microcontroller Software Interface Standard,Cortex微控制器软件接口标准)提供Cortex-M内核与软件之间的接口,即用户可以通过这些统一的接口(函数API)去访问底层硬件,而不必关心不同厂家针对具体硬件的实现过程(单片机的启动文件也在这个标准中)。CMSIS的架构图如下:
ST和NXP厂家各自实现的芯片是有差异的,而有了CMSIS之后,ST和NXP需要针对自家芯片的特点执行CMSIS。比如CMSIS的UART中ARM_DRIVER_USART结构体有很多操作底层USART的函数,用户只需要调用结构体中的函数即可,函数的具体实现过程由ST和NXP实现(有差异)。对于用户来说,不管是ST还NXP只要是Cortex-M内核,这些ARM_DRIVER_USART中的函数API都是相同的(不关心底层硬件的实现过程),那么在使用的时候提高了代码的移植性、复用性和开发进度。
在STM32H7(Cortex-M7)中部分ARM_DRIVER_USART中的函数需要调用HAL_UART_Init()初始化串口,但是NXP是直接调用自己的寄存器实现。最终对于用户而言,只需要调用接口函数即可,不必去关心ST和NXP操作串口硬件的过程和方法。
简单来说,就像电动螺丝刀。ARM提供了核心的电动控制部分和螺丝刀的标准大小,但是不管厂家具体怎么制作这些螺丝刀(只需要遵守标准即可)。所以,在统一标准下,用户使用电动螺丝刀可以安装不同的螺丝刀,而且使用方法都是相同的,避免了用户再去区分这些螺丝刀的差异,提高使用的便利性(提高开发速度)。
2. CMSIS的组成部分:
CMSIS组成部分如下:
(1)Core层:提供对Cortex-M处理器核心的访问,包括寄存器操作、中断管理(NVIC)、位带操作、系统控制块(SCB,包含时钟控制、异常处理等)、内存保护单元(MPU)等;
(2)DSP层:提供数字信号处理的算法函数,比如滤波器、三角函数、矩阵运算等,使用C语言实现,并针对不同Cortex-M内核优化性能。
(3)RTOS层:提供操作系统的接口API,比如任务调度、资源管理、时间管理等,基于C语言实现。常使用的FreeRTOS、Threadx都是使用此接口。
(4)Driver层:提供标准化的外设驱动接口,如串口、以太网、USB等,使开发者无需了解具体硬件细节即可配置外设。ARM定义了这些外设接口函数和寄存器地址,所有的厂家都需要安这个标准来实现具体的函数执行。
(5)CMSIS-NN层:针对神经网络的优化库,通过高效内核减少内存占用,适用于Cortex-M处理器上的AI应用。
(6)编译层:定义通用的数据类型(uint32_t、float)、编译器相关的指令等,方便代码可以在不同编译环境中运行。
等等。
CMSIS通过标准化接口和组件,降低了嵌入式开发的复杂性。CMSIS是ARM Cortex-M生态的核心支柱,在跨平台开发、代码重用和实时系统集成等方面有很大应用。开发者可借助CMSIS的模块化架构,快速构建高效、可移植的嵌入式应用。
3. CMSIS文件举例:
3.1 CMSIS的USART举例:本文通过USART来说明CMSIS的使用方法和优势。底层USART有一个结构体ARM_DRIVER_USART,此结构体中定义了很多操作USART硬件的接口函数:
3.2 ARM_DRIVER_USART内部函数的实现过程:比如STM32H7,使用ARM_DRIVER_USART时,需要提前利用STM32CUBE生成HAL_UART_MspInit()和HAL_UART_MspDeInit(),因为ARM_DRIVER_USART中的部分函数需调用它们初始化、操作串口:
但是NXP中的实现方法是不一样的,只是用户不需要关心,用户只要调用ARM_DRIVER_USART中的函数即可。
如果没有文件UART_STM32H7xx.c,可以按如下方法添加组件:
3.3 使用优势:比如创建通用模板库。在使用CMSIS中的ARM_DRIVER_USART来封装通用的串口初始化、发送、接受函数。比如做一个通用的USART初始化函数,不管在什么芯片上,用户只需调用user_usart_init()函数即可。在user_usart_init()函数中,去调用ARM_DRIVER_USART内部函数。
比如在STM32H7中,用户只需提前利用STM32CUBE生成HAL_UART_MspInit()和HAL_UART_MspDeInit(),然后移植对应的UART_STM32H7xx.c相关文件即可以使用user_usart_init()函数。而在NXP芯片中,用户只需移植对应LPC_xx_UART文件即可(这个文件的具体名称可能不正确。不记得了。方法是没问题的)。
3.4 事件回调函数的使用:在ARM_DRIVER_USART中配置好一个事件回调函数(用户实现),然后系统会在串口发送完成和接受完成回调函数中(开启中断后,硬件自动执行,不需要用户实现)给事件回调函数相关事件置位。这样用户通过判断事件回调函数中事件标志位便可以判断串口发送和接受情况:
3.5 补充知识:STM32CUBE生成代码(HAL库)初始化USART流程:
3.6 上述知识概述:
4. 总结:CMSIS是Cortex-M内核的重要组成部分。在CMSIS标志接口下,用户可以不用关心底层的实现过程,只需要编写自己用户层的代码即可,极大提高了代码的移植性、重用性和开发速度。