第二讲:环境搭建——交叉编译工具链安装、Linux内核头文件准备、CMake工程创建、第一个Hello SOEM程序
各位同学,欢迎来到第二讲。
上一讲我们聊了SOEM的整体架构和它能干什么。今天咱们要动真格的了——把开发环境搭起来,然后跑通第一个SOEM程序。
环境搭建这事儿,说简单也简单,说坑也多。我这些年帮不少团队搭过环境,见过有人卡在工具链版本上三天搞不定。所以这一讲,我会把每一步的关键点都点出来。
2.1 交叉编译工具链安装
做嵌入式开发,交叉编译是绕不开的。说白了,就是你在PC上写代码,编译出来的程序要在ARM板子上跑。
第一步:选择工具链
我个人习惯用Linaro提供的GCC工具链,稳定且社区活跃。以ARM Cortex-A系列为例,常用的版本是:
gcc-arm-linux-gnueabihf—— 针对ARMv7-A,硬浮点aarch64-linux-gnu—— 针对ARMv8-A,64位
第二步:安装
在Ubuntu 20.04/22.04上,直接apt安装就行:
sudo apt update
sudo apt install gcc-arm-linux-gnueabihf
sudo apt install gcc-aarch64-linux-gnu
安装完成后,验证一下:
arm-linux-gnueabihf-gcc --version
第三步:设置环境变量
我习惯把工具链路径加到~/.bashrc里:
export CROSS_COMPILE=arm-linux-gnueabihf-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
然后source ~/.bashrc让它生效。
2.2 Linux内核头文件准备
SOEM在Linux上跑,需要内核头文件来编译。为什么呢?因为SOEM底层要调用socket、ioctl这些系统调用,需要知道内核的数据结构定义。
方法一:使用目标板的内核头文件
这是最稳妥的做法。把板子上的/usr/include或内核源码里的include/uapi目录拷贝到你的开发机上。
方法二:使用通用内核头文件
如果只是编译SOEM应用层,用通用头文件也够用:
sudo apt install linux-libc-dev-armhf-cross
2.3 CMake工程创建
SOEM官方用的是CMake构建系统。咱们也用它,方便管理。
第一步:安装CMake
sudo apt install cmake cmake-curses-gui
第二步:创建工程目录结构
我习惯这样组织:
soem_hello/
├── CMakeLists.txt
├── src/
│ └── main.c
├── lib/
│ └── soem/ # SOEM源码
└── build/
第三步:编写CMakeLists.txt
这里我直接给一个能用的模板:
cmake_minimum_required(VERSION 3.10)
project(soem_hello C)
# 设置交叉编译
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# 指定工具链
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
# 添加SOEM源码
add_subdirectory(lib/soem)
# 添加可执行文件
add_executable(soem_hello src/main.c)
# 链接SOEM库
target_link_libraries(soem_hello soem)
CMAKE_C_COMPILER指定编译器,否则CMake会默认用gcc,编译出来的东西在ARM板子上跑不了。
2.4 第一个Hello SOEM程序
好了,环境搭好了,咱们写个最简单的程序,验证一下SOEM能不能用。
代码:
// src/main.c
#include <stdio.h>
#include <soem/ethercat.h>
int main(int argc, char *argv[])
{
printf("Hello SOEM!\n");
printf("SOEM Version: %s\n", ec_version);
// 初始化EtherCAT
if (ec_init("eth0") > 0)
{
printf("EtherCAT initialized on eth0\n");
ec_close();
}
else
{
printf("Failed to initialize EtherCAT\n");
return -1;
}
return 0;
}
编译:
cd build
cmake ..
make
编译成功后,你会得到一个soem_hello可执行文件。用file命令看看:
file soem_hello
输出应该是类似:
soem_hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked
看到ARM字样,说明交叉编译成功了。
No such file or directory。查了半天,发现是动态链接库路径不对。解决办法:要么静态编译,要么把libsoem.so拷贝到板子的/usr/lib下。
2.5 本章知识体系
下面这张图,帮你理清今天讲的内容:
这张图把今天的内容串起来了。你想想看,从工具链到内核头文件,再到CMake工程,最后编译出能在ARM板子上跑的Hello程序——这就是一个完整的嵌入式开发流程。
2.6 验证与测试
把编译好的soem_hello拷贝到板子上:
scp soem_hello root@192.168.1.100:/root/
在板子上运行:
./soem_hello
如果看到:
Hello SOEM!
SOEM Version: 1.4.0
EtherCAT initialized on eth0
恭喜你,环境搭建成功了!
eth0网口,或者网口名字不一样(比如end0),记得把代码里的"eth0"改成实际的名字。我遇到过一块板子叫enp1s0,当时找了半天才找到原因。
好了,这一讲的内容就到这里。环境搭好了,下一讲我们就可以真正开始写SOEM的应用了。
公众号:蓝海资料掘金营,微信deep3321