CANopenNode/CANopenNode
GitHub: CANopenNode/CANopenNode
开源的CANopen协议栈完整实现,用于构建符合EN 50325-4工业标准的CAN总线嵌入式控制设备。
Stars: 1820 | Forks: 769
# CANopenNode
CANopenNode 是免费且开源的 CANopen 协议栈。
CANopen 是基于 CAN 构建的嵌入式控制系统的国际标准化 (EN 50325-4) ([CiA301](https://www.can-cia.org/cia-groups/technical-documents)) 高层协议。有关 CANopen 的更多信息,请参阅 http://www.can-cia.org/
CANopenNode 采用面向对象的方式以 ANSI C 编写。它运行于不同的微控制器上,可作为独立应用或与 RTOS 配合使用。
变量(通信、设备、自定义)收集在 CANopen 对象字典中,可从 C 代码和 CANopen 网络两方面进行访问。
CANopenNode 主页是 https://github.com/CANopenNode/CANopenNode
这是具有新对象字典实现的 CANopenNode 版本 4。旧版本请使用 `git checkout` 切换到分支 `v1.3-master` 或 `v2.0-master`。
## 特性
### CANopen
- [对象字典](https://www.can-cia.org/can-knowledge/canopen-internal-device-architecture/) 提供了对任何变量的清晰且灵活的组织方式。变量可以直接访问,也可以通过读/写函数访问。
- [NMT](https://www.can-cia.org/can-knowledge/network-management/) 从机用于启动、停止、复位设备。包含简单的 NMT 主机。
- [心跳](https://www.can-cia.org/can-knowledge/error-control-protocols) 生产者/消费者错误控制,用于监控 CANopen 设备。较旧的替代方案“节点保护”也可用。
- [PDO](https://www.can-cia.org/can-knowledge/pdo-protocol/) 用于以高优先级和无协议开销广播过程数据。对象字典中的变量可以动态映射到 TPDO,然后根据通信规则传输并由另一设备作为 RPDO 接收。支持位映射。
- [SDO](https://www.can-cia.org/can-knowledge/sdo-protocol/) 服务器允许对 CANopen 设备内的所有对象字典变量进行快速、分段和块传输访问。
- [SDO](https://www.can-cia.org/can-knowledge/sdo-protocol/) 客户端可以访问网络内任何 CANopen 设备上的任何对象字典变量。
- [紧急](https://www.can-cia.org/can-knowledge/special-function-protocols/) 消息生产者/消费者。
- [同步](https://www.can-cia.org/can-knowledge/special-function-protocols/) 生产者/消费者支持 PDO 对象等的网络同步传输。
- [时间戳](https://www.can-cia.org/can-knowledge/special-function-protocols/) 生产者/消费者支持毫秒分辨率的日期和时间同步。
- [LSS](https://www.can-cia.org/can-knowledge/cia-305-layer-setting-services-lss/) CANopen node-id 和比特率设置,主机和从机,LSS fastscan。
- [CANopen 网关](https://www.can-cia.org/can-knowledge/cia-309-series-accessing-canopen-via-tcp/),CiA309-3 Ascii 命令接口,用于 NMT 主机、LSS 主机和 SDO 客户端。
- [CANopen Safety](https://standards.globalspec.com/std/1284438/en-50325-5),EN 50325-5,CiA304,安全相关网络中的“类 PDO”通信。
- 已通过 [CANopen 一致性测试工具](https://www.can-cia.org/services/canopen-conformance-test-tool/)。
### 其他
- [适用于 16 位及以上微控制器](#device-support)
- [多线程,实时](#canopenNode-flowchart)
- [对象字典编辑器](#object-dictionary-editor)
- 用于对象字典或其他变量的非易失性存储。自动或通过标准 CANopen 命令控制,可配置。
- [支持省电模式](#power-saving)
- [支持 Bootloader](https://github.com/CANopenNode/CANopenNode/issues/111)(用于固件更新)
## 相关项目
- [CANopenNode](https://github.com/CANopenNode/CANopenNode)(本项目):CANopen 协议栈,CANopen 设备的基础。它不包含设备特定代码(驱动程序),必须为每个目标系统单独添加。示例展示了基本原理,可在任何系统上编译,但不连接任何 CAN 硬件。
- [CANopenDemo](https://github.com/CANopenNode/CANopenDemo):带有 CANopenNode 和不同目标系统的演示设备,包含教程和测试工具。
- [CANopenNode.github.io](https://github.com/CANopenNode/CANopenNode.github.io):Html 文档,由 doxygen 编译,用于 CANopenDemo、CANopenNode 和其他设备,也可在线访问:https://canopennode.github.io
- [CANopenEditor](https://github.com/CANopenNode/CANopenEditor):对象字典编辑器,外部 GUI 工具,用于编辑自定义设备的 CANopen 对象字典。它生成 C 源代码、电子数据表和设备文档。它是 [libedssharp](https://github.com/robincornelius/libedssharp) 的一个分支。
- [CANopenLinux](https://github.com/CANopenNode/CANopenLinux):Linux 设备上的 CANopenNode。它可以是基本的 CANopen 设备,也可以是具有 commander 功能的更高级设备。
- [CANopenSTM32](https://github.com/CANopenNode/CanOpenSTM32):STM32 微控制器上的 CANopenNode。
- [Analog Devices Inc.](https://github.com/Analog-Devices-MSDK/CANopenADI):Analog Devices Inc. MAX32xx 微控制器上的 CANopenNode。
- [CANopenPIC](https://github.com/CANopenNode/CANopenPIC):Microchip PIC 微控制器上的 CANopenNode。适用于 16 位和 32 位设备。包含 Arduino 风格 [Max32](https://reference.digilentinc.com/reference/microprocessor/max32/start) 开发板的示例。
- [doc/deviceSupport.md](doc/deviceSupport.md):不同设备上 CANopenNode 的其他实现列表。
## 文档、支持和贡献
所有代码均在源头文件中进行了记录。`doc` 目录中有一些附加文档。
要生成完整的 html 文档,请在项目基础目录中运行 [doxygen](https://www.doxygen.nl/index.html):`sudo apt install doxygen graphviz pdf2svg; doxygen > /dev/null`
完整的生成文档也可在线获取:https://canopennode.github.io
教程、演示设备和测试可在 [CANopenDemo](https://github.com/CANopenNode/CANopenDemo) 仓库中找到。
请在 https://github.com/CANopenNode/CANopenNode/issues 上报告问题。
欢迎贡献。贡献代码的最佳方式是复刻项目,修改它,然后发送 pull request。请遵循 [推荐的 C 风格和编码规则](https://github.com/MaJerle/c-code-style),使用 .clang-format 文件进行自动代码格式化。
CANopenNode 文件符合 [MISRA C:2012](https://www.misra.org.uk) 指南,但有一些注明的例外情况,如 [MISRA.md](MISRA.md) 中所示。
## CANopenNode 流程图
典型 CANopenNode 实现的流程图:
```
-----------------------
| Program start |
-----------------------
|
-----------------------
| CANopen init |
-----------------------
|
-----------------------
| Start threads |
-----------------------
| | |
-------------------- | --------------------
| | |
---------------------- ------------------------ -----------------------
| CAN receive thread | | Timer interval thread | | Mainline thread |
| | | | | |
| - Fast response. | | - Realtime thread with | | - Processing of time |
| - Detect CAN ID. | | constant interval, | | consuming tasks |
| - Partially process | | typically 1ms. | | in CANopen objects: |
| messages and copy | | - Network synchronized | | - SDO server, |
| data to target | | - Copy inputs (RPDOs, | | - Emergency, |
| CANopen objects. | | HW) to Object Dict. | | - Network state, |
| | | - May call application | | - Heartbeat. |
| | | for some processing. | | - LSS slave |
| | | - Copy variables from | | - Gateway (optional): |
| | | Object Dictionary to | | - NMT master |
| | | outputs (TPDOs, HW). | | - SDO client |
| | | | | - LSS master |
| | | | | - May cyclically call |
| | | | | application code. |
---------------------- ------------------------ -----------------------
```
CANopenNode 的所有代码都是非阻塞的。源文件中的代码被收集到对象中。代码的各部分可以启用/禁用,因此项目中只能使用所需的文件和代码部分。请参阅 301/CO_config.h 文件中的栈配置。
为了获得最高效率,代码可以在不同的线程中运行,如上图所示。这适用于微控制器。也可以从单个线程运行所有内容,如 Linux 设备上可用的那样。代码包含在必要时触发 OD 对象处理的机制。
在 CANopen 初始化部分,所有 CANopen 对象被初始化。在运行时,CANopen 对象被循环处理。
文件 CANopen.h 和 CANopen.c 是所有 CANopen 对象的集合。它可能看起来很复杂,但提供了一些灵活性,并且适用于 CANopen 对象的最常见配置。CANopen 对象可以在全局空间中定义,也可以动态分配。可以使用默认的对象字典(OD.h/.c 文件),但也可以通过 #CO_config_t 结构配置多个对象字典。CANopen.h 和 CANopen.c 文件也可以仅作为基于 CANopenNode 的设备更定制化实现的参考。
对象字典是所有网络可访问变量的集合,提供了最灵活的用法。OD 变量可以通过对象字典初始化,或者应用程序可以为特定 OD 变量指定自己的读/写访问函数。OD 变量组也可以按命令或自动存储到非易失性存储器中。
## 文件结构
- **301/** - CANopen 应用层和通信配置文件。
- **CO_config.h** - CANopenNode 的配置宏。
- **CO_driver.h** - CAN 硬件与 CANopenNode 之间的接口。
- **CO_ODinterface.h/.c** - CANopen 对象字典接口。
- **CO_Emergency.h/.c** - CANopen 紧急协议。
- **CO_HBconsumer.h/.c** - CANopen 心跳消费者协议。
- **CO_NMT_Heartbeat.h/.c** - CANopen 网络管理和心跳生产者协议。
- **CO_PDO.h/.c** - CANopen 过程数据对象协议。
- **CO_SDOclient.h/.c** - CANopen 服务数据对象 - 客户端协议(主机功能)。
- **CO_SDOserver.h/.c** - CANopen 服务数据对象 - 服务器协议。
- **CO_SYNC.h/.c** - CANopen 同步协议(生产者和消费者)。
- **CO_TIME.h/.c** - CANopen 时间戳协议。
- **CO_fifo.h/.c** - 用于 SDO 和网关数据传输的 Fifo 缓冲区。
- **crc16-ccitt.h/.c** - CRC 16 CCITT 多项式计算。
- **303/** - CANopen 建议。
- **CO_LEDs.h/.c** - CANopen LED 指示灯。
- **304/** - CANopen 安全相关数据对象,如 EN 50325-5:2010 所规定。
- **CO_SRDO.h/.c** - CANopen 安全相关数据对象协议。
- **CO_GFC.h/.c** - CANopen 全局故障安全命令(生产者和消费者)。
- **305/** - CANopen 层设置服务 (LSS) 和协议。
- **CO_LSS.h** - CANopen 层设置服务协议(通用)。
- **CO_LSSmaster.h/.c** - CANopen 层设置服务 - 主机协议。
- **CO_LSSslave.h/.c** - CANopen 层设置服务 - 从机协议。
- **309/** - 从其他网络访问 CANopen。
- **CO_gateway_ascii.h/.c** - Ascii 映射:NMT 主机、LSS 主机、SDO 客户端。
- **storage/**
- **CO_storage.h/.c** - CANopen 数据存储基础对象。
- **CO_storageEeprom.h/.c** - 用于将数据存储到块设备 的 CANopen 数据存储对象。
- **CO_eeprom.h** - 与 CO_storageEeprom 配合使用的 Eeprom 接口,函数是目标系统特定的。
- **extra/**
- **CO_trace.h/.c** - CANopen 跟踪对象,用于随时间记录变量。
- **example/** - 包含基本示例的目录,应能在任何系统上编译。
- **CO_driver_target.h** - CANopenNode 的示例硬件定义。
- **CO_driver_blank.c** - CANopenNode 的示例空白接口。
- **main_blank.c** - 主线和其他线程 - 示例模板。
- **CO_storageBlank.h/.c** - 数据存储到非易失性存储器的示例空白演示。
- **Makefile** - 示例的 Makefile。
- **DS301_profile.xpd** - DS301 的 CANopen 设备描述文件。它还包括 CANopenNode 特定的属性。此文件也位于对象字典编辑器的配置文件中。
- **DS301_profile.eds**, **DS301_profile.md** - 标准 CANopen EDS 文件和 markdown 文档文件,由 DS301_profile.xpd 自动生成。
- **OD.h/.c** - CANopen 对象字典源文件,由 DS301_profile.xpd 自动生成。
- **doc/** - 包含文档的目录。
- **CHANGELOG.md** - 更新日志文件。
- **deviceSupport.md** - 有关受支持设备的信息。
- **objectDictionary.md** - CANopen 对象字典接口说明。
- **CANopenNode.png** - 小图标。
- **html** - 包含文档的目录 - 必须由 Doxygen 生成。
- **CANopen.h/.c** - CANopen 对象的初始化和处理,适用于常见配置。
- **Doxyfile** - 文档生成器 *doxygen* 的配置文件。
- **LICENSE** - 许可证。
- **MISRA.md** - MISRA C:2012 一致性信息。
- **README.md** - 本文件。
## 对象字典编辑器
对象字典是 CANopen 最关键的部分之一。
要自定义对象字典,必须使用外部应用程序:[CANopenEditor](https://github.com/CANopenNode/CANopenEditor)。二进制文件也可在那里获取。在 Linux 中,它使用 mono 运行,Ubuntu 默认提供 mono。
在程序的偏好设置中,将导出器设置为 "CANopenNode_V4"。然后开始新项目或打开现有项目文件。
支持多种项目文件类型,EDS, XDD v1.0, XDD v1.1, 旧的自定义 XML 格式。生成的项目文件可以保存为 XDD v1.1 文件格式 (xmlns="http://www.canopen.org/xml/1.1")。项目文件也可以导出为其他格式,可用于生成文档和对象字典的 CANopenNode 源文件。
如果开始了新项目,则可以插入 `DS301_profile.xpd`。如果正在编辑现有(旧)项目,则可以删除现有的 `Communication Specific Parameters`,然后插入新的 `DS301_profile.xpd`。另一种方法是在 [objectDictionary.md](doc/objectDictionary.md) 中观察 CANopenNode 的对象字典要求,编辑现有的通信参数。
要克隆、添加或删除,请选择对象并使用右键单击。正确设置自定义对象字典需要一些 CANopen 知识。也可以从另一个项目插入单独的对象。
CANopenNode 在标准项目文件中包含一些自定义属性。有关更多信息,请参阅 [objectDictionary.md]( )。
## 设备支持
CANopenNode 可以在许多不同的设备上运行。每个设备(或微控制器)必须有自己到 CANopenNode 的接口。CANopenNode 可以在有或没有操作系统的情况下运行。
将所有设备接口放在单个项目中是不切实际的。其他微控制器的接口位于单独的项目中。有关已知设备接口的列表,请参阅 [deviceSupport.md](doc/deviceSupport.md)。
## 一些细节
### RTR
RTR(远程传输请求)是 CAN 总线的一项功能。CANopen 不建议使用 RTR。CANopenNode 中未实现 RTR PDO。
### 错误控制
当节点启动(处于 NMT 操作状态)时,允许发送或接收过程数据对象 (PDO)。如果设置了错误寄存器(对象 0x1001),则可能不允许进入 NMT 操作状态。
### 省电
所有 CANopen 对象计算操作系统的下一个定时器信息。计算基于在已知时间过期的各种定时器。可用于使微控制器进入睡眠并在计算的时间唤醒。
## 更新日志
参见 [CHANGELOG.md](doc/CHANGELOG.md)
## 许可证
根据 Apache 许可证 2.0 版(“许可证”)授权;
除非遵守许可证,否则您不得使用本文件。
您可以在以下位置获取许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则根据许可证分发的软件
是按“原样”分发的,
没有任何明示或暗示的担保或条件。
请参阅许可证以了解管理权限和
限制的特定语言。
标签:ANSI C, CANopen, CANopenNode, CAN总线, CiA301, EN 50325-4, Heartbeat, ICS, NMT, NTLM Relay, Object Dictionary, PDO, PKINIT, RTOS, SCADA, SDO, 协议栈, 哈希传递, 客户端加密, 客户端加密, 嵌入式开发, 嵌入式系统, 工业控制, 工控安全, 开源, 微控制器, 汽车电子, 物联网, 通信协议