2、环境搭建与编译:Linux环境下的SOEM编译、Windows环境下的SOEM编译、CMakeLists.txt深度解析、依赖库分析
好,咱们正式开始动手了。
上一章聊了SOEM是什么、能干什么。这一章,咱们得把环境搭起来,把代码编译通过。说白了,就是让SOEM在你的电脑上先跑起来。
我个人习惯,拿到一个开源协议栈,第一件事不是读代码,而是先编译。编译通过了,心里才有底。你想想看,代码再漂亮,编译不过全是白搭。
2.1 Linux环境下的SOEM编译
Linux下编译SOEM,其实非常简单。我最早接触SOEM是在Ubuntu 16.04上,那时候踩了不少坑。现在好多了,CMake已经非常成熟。
第一步:安装依赖
SOEM在Linux上依赖两个东西:一个是CMake,一个是libpcap。libpcap是用来抓网络包的,SOEM底层通过它来收发EtherCAT帧。
sudo apt-get update
sudo apt-get install cmake libpcap-dev
嗯,这里要注意。有些老版本的Ubuntu,libpcap-dev的版本可能比较低,但不影响SOEM编译。我在项目中遇到过,用Ubuntu 18.04编译SOEM 1.3.1,完全没问题。
第二步:下载源码并编译
git clone https://github.com/OpenEtherCATsociety/SOEM.git
cd SOEM
mkdir build && cd build
cmake ..
make
就这么简单。编译完成后,你会在build目录下看到libsoem.so这个动态库,以及一些测试程序。
cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. 来指定安装路径。这样后续开发时,头文件和库文件都在标准位置,省去很多麻烦。
2.2 Windows环境下的SOEM编译
Windows下编译SOEM,说实话,比Linux麻烦一点。主要是因为Windows没有原生的libpcap,需要装WinPcap或Npcap。
第一步:安装工具链
我推荐用Visual Studio 2019或2022。当然,MinGW也行,但我个人更习惯VS。
第二步:安装WinPcap开发包
去WinPcap官网下载开发者包。安装后,记住安装路径,一般是 C:\WpdPack。
第三步:CMake配置
打开CMake GUI,源码目录选SOEM根目录,构建目录选build。点击Configure,选择Visual Studio生成器。
这时候CMake会报错,说找不到libpcap。别慌,你需要手动设置两个变量:
PCAP_INCLUDE_DIR:指向C:\WpdPack\IncludePCAP_LIBRARY:指向C:\WpdPack\Lib\x64\wpcap.lib
设置好后,再点Configure,应该就绿了。然后Generate,Open Project,在VS里编译即可。
2.3 CMakeLists.txt深度解析
好,编译通过了。但咱们不能就这么算了。你得知道CMakeLists.txt里到底写了什么。我带你一行一行看。
SOEM根目录下的CMakeLists.txt,大概200多行。核心逻辑其实就几块:
第一块:项目定义
cmake_minimum_required(VERSION 2.8)
project(soem VERSION 1.4.0 LANGUAGES C)
这里指定了最低CMake版本和项目名称。SOEM是用纯C写的,所以只启用C语言。
第二块:依赖查找
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PCAP libpcap)
endif()
if(NOT PCAP_FOUND)
find_path(PCAP_INCLUDE_DIR pcap.h)
find_library(PCAP_LIBRARY pcap)
endif()
这段代码很有意思。它先用pkg-config找libpcap,找不到再用find_path和find_library。为什么要这样?
我解释一下:pkg-config是Linux下的标准方式,但Windows下没有。所以SOEM做了兼容处理。你在Windows下手动设置PCAP_INCLUDE_DIR和PCAP_LIBRARY,就是绕过了pkg-config,直接告诉CMake库在哪。
第三块:源文件组织
set(SOEM_SRC
osal/osal.c
osal/linux/osal_linux.c
ethercatbase.c
ethercatcoe.c
ethercatconfig.c
ethercatdc.c
ethercatmain.c
ethercatprint.c
...)
这里把所有源文件列出来了。注意看,osal/linux/osal_linux.c是Linux平台特有的。如果是Windows,会换成osal/windows/osal_win32.c。这就是SOEM跨平台的秘密——通过OSAL层隔离平台差异。
第四块:库和目标
add_library(soem SHARED ${SOEM_SRC})
target_link_libraries(soem ${PCAP_LIBRARY})
target_include_directories(soem PUBLIC ${PCAP_INCLUDE_DIR})
这里生成动态库libsoem.so,并链接libpcap。注意PUBLIC关键字,意思是使用soem库的其他项目,也会自动包含libpcap的头文件路径。
2.4 依赖库分析
SOEM的依赖其实非常少。说白了,就一个libpcap。
libpcap是什么?
libpcap是Linux下的网络数据包捕获库。tcpdump、Wireshark底层都用它。SOEM用它来发送和接收EtherCAT帧。
你可能会问:为什么不用socket?
嗯,这个问题问得好。EtherCAT帧是直接在以太网层传输的,不经过TCP/IP协议栈。如果用socket,你只能发UDP/TCP包,没法发原始的以太网帧。而libpcap可以让你绕过协议栈,直接操作网络接口。
libpcap的核心API
SOEM只用到了libpcap的几个函数:
| 函数 | 作用 |
|---|---|
| pcap_open_live | 打开网络接口,准备抓包 |
| pcap_sendpacket | 发送原始以太网帧 |
| pcap_next_ex | 接收下一个数据包 |
| pcap_close | 关闭网络接口 |
你看,就这么几个函数。SOEM的底层网络操作,全靠它们。
2.5 本章知识体系
为了让你更直观地理解本章内容,我画了一张图:
这张图把本章的核心内容串起来了。Linux和Windows两条路径,最终都依赖libpcap。而CMakeLists.txt就是连接源码和编译器的桥梁。
好了,环境搭建就讲到这里。编译通过只是第一步,下一章咱们要真正开始读代码了。到时候,我会带你从main函数开始,一步步走进SOEM的世界。
公众号:蓝海资料掘金营,微信deep3321