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
目录下创建 include
、lib
文件夹,将编译出 的 gsl
库的头文件 inlcude/gsl
放入到 components/Gsl/include
目录下,将 libgsl.a
、libgslcblas.a
放入到 components/Gsl/lib
目录下,并创建 CmakeLists.txt
文件,导入后文件目录如下:
编写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::gsl
、GSL::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::gsl
、GSL::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
链接成功。