ARM-software/CMSIS-DSP

GitHub: ARM-software/CMSIS-DSP

ARM 官方的嵌入式计算库,为 Cortex-M 和 Cortex-A 提供涵盖数学运算、信号变换、滤波及经典机器学习的高性能优化计算内核。

Stars: 1049 | Forks: 234

[![GitHub 发布(包含预发布版的最新版本)](https://img.shields.io/github/v/release/ARM-software/CMSIS-DSP?include_prereleases)](https://github.com/ARM-software/CMSIS-DSP/releases/latest) [![GitHub](https://img.shields.io/github/license/ARM-software/CMSIS-DSP)](https://github.com/ARM-software/CMSIS-DSP/blob/main/LICENSE) [![C 测试](https://img.shields.io/github/actions/workflow/status/ARM-software/CMSIS-DSP/runtest.yaml?logo=arm&logoColor=0091bd&label=C%20Cortex-M%20Tests)](https://github.com/ARM-software/CMSIS-DSP/actions/workflows/runtest.yaml) [![CPP 测试](https://img.shields.io/github/actions/workflow/status/ARM-software/CMSIS-DSP/runcpptest.yaml?logo=arm&logoColor=0091bd&label=CPP%20Cortex-M%20Tests)](https://github.com/ARM-software/CMSIS-DSP/actions/workflows/runcpptest.yaml) [![Neon 测试](https://img.shields.io/github/actions/workflow/status/ARM-software/CMSIS-DSP/runneontest.yaml?logo=arm&logoColor=0091bd&label=C%20Cortex-A%20Tests)](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 采用 [![License](https://img.shields.io/github/license/ARM-software/CMSIS-DSP?label)](https://github.com/ARM-software/CMSIS-DSP/blob/main/LICENSE) 许可。 # 贡献与 Pull Requests 接受在 [![License](https://img.shields.io/github/license/ARM-software/CMSIS-DSP?label)](https://github.com/ARM-software/CMSIS-DSP/blob/main/LICENSE) 许可下的贡献。请仅提交全部代码均由你本人编写的贡献。
标签:ARM架构, Bash脚本, C/C++, DSP, UML, 事务性I/O, 信号处理, 客户端加密, 嵌入式系统, 数学计算库, 逆向工具