CiA 303_3 CANopenNode 如何计算 RUN ERROR 指示灯
按 LED 源码学习 CiA 303-3:CANopenNode 如何计算 RUN / ERROR 指示灯@[toc] 结论303/CO_LEDs.c/h 的核心不是“驱动 LED”,而是实现 CiA 303-3 CANopen indicators:把 CANopen 设备的通信相关状态,转换成标准的 绿色 RUN LED 与 红色 ERROR LED 指示模式。 本模块的输入来自 CANopen 状态与错误上下文,例如 NMT 状态、LSS 配置状态、CAN bus-off、CAN warning、Heartbeat consumer 错误、SYNC 超时、RPDO event timer 超时、其他错误、固件下载状态等;输出是 LEDred / LEDgreen bitfield 中的 CO_LED_CANopen 位。 本文只讨论 CANopenNode 经典 CANopen 的: 303/CO_LEDs.h 303/CO_LEDs.c NMT、LSS、Heartbeat consumer、SYNC、PDO、CAN bus-off 只作为 LE...
CANopenNode LSS运行流程
从源码看 CANopenNode LSS:搞懂主从机运行流程 @[toc] 先给结论LSS(Layer Setting Services)不是用来传过程数据的,也不是普通 SDO 配置。它解决的是设备还没有有效 Node-ID,或者需要统一切换 CAN 位率时,主站如何在 CAN 总线上找到并配置从站的问题。 在 CANopenNode 的 305 目录中,LSS 的运行核心可以压缩成三句话: 主站只通过 0x7E5 发命令,从站只通过 0x7E4 回响应。 这是 LSS 固定使用的两条 CAN 帧通道。 从站通过 0x1018 身份对象形成 128 bit LSS Address。 主站可以已知地址精准选择,也可以对未配置节点做 Fastscan。 Node-ID 和 bit rate 先进入 pending 值。 Node-ID 通常要经过保存和通信复位后才真正成为 CANopen 栈运行用的 ID;bit rate 的激活更危险,必须保证全网节点同步切换。 1. LSS 解决的工程问题在普通 CANopen 网络中,很多通信对象都依赖 Node-ID。例如心跳常见为...
CANopenNode `CO_new()` 与 `CO_config
CANopenNode CO_new() 与 CO_config.h 宏机制详解@[toc] CO_new() 不是一个单纯的 malloc() 包装函数。它是 CANopenNode 把“协议栈功能选择”落到“对象实例、内存占用、CAN 接收过滤槽位、CAN 发送缓冲槽位”的集中入口。 换句话说,CO_config.h 里的宏回答的是:这个协议能力是否参与编译、是否保留对应代码路径、是否启用某些回调或动态配置特性。CO_new() 回答的是:在当前对象字典或 CO_config_t 配置下,实际要创建几个对象、每个对象占多少内存、每类 CAN 报文在 CANrx[] 和 CANtx[] 中从哪个下标开始。 CO_new() 的核心任务不是协议通信,而是对象装配从代码结构看,CO_new() 可以分为四层:参数检查、对象分配、CAN 报文槽位统计、最终对象返回。 第一层是配置合法性检查。只有在 CO_MULTIPLE_OD 被定义时,函数才会把 config 视为有效配置来源,并检查 CNT_NMT、CNT_HB_CONS、CNT_EM、CNT_SDO_SRV、CNT_SD...
CANopen 网络拓扑限制
从 Node-ID 到线长:读懂 CAN/CANopen 网络拓扑限制 @[toc] 结论先行“CANopen 逻辑上限制到 128,物理上一段常见只能挂 64 个节点;1 Mbit/s 可到 25 m,50 kbit/s 可到 1000 m”这段话把两类约束放在了一起:一类是 CANopen 协议层的地址空间,另一类是 CAN 物理层的线缆、终端、收发器负载和传播延迟。两者都影响网络规模,但判断方式完全不同。 CANopen 的 Node-ID 是逻辑地址问题,7 bit 编码提供 0127 的编号空间;普通节点通常使用 1127,0 用于广播或特殊用途。 CAN 的线性拓扑是物理层问题。一个 CAN 总线段应尽量保持主干线连续,两端各 120 Ω 终端,节点通过短支线接入。 线长受位速率限制。速率越高,单个 bit 的时间越短,信号传播、收发器延迟和采样裕量越紧张,所以允许总线越短。 节点数量受收发器和线缆负载限制。协议允许的地址数量不等于一段总线的可靠驱动能力。 中继器可以在低速下扩展网络规模和构造分段/树形结构,但中继器本身也...
Lely CANopen 交叉构建说明
Lely CANopen 交叉构建说明:为什么执行 make install DESTDIR="${PWD}/stage",以及 lib/pkgconfig 的作用@[toc] 结论在 Lely CANopen / lely-core 的交叉编译流程中: 12make -j"$(nproc)"make install DESTDIR="${PWD}/stage" 这两条命令不是重复动作。它们分别解决两个问题: make:把源码编译、链接成目标平台可用的库和工具。 make install DESTDIR="${PWD}/stage":把已构建产物按最终安装目录布局复制到 staging 目录,便于检查、打包、部署和给后续应用交叉编译使用。 本次构建还安装了 lib/pkgconfig/*.pc 文件。它们不是库本体,而是给 pkg-config 查询的构建元数据,用来自动输出依赖 Lely 库时需要的 -I、-L、-l 等编译和链接参数。 先看完整流程123...
Lely CANopen configure 配置项与日志解读
Lely CANopen configure 配置项与日志解读 @[toc] 1. configure 在构建链路中的位置configure 属于 GNU Build System 的配置阶段。它不会直接把 Lely 源码编译成库,而是读取命令行参数、探测工具链和目标系统能力,然后生成 Makefile、config.h、.pc 文件和 libtool 相关脚本。后续 make 才进入编译阶段。 一个典型的交叉编译配置命令可以写成: 1234567../configure \ --host=aarch64-poky-linux \ --prefix=<INSTALL_PREFIX> \ --disable-python \ --disable-cython \ --disable-tests \ --disable-unit-tests 这条命令包含两类信息:一类是“目标平台和安装位置”,另一类是“功能裁剪策略”。前者影响工具链选择和安装目录,后者影响 Python、测试、CANopen 模块、C++ 接口等是否进入构建目标。 2. config...
从 `autoreconf -i` 看懂 Autoconf:以 Lely CANopen 交叉编译为例
从 autoreconf -i 看懂 Autoconf:以 Lely CANopen 交叉编译为例 本文面向第一次接触 Autotools / Autoconf 的读者。目标不是背命令,而是看懂:autoreconf -i 为什么要执行、从哪个文件开始、会生成什么文件、这些文件又怎样参与 Lely CANopen 的交叉编译。 @[toc] 先给结论autoreconf -i 的作用是:根据源码中的 Autotools 描述文件,生成后续构建需要的 configure 脚本、Makefile.in 模板、config.h.in 模板和一批辅助脚本。 它不是编译命令,也不会生成 ARM/aarch64 目标程序。真正编译 Lely 的动作发生在后面的 make 阶段。 完整链路如下: 12345678910111213141516171819202122flowchart TD A[configure.ac<br/>Autoconf 入口] --> B[autoreconf -i] C[Makefile.am<br/&...
Lely CANopen 入门:从协议背景到 i
Lely CANopen 入门:从协议背景到 i.MX8P 交叉编译安装@[toc] 先给结论Lely CANopen 适合做 嵌入式 Linux 侧 CANopen master,尤其适合已经使用 SocketCAN、C++、事件循环或 Yocto SDK 的项目。它不是只能跑在 PC 上的调试工具,而是一套包含 C 核心库、C++ 应用层封装、命令行工具和 DCF/EDS 辅助工具的 CANopen 实现。 如果你的目标是 i.MX8P 这类 ARM64 Linux 板卡,推荐流程是: 在 x86 Ubuntu 主机安装构建依赖和 i.MX8P Yocto SDK。 加载 Yocto SDK 环境脚本,得到 aarch64-poky-linux-* 工具链和目标 sysroot。 从源码构建 Lely CANopen,并通过 --host=aarch64-poky-linux 交叉编译。 用 make install DESTDIR=... 收集头文件、库、工具和示例配置。 打包部署到 i.MX8P。 在 i.MX8P 上启动 vcan0,运行 coctl...
RPC 是什么:原理、边界与工业/嵌入式通信中的适用场景
@[toc] RPC 是什么:原理、边界与工业/嵌入式通信中的适用场景 摘要: RPC(Remote ProcedureCall,远程过程调用)把跨节点通信抽象成“调用远端函数”,解决的是接口抽象、参数序列化、请求/响应匹配、跨语言代码生成和工具化问题。它不解决物理层、链路层、总线仲裁、实时调度和广播多回应聚合问题。因此,RPC更适合点对点、低频、结构化的控制/配置/调试接口;不适合高频实时PDO、广播控制、硬实时闭环和多主多从共享总线仲裁。工业和嵌入式系统中,更稳妥的做法是把通信拆成实时数据面、诊断配置面和工具调试面:实时数据面使用原生CAN/PDO;诊断配置面使用 UDS/ISO-TP、CANopen SDO 或Modbus;工具调试面再考虑 eRPC/gRPC 这类 RPC。 一、RPC 是什么:诞生背景与核心抽象RPC的直译是“远程过程调用”。它试图解决一个长期存在的软件工程问题:当一个程序需要使用另一台机器、另一个进程、另一个CPU 核或另一个 MCU 上的能力时,能否像调用本地函数一样调用远端...
autogen_parameter_manager:面向固件产品参数的生成式管理软件包
autogen_parameter_manager:面向固件产品参数的生成式管理软件包 仓库地址: https://github.com/wdfk-prog/parameters@[toc] 推荐判断在嵌入式产品中,参数管理通常会从几个配置变量开始。早期代码里直接定义全局变量,或者在某个模块中保存默认值,短期内成本很低。项目继续推进后,参数会进入更多流程:生产标定需要写入校准值,现场调试需要临时修改阈值,上位机需要读取和展示配置,售后脚本需要批量检查状态,固件升级还要考虑旧版本已经保存的数据是否仍然可用。 到这个阶段,真正需要维护的已经不是单个变量,而是一组产品参数的长期接口。每个参数都可能同时包含外部 ID、类型、默认值、最小值、最大值、单位、说明、读写属性、持久化标记和版本兼容关系。只要这些信息分散在协议代码、shell 命令、业务模块和存储代码中,后续迭代就容易出现规则不一致。 autogen_parameter_manager 适合用于这类固件项目。它把参数表作为事实源,生成固件侧需要的参数定义、ID 映射、静态布局和摘要信息;运行时再基于这些生成数据提供类型化访...








