cmsis和stm32中std库的关系
Referneces:
- STM32函数固件库
- CMSIS_6 -> 此为arm提出的cmsis6的标准,各个用arm作内核的mcu厂商在写自家的固件库时应该遵守的标准。以后以stm32为例说明
- 【STM32】驱动库的选择:CMSIS Driver、SPL、HAL、LL | 在ARM MDK、STM32Cube中如何选择? -> 感觉这篇文里对于cmsis库的描述有些不准。cmsis库不是对硬件操作的实现,而是一个模板
以下基于cmsis和stm32 std库进行一个对比
对比前准备工作
下载cmsis
arm官方提供的cmsis可以在github找到。链接如下:
https://github.com/ARM-software/CMSIS_6
(以上仅用于对比)
repo目录如下:
为构建stm32工程,配置好cmsis以及stm32 std库
随便在keil官网里找一款stm32的package,然后导入keil中。链接如下:
https://www.keil.arm.com/packs/stm32f1xx_dfp-keil/versions/
然后还有cmsis的package,下载好之后导入keil中。链接如下:
https://www.keil.arm.com/packs/cmsis-arm/versions/
(用于对stm32 std工程的创建,因为stm32的std库是基于cmsis的描述进行构建的)
完成之后可以用两种方式查看是否导入成功:
1)查看keil目录
cmsis:
stm32 package
2)在keil中的Pack Installer查看
基于构建stm32 std库构建工程
对比
先看stm32工程,然后对比cmsis。
1)stm32 std库工程对于core_cm3.h
的头文件包含关系如下,即core_cm3.h
包含于stm32f10x.h
包含于stm32f10x_gpio.h
2)之后观察CMSIS/Core/Template/Device_M目录下system_Device.c
和system_Device.h
然后对比stm32工程下的system_stm32f10x.c
和system_stm32f10x.h
文件
```c
// file name: system_stm32f10x.c
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
```
```c
// file name: system_Device.c
/*---------------------------------------------------------------------------
System initialization function
*---------------------------------------------------------------------------*/
void SystemInit (void)
{
/* ToDo: Add code to initialize the system.
Do not use global variables because this function is called before
reaching pre-main. RW section maybe overwritten afterwards. */
/* ToDo: Initialize VTOR if available */
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
SCB->VTOR = (uint32_t)(&__VECTOR_TABLE[0]);
#endif
/* ToDo: Enable co-processor if it is used */
#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \
(defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0U))
SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */
(3U << 11U*2U) ); /* enable CP11 Full Access */
#endif
/* ToDo: Initialize SAU if TZ is used */
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
TZ_SAU_Setup();
#endif
SystemCoreClock = SYSTEM_CLOCK;
}
```
可以发现stm32工程下的SystemInit
是根据cmsis下的ToDo
注释实现的。
在stm32工程中,除了还有一个名为stm32f10x.h
的头文件,与system_stm32f10x.c
和system_stm32f10x.h
基于cmsis
的实现紧密相关。其中stm32f10x.h
中实现了内存映射的功能,如下:
```c
...
/** @addtogroup Peripheral_memory_map
* @{
*/
#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */
#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */
#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */
#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */
/*!< Peripheral memory map */
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define TIM2_BASE (APB1PERIPH_BASE + 0x0000)
#define TIM3_BASE (APB1PERIPH_BASE + 0x0400)
#define TIM4_BASE (APB1PERIPH_BASE + 0x0800)
#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00)
...
```
3)以下则为stm32 std固件库基于cmsis的外设部分的实现,这里只列举gpio。其他timer/uart/i2c/spi等以此类推
stm32 std固件库包含关系:
cmsis包含关系:
(PS:对于其他使用arm内核的方案,如rlt,其外设驱动固件库的结构都大同小异,都是以cmsis为蓝本进行功能实现的r)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步