cmsis和各种库的关系

佚名 / 2024-09-26 / 原文

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目录如下:
image

为构建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:
image
stm32 package
image

2)在keil中的Pack Installer查看
image

基于构建stm32 std库构建工程

image

对比

先看stm32工程,然后对比cmsis。

  1. stm32 std库工程对于core_cm3.h的头文件包含关系如下,即core_cm3.h包含于stm32f10x.h包含于stm32f10x_gpio.h
    image

  2. 之后观察CMSIS/Core/Template/Device_M目录下system_Device.csystem_Device.h
    image
    然后对比stm32工程下的system_stm32f10x.csystem_stm32f10x.h文件

    // 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 
    }
    
    // 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.csystem_stm32f10x.h基于cmsis的实现有紧密相关