第二章:CANopenNode源码获取与编译
好,咱们正式开始动手了。这一章,我带你走一遍CANopenNode的源码获取和编译流程。说白了,就是先把代码拿到手,然后在Linux上跑通,最后为移植到STM32做准备。
我个人习惯,拿到一个开源项目,第一件事就是看它的目录结构和编译方式。这就像你拿到一个新工具,先掂量掂量分量,看看手感。CANopenNode这个项目,结构挺清晰的,咱们一步步来。
2.1 从GitHub上把代码拉下来
这个没啥好说的,用git clone就行。但我建议你fork一下再clone,这样你后面改代码、提PR都方便。
git clone https://github.com/CANopenNode/CANopenNode.git
cd CANopenNode
git checkout master
嗯,这里要注意:别用默认的develop分支。我在项目中遇到过,develop分支有时候会有一些实验性的改动,不够稳定。master分支是经过测试的,拿来用最靠谱。
拉下来之后,看看目录结构:
CANopenNode/— 核心协议栈代码CANopenSocket/— Linux下的socketCAN接口example/— 示例程序doc/— 文档test/— 测试代码
你想想看,一个协议栈项目,核心代码其实没多少。真正让你头疼的,往往是硬件接口和操作系统适配。CANopenNode把这两部分分得很开,这点做得不错。
2.2 Linux环境下的编译
我建议你在Ubuntu 20.04或22.04上编译。为什么?因为这两个版本的gcc和cmake版本都比较新,而且社区支持好。我曾经在CentOS 7上折腾过,那叫一个痛苦——cmake版本太老,还得手动升级。
先装依赖:
sudo apt-get update
sudo apt-get install build-essential cmake git
sudo apt-get install libsocketcan-dev # 如果你要用socketCAN
然后编译:
mkdir build && cd build
cmake ..
make -j4
这里有个小坑:cmake .. 的时候,可能会报找不到某些库。别慌,看看错误信息,缺什么装什么。我遇到过缺libsocketcan的情况,装一下就好了。
编译成功后,你会看到几个可执行文件:
CANopenDemo— 一个完整的CANopen从站示例CANopenMaster— 主站示例CANopenTest— 测试程序
2.3 编译选项的玄机
cmake的时候,你可以加一些选项来控制编译内容。我个人常用的几个:
cmake .. -DCANOPEN_SUPPORT_SDO=ON -DCANOPEN_SUPPORT_EMCY=ON
这些选项控制着协议栈的功能模块。你想想看,如果你的设备不需要紧急报文(EMCY),那就可以关掉,省点代码空间。对于STM32这种资源受限的平台,这个功能特别有用。
常用的选项有:
| 选项 | 说明 | 默认值 |
|---|---|---|
| CANOPEN_SUPPORT_SDO | SDO服务 | ON |
| CANOPEN_SUPPORT_PDO | PDO服务 | ON |
| CANOPEN_SUPPORT_EMCY | 紧急报文 | ON |
| CANOPEN_SUPPORT_LSS | LSS服务 | OFF |
嗯,这里要注意:LSS默认是关的。如果你需要LSS(比如做节点ID自动分配),记得手动打开。
2.4 为STM32移植做准备
好了,Linux上跑通了,接下来要考虑怎么移植到STM32上。这一步其实是最关键的,因为STM32的资源比PC少得多。
首先,你得理解CANopenNode的架构。它把硬件抽象层(HAL)单独拿出来了。你只需要实现几个接口函数:
CANopenNode_Init()— 初始化CANopenNode_Process()— 主循环调用CANopenNode_Stop()— 停止
说白了,你只需要关心这三个函数。其他的,协议栈自己搞定。
我建议你先把STM32的CAN外设驱动写好,然后照着Linux版本的HAL实现,把接口填上。具体怎么做,下一章我会详细讲。
另外,定时器中断的优先级也要注意。CANopenNode内部用了一个定时器来做心跳和超时处理。这个中断的优先级不能太低,否则会影响实时性。我曾经在一个项目里,把定时器中断优先级设得太低,结果心跳报文老是超时,排查了半天才发现是这个问题。
2.5 一个简单的测试
移植之前,我建议你先在Linux上跑一下示例程序,熟悉一下流程。这样你移植到STM32后,心里有底。
# 启动虚拟CAN
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0
# 运行示例
./build/CANopenDemo vcan0
如果一切正常,你会看到终端打印出一些状态信息。嗯,看到这些信息,说明你的环境已经准备好了。
好了,这一章就到这里。下一章,我们正式进入STM32移植的实战环节。到时候,我会手把手教你如何把CANopenNode跑在STM32上。