你如何在没有 IDE 的情况下使用 CMSIS?

How do you use CMSIS without an IDE?

我正在使用 STM32F103C8T6,并且想使用 CMSIS,which is essentially just register definitions and no code,让我的生活更轻松,同时仍然保持在低水平。问题是我不知道如何使用 Makefile 安装在命令行上使用的库。所有文档似乎都与特定于供应商的 IDE 绑定,例如 STM32CubeIDE.

我想首先要做的是下载CMSIS库,我在GitHub. However, after unzipping ARM.CMSIS.5.6.0.pack I found no files named stm32f10x.h. I spend some more time and found a CMSIS pack for the specific MCU I'm using, but it doesn't contain core_cm3.h, which however presents in ARM.CMSIS.5.6.0.pack. The document上找到说我需要将两者都包含到我的项目中,所以我需要复制从不同地方下载的文件吗到我的项目,或者什么?

作为加分题:CMSIS和科力有什么关系?特定于设备的 CMSIS 包是从 www.keil.com 下载的,但我暂时不想使用 Keil MDK,因为它似乎是一种商业产品,而且 GNU Arm 工具链对我来说非常有用。


编辑: 我应该从一开始就更具体一些,但现在让我们关注如何将 Basic CMSIS Example 构建为一个最小的、完整的和可验证的示例。

我做了什么:

  1. 分别下载 CMSIS-Core 和 CMSIS-DFP 并将其解压缩到 /Users/nalzok/Developer/CMSIS/ARM.CMSIS.5.6.0//Users/nalzok/Developer/CMSIS/Packs/Keil.STM32F1xx_DFP.2.3.0/
  2. 创建一个名为 main.c 的文件,并将 the basic example 的内容复制到其中。
  3. 在第一行添加#define STM32F10X_MD以指定芯片。
  4. 修正拼写错误:将第 31 行的 : 替换为 ;,并将第 33 行替换为 timer1_init (42);.
  5. 构建并出现错误

/tmp $ arm-none-eabi-gcc -I/Users/nalzok/Developer/CMSIS/ARM.CMSIS.5.6.0/CMSIS/Include/ -I/Users/nalzok/Developer/CMSIS/Packs/Keil.STM32F1xx_DFP.2.3.0/Device/Include/ main.c
main.c: In function 'main':
main.c:42:5: warning: implicit declaration of function 'Get_InputValues' [-Wimplicit-function-declaration]
   42 |     Get_InputValues ();                          // Read Values
      |     ^~~~~~~~~~~~~~~
main.c:44:5: warning: implicit declaration of function 'Calculation_Response' [-Wimplicit-function-declaration]
   44 |     Calculation_Response ();                     // Calculate Results
      |     ^~~~~~~~~~~~~~~~~~~~
main.c:45:5: warning: implicit declaration of function 'Output_Response' [-Wimplicit-function-declaration]
   45 |     Output_Response ();                          // Output Results
      |     ^~~~~~~~~~~~~~~
/var/folders/m4/7my6q_kj6pxgzb1b7pxyhp0h0000gn/T//cc1ZVBaH.s: Assembler messages:
/var/folders/m4/7my6q_kj6pxgzb1b7pxyhp0h0000gn/T//cc1ZVBaH.s:197: Error: selected processor does not support `wfe' in ARM mode
/var/folders/m4/7my6q_kj6pxgzb1b7pxyhp0h0000gn/T//cc1ZVBaH.s:310: Error: selected processor does not support `cpsid i' in ARM mode
/var/folders/m4/7my6q_kj6pxgzb1b7pxyhp0h0000gn/T//cc1ZVBaH.s:318: Error: selected processor does not support `cpsie i' in ARM mode

根据@KamilCuk 下面的评论,我添加了更多选项并注释掉了函数 Get_InputValuesCalculation_ResponseOutput_Response,但现在我遇到了一些不同的错误。

