ESP32:连接外部库GSL

本文使用 Vscode + ESP-IDF 环境搭建工程。

简介

GSL 全称 GNU Scientific Library,它是一个开源的数值计算库,用于提供一系列数学函数和算法,用于解决科学和工程领域的数值计算问题。GNU Scientific Library 提供了许多常见的数学函数,包括线性代数、微积分、特殊函数、随机数生成、优化、数值积分等。

该库是用 C 语言编写的,但也提供了 C++、Fortran、Python 等语言的接口。它可以在 Linux、Windows 和其他类 Unix 系统上使用。

一些常见的功能和模块包括:

  • 线性代数:矩阵和向量运算、线性方程组求解、特征值和特征向量计算等。
  • 微积分:数值积分、微分方程求解等。
  • 特殊函数:贝塞尔函数、超几何函数等。
  • 随机数生成:各种分布的随机数生成器。
  • 最优化:非线性优化、曲线拟合等。

如果你正在进行科学计算或工程计算,并且需要一个功能丰富的数值计算库,GNU Scientific Library 可能是一个很好的选择。

博主在使用ESP32开发项目时,遇到了使用非线性最小二乘法对曲线进行拟合的需求,于是选择使用GSL库实现功能。

导入

生成GSL静态库

在Linux环境下通过 ESP-IDF 自带的交叉编译器编译 gsl 库,并生成.a静态库,实现细节参考:Linux下编译GSL库为ARM框架库文件

导入库到工程下

在ESP32工程目录 components/ 文件夹下创建 Gsl 目录,在 Gsl 目录下创建 includelib 文件夹,将编译出 的 gsl 库的头文件 inlcude/gsl 放入到 components/Gsl/include 目录下,将 libgsl.alibgslcblas.a 放入到 components/Gsl/lib 目录下,并创建 CmakeLists.txt 文件,导入后文件目录如下:

esp32 控制5v继电器 esp32连接继电器_gnu

编写CmakeLists.txt

打开CmakeLists.txt,并添加如下内容:

# Compiling and Linking the Library
# We have to make the component know where its .h files are
# and where to find its .a file.
# the GSL documentation says that for some functions both lgslcblas and lgsl must be linked in order to work properly
# (https://www.gnu.org/software/gsl/doc/html/usage.html#linking-programs-with-the-library)
# 
idf_component_register(INCLUDE_DIRS "./include")
set(ENV{GSL_ROOT_DIR} "D:/WXHY/NTSB/CORE-Board/CoreBoard/components/Gsl")

find_package(GSL REQUIRED)

target_link_libraries(${COMPONENT_LIB} INTERFACE GSL::gsl GSL::gslcblas)
  • idf_component_register(INCLUDE_DIRS "./include") 指定包含头文件路径为 ./include
  • set(ENV{GSL_ROOT_DIR} "D:/WXHY/NTSB/CORE-Board/CoreBoard/components/Gsl")创建环境变量 GSL_ROOT_DIR为后续连接GSL库需要;
  • find_package(GSL REQUIRED)调用Cmake提供的FindGSL模块,会按照GSL_ROOT_DIR环境变量的路径查找gsl的头文件和库所在路径,并生成库GSL::gslGSL::gslcblas,如下:
#.\Espressif\tools\cmake\3.16.4\share\cmake-3.16\Modules\FindGSL.cmake:
...
  else()
    # For all other environments (ones without dll libraries), create
    # the imported library targets.
    add_library( GSL::gsl      UNKNOWN IMPORTED )
    add_library( GSL::gslcblas UNKNOWN IMPORTED )
    set_target_properties( GSL::gslcblas PROPERTIES
      IMPORTED_LOCATION                 "${GSL_CBLAS_LIBRARY}"
      INTERFACE_INCLUDE_DIRECTORIES     "${GSL_INCLUDE_DIRS}"
      IMPORTED_LINK_INTERFACE_LANGUAGES "C" )
    set_target_properties( GSL::gsl PROPERTIES
      IMPORTED_LOCATION                 "${GSL_LIBRARY}"
      INTERFACE_INCLUDE_DIRECTORIES     "${GSL_INCLUDE_DIRS}"
      IMPORTED_LINK_INTERFACE_LANGUAGES "C"
      INTERFACE_LINK_LIBRARIES          GSL::gslcblas )
  endif()

关于find_package()的详解可参考:https://zhuanlan.zhihu.com/p/631259689

  • target_link_libraries(${COMPONENT_LIB} INTERFACE GSL::gsl GSL::gslcblas)连接GSL::gslGSL::gslcblas到工程中。

至此CmakeLists.txt编写完成。

编译测试

main.c中添加如下代码:

#include <stdio.h>
#include <gsl/gsl_math.h>

int app_main() 
{
    double x = 1.23;
    double result = gsl_pow_2(x);

    printf("The square of %.2f is %.2f\n", x, result);

	while(1)
    {
	}
}

编译下载到ESP32板卡中,打开监视器,输出如下信息:

The square of 1.23 is 1.51

链接成功。