ARM-software/CMSIS-DSP
GitHub: ARM-software/CMSIS-DSP
ARM 官方的嵌入式计算库,为 Cortex-M 和 Cortex-A 提供涵盖数学运算、信号变换、滤波及经典机器学习的高性能优化计算内核。
Stars: 1049 | Forks: 234
[](https://github.com/ARM-software/CMSIS-DSP/releases/latest) [](https://github.com/ARM-software/CMSIS-DSP/blob/main/LICENSE) [](https://github.com/ARM-software/CMSIS-DSP/actions/workflows/runtest.yaml) [](https://github.com/ARM-software/CMSIS-DSP/actions/workflows/runcpptest.yaml) [](https://github.com/ARM-software/CMSIS-DSP/actions/workflows/runneontest.yaml)
# CMSIS-DSP
## 关于
CMSIS-DSP 是一个针对嵌入式系统优化的计算库(由于历史遗留原因,其名称中包含了 DSP)。
它为 Cortex-M 和 Cortex-A 提供了优化的计算内核。
根据核心的不同提供了多种变体,并且当 Helium 或 Neon 扩展可用时,大多数函数都使用了向量化版本。
本仓库包含 CMSIS-DSP 库以及其他几个项目:
* 裸机 Cortex-M 或 Cortex-A 的测试框架
* 裸机 Cortex-M 的示例
* PythonWrapper
你不需要任何其他项目即可构建和使用 CMSIS-DSP 库。构建其他项目可能需要安装其他库(CMSIS)、其他工具(Arm Virtual Hardware)或 CMSIS 构建工具。
### CMSIS-DSP 内核
CMSIS-DSP 提供的内核(列表非详尽):
* 基础数学运算(实数、复数、四元数、线性代数、快速数学函数)
* DSP(滤波)
* 变换(FFT、MFCC、DCT)
* 统计
* 经典机器学习(支持向量机、用于聚类的距离函数等)
内核提供多种数据类型:f64、f32、f16、q31、q15、q7。
### Python 封装
还有一个可用的 [PythonWrapper](https://pypi.org/project/cmsisdsp/),可以通过以下命令安装:
`pip install cmsisdsp`
使用此封装,你可以使用尽可能接近 C API 的接口在 Python 中设计算法。该封装与 NumPy 兼容,并且支持定点运算。此封装可以在 google colab 中运行。
其目的是让从设计到最终 C 语言实现的过程变得更加容易。
## 支持 / 联系方式
如有任何问题或需要联系 CMSIS-DSP 团队,请在 https://github.com/ARM-software/CMSIS-DSP/issues 创建新的 issue
## 目录
* [追求速度的构建](#building-for-speed)
* [推荐选项](#options-to-use)
* [应避免的选项](#options-to-avoid)
* [半精度浮点数支持](#half-float-support)
* [如何构建](#how-to-build)
* [如何使用 MDK 或 Open CMSIS-Pack 构建](#how-to-build-with-mdk-or-open-cmsis-pack)
* [如何使用 Make 构建](#how-to-build-with-make)
* [如何使用 cmake 构建](#how-to-build-with-cmake)
* [如何安装为 cmake 包](#how-to-install-as-a-cmake-package)
* [如何使用 Zephyr 构建](#how-to-build-with-zephyr)
* [如何使用任何其他构建系统构建](#how-to-build-with-any-other-build-system)
* [如何针对 Neon 和 aarch64 构建](#how-to-build-for-aarch64)
* [代码体积](#code-size)
* [文件夹和文件](#folders-and-files)
* [文件夹](#folders)
* [文件](#files)
## 追求速度的构建
当你需要高性能时,就会用到 CMSIS-DSP。因此,在编译 CMSIS-DSP 时,应使用能提供最佳性能的选项:
### 推荐选项
* 必须使用 `-O3 -ffast-math` 以获得最佳性能。
* 使用 Helium 时,强烈建议使用 `-O3 -ffast-math`
* 目前,在以 Helium 为目标时,`GCC` 无法提供良好的性能。你应该使用 Arm 编译器
当使用浮点数时,应选择 fpu,以确保编译器不会使用软件浮点模拟。
在开启 Helium 支持进行构建时,CMSIS-DSP 会自动检测到它。但对于 Neon 则不然,你必须在 C 编译时启用选项 `-DARM_MATH_NEON`。在使用 `cmake` 时,此选项由 `-DNEON=ON` 控制。
* 使用 cmake 编译时,还可以使用 `-DLOOPUNROLL=ON`
* 它对应的 C 选项是 `-DARM_MATH_LOOPUNROLL`
编译器会进行循环展开。因此,可能不需要此选项,但这高度依赖于所使用的编译器。对于某些编译器,需要此选项才能获得更好的性能。
内存速度也很重要。如果你能将 CMSIS-DSP 使用的数据和常量表映射到 `DTCM` 内存中,那就更好了。如果有缓存,请启用它。
### 应避免的选项
* `-fno-builtin`
* `-ffreestanding` 因为它会启用前一个选项
该库会进行一些类型[双关](https://en.wikipedia.org/wiki/Type_punning)(type punning)操作,以便将内存中的 32 位字处理为一对 `q15` 或四个 `q7`。这些类型操作是通过 `memcpy` 函数完成的。当拷贝的长度较小(4 字节)时,大多数编译器应该都能优化掉这些函数调用。
当使用 `-fno-builtin` 时,这种优化将**不会**发生,并且会对性能产生**非常糟糕的**影响。
某些编译器可能还需要使用 `-munaligned-access` 选项,以指定使用了非对齐访问。
## 半精度浮点数支持
库中添加了 `f16` 数据类型(半精度浮点数)。仅当你的 Cortex 具备某些半精度浮点硬件加速时(例如带有 Helium 扩展),它才有用。如果你不需要 `f16`,则应将其禁用,因为它可能会导致编译问题。只需在构建时定义 `-DDISABLEFLOAT16` 即可。
## 如何构建
你可以使用 Open CMSIS-Pack、cmake 或 Makefile 来构建 CMSIS-DSP,如果你使用任何其他构建工具,也很容易进行构建。
### 如何使用 MDK 或 Open CMSIS-Pack 构建
标准的构建方式是使用 CMSIS pack 技术。CMSIS-DSP 可作为一个 pack 提供。
你可以使用 [CMSIS-Toolbox](https://open-cmsis-pack.github.io/cmsis-toolbox/) 或任何一款 [Arm Keil IDE](https://www.keil.arm.com/)
如果你想为 `Corstone-300` 虚拟硬件平台构建 `FFT` 示例,你只需执行以下操作:
`cbuild -O cprj examples_ac6.csolution.yml --update-rte -r --toolchain AC6 -c fftbin.Release+VHT-Corstone-300"`
在 `Examples/cmsis_build` 文件夹中运行,并假设已安装命令行工具和所需的 pack。
### 如何使用 Make 构建
在 `Source` 中有一个 `Makefile` 示例。
在每个源码文件夹中(如 `BasicMathFunctions`),你会看到没有 `_datatype` 后缀的文件(如 `BasicMathFunctions.c` 和 `BasicMathFunctionsF16.c`)。
你的 makefile 只需要这些文件即可。它们包含了源码文件夹中的所有其他 C 文件。
然后,对于包含路径,你需要添加:`Include`、`PrivateInclude`,并且由于存在对 CMSIS Core 的依赖,还需要 `CMSIS_5/CMSIS` 中的 `Core/Include`。
如果你是为 `Cortex-A` 进行构建并希望使用 Neon,你还需要包含 `ComputeLibrary/Include` 以及 `ComputeLibrary/Source` 中的源文件。
### 如何使用 cmake 构建
创建一个 `CMakeLists.txt` 并在其中添加一个项目。
将 CMSIS-DSP 作为一个子目录添加。在下面的示例中,变量 `CMSISDSP` 是 CMSIS-DSP 仓库的路径。
```
cmake_minimum_required (VERSION 3.14)
# 定义项目
project (testcmsisdsp VERSION 0.1)
add_subdirectory(${CMSISDSP}/Source bin_dsp)
```
CMSIS-DSP 依赖于 CMSIS Core 的头文件。因此,你应该在 cmake 命令行中定义 `CMSISCORE`。CMSIS-DSP 将使用 `${CMSISCORE}/Include` 作为路径。
你还应该设置用于构建该库的编译选项。
如果为 Helium 构建,你应该使用 `MVEF`、`MVEI` 或 `HELIUM` 中的任何一个选项。
如果为 Neon 构建,请使用 `NEON` 和/或 `NEONEXPERIMENTAL`。
#### 启动构建
一旦 cmake 生成了 makefile,你就可以使用 GNU Make 来进行构建。
```
make VERBOSE=1
```
### 如何安装为 cmake 包
CMSIS-DSP 可以作为 cmake 包安装,用于在 Windows、macOS 或 Linux 上进行主机构建。将 `CMAKE_INSTALL_PREFIX` 设置为必须安装该包的文件夹。安装的包导出了目标 `CMSISDSP::CMSISDSP`。头文件安装在 `include/CMSIS-DSP` 下,以避免与其他包冲突,但应用程序在与 `CMSISDSP::CMSISDSP` 链接时,仍然可以通过 `#include "arm_math.h"` 来包含 CMSIS-DSP 头文件。当设置了 `CMSISCORE` 时,包安装将被禁用,因为 `CMSISCORE` 通常用于由 CMSIS Toolbox 或 Zephyr 处理的 Cortex-M 构建。
为了在带有 Neon 的 Arm 主机上获得最佳性能,请在 `Release` 模式下构建,启用 `HOST` 和 `NEON`,并使用 `-O3 -ffast-math`:
```
cmake -S . -B build-cmsisdsp-neon \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/path/to/cmsis-dsp-install \
-DHOST=ON \
-DNEON=ON \
-DCMAKE_C_FLAGS_RELEASE="-O3 -ffast-math"
cmake --build build-cmsisdsp-neon
cmake --install build-cmsisdsp-neon
```
对于 Windows 或 x86 主机构建,请勿启用 `NEON`。`HOST=ON` 移除了对主机编译器的 CMSIS Core 内联函数依赖。如果不需要 float16 支持,设置 `DISABLEFLOAT16=ON` 可以避免编译器支持问题。
在 Linux 或 macOS x86 上:
```
cmake -S . -B build-cmsisdsp-host \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/path/to/cmsis-dsp-install \
-DHOST=ON \
-DDISABLEFLOAT16=ON \
-DCMAKE_C_FLAGS_RELEASE="-O3 -ffast-math"
cmake --build build-cmsisdsp-host
cmake --install build-cmsisdsp-host
```
在带有 Visual Studio 的 Windows 上:
```
cmake -S . -B build-cmsisdsp-host `
-G "Visual Studio 17 2022" -A x64 `
-DCMAKE_INSTALL_PREFIX=C:\cmsis-dsp-install `
-DHOST=ON `
-DDISABLEFLOAT16=ON `
-DCMAKE_C_FLAGS_RELEASE="/O2 /fp:fast"
cmake --build build-cmsisdsp-host --config Release
cmake --install build-cmsisdsp-host --config Release
```
对于 MSVC,`/O2 /fp:fast` 是等同于 `-O3 -ffast-math` 的高性能等效设置。
然后,应用程序可以使用已安装的包:
```
find_package(CMSISDSP CONFIG REQUIRED)
target_link_libraries(my_application PRIVATE CMSISDSP::CMSISDSP)
```
使用指向安装文件夹的 `CMAKE_PREFIX_PATH` 配置应用程序:
```
cmake -S my_application -B build-my-application -DCMAKE_PREFIX_PATH=/path/to/cmsis-dsp-install
```
如果不需要该包,请在配置 CMSIS-DSP 时传入 `-DCMSISDSP_INSTALL=OFF`。
### 如何使用 Zephyr 构建
将以下内容添加到你的 west 文件中:
```
- name: cmsis-dsp
url: https://github.com/ARM-software/CMSIS-DSP
revision: main
path: modules/lib/cmsis-dsp
```
### 如何使用任何其他构建系统构建
你需要以下文件夹:
* Source
* Include
* PrivateInclude
* ComputeLibrary(仅当你的目标是 Neon 时)
* Ne10(仅当你的目标是 Neon 时)
在 `Source` 子文件夹中,你可以构建所有带有数据类型后缀(如 `_f32.c`)的源文件,或者只编译没有数据类型后缀的文件。例如对于 `BasicMathFunctions`,你可以构建除了 `BasicMathFunctions.c` 和 `BasicMathFunctionsF16.c` 之外的所有 C 文件,或者你可以只构建这两个文件(它们包含了该文件夹中所有其他的 C 文件)。
`f16` 文件不是强制性的。你可以通过定义 `-DDISABLEFLOAT16` 进行构建
### 如何针对 Neon 和 aarch64 构建
`Core_A/Include` 中定义的内联函数在较新的 Cortex-A 处理器上不可用。
但是,你仍然可以为这些 Cortex-A 核心进行构建,并从 Neon 内联函数中受益。
你需要在编译器命令行上使用 `-D__GNUC_PYTHON__` 进行构建。引入此标志是为了构建 Python 封装,它会禁用 CMSIS Core 头文件的使用。
启用此标志后,CMSIS-DSP 会定义一些用于库中编译器可移植性的宏:
```
#define __ALIGNED(x) __attribute__((aligned(x)))
#define __STATIC_FORCEINLINE static inline __attribute__((always_inline))
#define __STATIC_INLINE static inline
```
如果你使用的编译器需要不同的定义,可以将它们添加到库 `Include` 文件夹中的 `arm_math_types.h` 中。MSVC 和 XCode 已经受到支持,在这种情况下,你不需要定义 `-D__GNUC_PYTHON__`
然后,你需要定义 `-DARM_MATH_NEON`
对于 cmake,等效的选项为:
* `-DHOST=ON`
* `-DNEON=ON`
cmake 会自动包含 `ComputeLibrary` 文件夹。如果你使用的是不同的构建系统,你也需要包含此文件夹才能在支持 Neon 的情况下进行构建。
Neon 上的一些 API 会有所不同:
* CFFT 和 RFFT F32 具有不同的 API。它们不再支持原地(in-place)操作,并且需要使用额外的临时缓冲区
* MFCC F32 需要使用第二个临时缓冲区
有关这些额外缓冲区的大小,请参见 Doxygen 文档。你还可以查看 `Testing/Source/Tests` 中的测试,了解如何使用这些函数。
## 代码体积
早期版本的库使用编译指令来控制代码体积。这太复杂了,而且在 CMSIS-DSP 仅作为静态库提供的情况下不可用。
现在,该库再次依赖链接器来进行代码体积优化。但是,这意味着对你编写的代码有一些限制,并且不得不引入了一些新的函数。
如果你事先知道 FFT 的大小,请使用像 `arm_cfft_init_64_f32` 这样的初始化函数,而不是使用通用的初始化函数 `arm_cfft_init_f32`。使用通用函数将导致链接器无法推断出 FFT 必须保留哪些函数和,从而将所有内容都包含进去。
RFFT、MFCC 等也有类似的函数。
如果仍然设置了标志 `ARM_DSP_CONFIG_TABLES`,你现在将收到编译错误,以此提醒你该标志不再对代码体积产生任何影响,你可能需要重新修改初始化代码。
## 文件夹和文件
构建和使用 CMSIS-DSP 库仅需以下文件夹:
* Source
* Include
* PrivateInclude
* ComputeLibrary(仅在使用 Neon 时)
其他文件夹属于不同的项目、测试或示例。
### 文件夹
* cmsisdsp
* 为 Python 仓库构建 CMSIS-DSP PythonWrapper 所需
* 它包含所有的 Python 包
* ComputeLibrary:
* 在开启 Neon 加速构建 CMSIS-DSP 时所需的一些内核
* Examples:
* 在裸机 Cortex-M 上使用 CMSIS-DSP 的示例
* 需要使用 CMSIS 构建工具
* Include:
* CMSIS-DSP 的包含文件
* PrivateInclude:
* 构建 CMSIS-DSP 所需的一些头文件
* PythonWrapper:
* CMSIS-DSP PythonWrapper 的 C 代码
* PythonWrapper 的示例
* Scripts:
* 调试脚本
* 用于生成 CMSIS-DSP 使用的某些系数表的脚本
* Source:
* CMSIS-DSP 源码
* Testing:
* 裸机 Cortex-M 和 Cortex-A 的 CMSIS-DSP 测试框架
* 需要使用 CMSIS 构建工具
### 文件
生成 PythonWrapper 需要一些文件:
* PythonWrapper_README.md
* LICENSE
* MANIFEST.in
* pyproject.toml
* setup.py
# 许可证
CMSIS-DSP 采用 [](https://github.com/ARM-software/CMSIS-DSP/blob/main/LICENSE) 许可。
# 贡献与 Pull Requests
接受在 [](https://github.com/ARM-software/CMSIS-DSP/blob/main/LICENSE) 许可下的贡献。请仅提交全部代码均由你本人编写的贡献。
标签:ARM架构, Bash脚本, C/C++, DSP, UML, 事务性I/O, 信号处理, 客户端加密, 嵌入式系统, 数学计算库, 逆向工具