/tmp $ arm-none-eabi-gcc -I/Users/nalzok/Developer/CMSIS/ARM.CMSIS.5.6.0/CMSIS/Include/ -I/Users/nalzok/Developer/CMSIS/Packs/Keil.STM32F1xx_DFP.2.3.0/Device/Include/ -D STM32F1 -D STM32F103x6 -mthumb -mcpu=cortex-m3 main.c
/Users/nalzok/opt/xPacks/arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/nalzok/opt/xPacks/arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libc.a(lib_a-exit.o): in function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
/Users/nalzok/opt/xPacks/arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /var/folders/m4/7my6q_kj6pxgzb1b7pxyhp0h0000gn/T//ccqfC5LA.o: in function `Device_Initialization':
main.c:(.text+0x164): undefined reference to `SystemCoreClock'
collect2: error: ld returned 1 exit status

你说的CMSIS部分,有的是ARM提供的(CMSIS核心),有的是你的芯片供应商(Device Family Pack)提供的。正如您所发现的,CMSIS 软件包只是 zip 文件的另一个名称。您可以将它们解压缩到任何您想要的位置。如您所知,核心 CMSIS 和大多数供应商特定部分仅包含头文件。然后需要在编译器包含路径中包含正确的目录,通常使用 -I... 命令行选项。

一种类型的供应商软件包称为设备系列包。除了供应商特定的外设定义之外,它们通常包含启动代码,并且通常包含与 SOC 内存布局相匹配的链接描述文件。这些是值得寻找的,将节省矢量 table 布局和其他此类低级代码的工作。

作为奖励:Keil 是一家软件工具制造商,归 ARM 所有。 Keil IDE 支持 CMSIS 软件包的更好功能,例如通过网络分发和更新它们,并且 Keil 维护着一个通用 SOC 包的存储库。我通常也使用 GNU 编译器,但使用 Keil 及其内置的 CMSIS 感知和软件包可用性效果很好。我什至为定制工作构建了一些软件包。我建议继续阅读 CMSIS documentation paying some attention to the section on packs。您不必有一个 IDE 来为您管理包。由于它们只是 zip 文件,因此您需要自己完成这项任务。

对于最新的设备headers,我建议从ST网站下载STM32CubeF1包。除其他内容(中间件、HAL 等)外,此软件包在 /Drivers/CMSIS/Device 文件夹中包含所需的设备 headers。您需要为 stm32f1xx.h header 定义的 STM32F103xB 符号才能正常工作。

当然,STM32CubeF1 软件包也包含 CMSIS 库,但它们通常有点过时。我更喜欢从您提到的 github 存储库中将它们下载为 .pack 文件。您至少需要 /CMSIS/Core 中的 header。如果您愿意,可以添加 CMSIS 的其他部分。其中一些(如 DSP)可能还需要您添加 /Lib 文件夹中提供的静态库。

请注意,如果您从 github 克隆 CMSIS 存储库而不是下载 .pack 文件,您最终会得到静态库的占位符版本,因为该项目使用 git LFS。您不能直接使用这些静态库文件(.a 文件),因为它们只是某种指针。我不熟悉 git LFS,但我猜你需要一些 git 命令(可能是结帐)来告诉你的 PC 下载实际的 .a 文件.

另请注意,有时 CMSIS 文件夹结构会因版本而异。您在 STM32CubeF1 中获得的文件夹结构可能与您从官方 CMSIS 存储库下载的不同。

忘了说:除了CMSIS和ST设备headers,你还需要以下文件:

  • system_stm32f1xx.c(STM32CubeF1/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates文件夹)
  • startup_stm32f103xb.s(STM32CubeF1/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc文件夹)
  • 来自 STM32CubeF1/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/linker 文件夹的链接描述文件。奇怪的是,STM32F103x8 有 none,因此您可能需要选择 STM32F103xB 并对其进行修改。我使用 IDE 生成的。

更新:

Here 您可以找到一个在 STM32CubeIDE 中创建的最小项目。我创建了一个空的 C 项目。 IDE 提供了一个链接器脚本和一个启动文件 (.s),但我删除了它们并使用了 STM32CubeF1 包中包含的那些。我还从 /Drivers/Device/ST/STM32F1xx/Include 目录中删除了不相关的 header 文件。但是我没有触及 /Drivers/CMSIS/Core/Include 中的那些,尽管那里有很多不相关的文件,因为很难确定哪些需要哪些不需要。

我知道您正在寻找没有 IDE 的解决方案,但我认为这个示例项目至少可以为您提供一些有关所需文件和项目结构的线索。

注意:示例项目名称为blinky.cube但是项目中没有Cube。我使用此命名约定只是为了指定我使用的 IDE,在本例中为 STM32CubeIDE。