u-boot 学习笔记
u-boot 学习笔记 u-boot分类 1.1. api 1.1.1. api.md 1.2. arch 1.2.1. arm 1.2.1.1. arm.md 1.2.1.2. assembly.md 1.2.2. arch.md 1.3. boot 1.3.1. bootm.md 1.3.2. bootretry.md 1.3.3. bootz.md 1.3.4. image.md 1.4. cmd 1.4.1. cmd.md 1.5. common 1.5.1. autoboot.md 1.5.2. board.md 1.5.3. cli.md 1.5.4. command.md 1.5.5. console.md 1.5.6. dmalloc.md 1.5.7. event.md 1.5.8. export.md 1.5.9. log.md 1.5.10. main.md 1.6. dm 1.6.1. adc.md 1.6.2. button.md 1.6.3. clock.md 1.6.4. core.md 1.6.5. dts.md 1....
RT-Thread 学习笔记
RT-Thread 学习笔记 其他资料 1.1. fatfs 1.1.1. fatfs.md 2. ARM指针寄存器.md 3. CAN驱动.md 4. completion.md 5. condvar.md 6. dataqueue.md 7. DFS.md 8. fal.md 9. fatfs.md 10. FINSH模块.md 11. I2C驱动.md 12. IDLE线程.md 13. IPC.md 14. littlefs.md 15. map文件分析.md 16. pipe.md 17. PM电源管理.md 18. readme.md 19. ringblock.md 20. ringbuffer.md 21. romfs.md 22. RTC.md 23. RT-LINK.md 24. RTT系统初始化.md 25. SDMMC.md 26. SIGNAL.md 27. SPI驱动.md 28. tmpfs.md 29. ULOG.md 30. USB.md 31. waitqueue.md 32. 串口驱动.md 33. 调度.md 34. 工作队列...
Lely CANopen:RPDO&TPDO 运行期收发、SYNC、事件与定时器机制原理和运行流程
Lely CANopen:RPDO/TPDO 运行期收发、SYNC、事件与定时器机制原理和运行流程 @[toc] 源码基线:lely-industries/lely-core,提交 620d1858eb8520dbc3dc5e1a7314565becd54199,查阅时间为 2026-07-30。 本文核心分析以下文件: 123456include/lely/co/rpdo.hinclude/lely/co/rpdo.hppsrc/co/rpdo.cinclude/lely/co/tpdo.hinclude/lely/co/tpdo.hppsrc/co/tpdo.c 前置文章已经说明 co_pdo_dn()、co_pdo_up()、PDO 映射校验、位级编解码以及对象字典 indication 桥接。本文不重复展开这些基础算法,而是集中分析 RPDO/TPDO 服务对象如何注册 CAN 接收器、维护运行期参数、处理 SYNC、事件定时器、接收超时、同步窗口、抑制时间、RTR 和用户回调。 事实边界:函数、字段、条件分支和调用链来自上述源码;并发风险、生...
README
canopen 学习笔记 [1. CANopen TIM&SYNC 运行流程.md](CANopen TIM&SYNC 运行流程.md) [2. CANopen CiA 协议全景:核心内容、重点与组合关系.md](CANopen CiA 协议全景:核心内容、重点与组合关系.md) [3. CANopen Emergency: 搞懂 EM 运行流程.md](CANopen Emergency: 搞懂 EM 运行流程.md) [4. CANopen NMT:搞懂 NMT 运行流程.md](CANopen NMT:搞懂 NMT 运行流程.md) [5. CANopen PDO 运行流程.md](CANopen PDO 运行流程.md) [6. CANopen 搞懂 SDO client&server 运行流程.md](CANopen 搞懂 SDO client&server 运行流程.md) [7. CANopen 网络拓扑限制.md](CANopen 网络拓扑限制.md) [8. CANopene Heartbeat运行流程.md](CANopen...
Lely CANopen `coapp Device` 本地 SDO PDO 读写、远程对象映射与运行机制
Lely CANopen coapp::Device:本地 SDO/PDO 读写、远程对象映射与运行机制 @[toc] 1. 先给出最关键的结论理解 Device 时,必须先把“本地读写”“远程读写”“SDO”“PDO”分开: Device 本质上是 co_dev_t 的 C++ 所有权与访问封装。 Device::Read()、Device::Write() 是对本地对象字典执行一次“本地 SDO 请求”,不会发送 CAN 帧。 Device::Get()、Device::Set() 是直接访问本地对象字典值,绕过 SDO 访问权限、范围检查和下载/上传回调。 Device::RpdoRead() 并不会通过 CAN 去读取远程节点,而是把“远程 TPDO 对象地址”转换为本地 RPDO 映射对象,再读取本地缓存值。 Device::TpdoWrite() 也不会执行远程 SDO 下载,而是把“远程 RPDO 对象地址”转换为本地 TPDO 映射对象,再写入本地待发送值。 真正通过 CAN 总线访问远程对象字典的是 co_csdo_t / lel...
Lely CANopen:co_dev 设备对象字典与 DCF 和 PDO 事件机制
Lely CANopen:co_dev 设备对象字典与 EDS/DCF 解析、concise DCF 和 PDO 事件机制 @[toc] 一句话结论Lely 的 co_dev_t 不是协议状态机,也不是简单的 EDS 文件句柄,而是 CANopen 设备描述在运行期的根对象: 它保存 Node-ID、网络号、设备名称、身份信息、支持的位速率、LSS 和 dummy PDO 类型等设备级元数据; 它用一棵以 16 位索引为 key 的红黑树管理全部 co_obj_t,每个 co_obj_t 再管理自己的 co_sub_t; dcf.c 先把 EDS/DCF 的 INI 文本解析为通用配置树,再逐层创建 co_dev_t → co_obj_t → co_sub_t; $NODEID + n 不只是文本替换,解析器会记录相应 flag,co_dev_set_id() 在 Node-ID 改变时遍历整棵对象字典并按差值修正相关值; 文本 EDS/DCF 与 concise DCF 是两种完全不同的格式:前者描述设备结构和元数据,后者是用于参数配置的一组...
Lely CANopen:can_net、io_can_net设计原理
Lely CANopen:can_net、io_can_net 与 CAN channel 的分层关系,以及 TX/RX Ring 的设计原理@[toc] 一句话结论Lely 中容易混淆的几个对象,实际处于不同层次: can_net_t 是纯内存中的 CAN 逻辑调度核心,负责协议定时器、CAN-ID 接收分发和发送回调;它不知道 SocketCAN、文件描述符、poll、executor 或真实 CAN 控制器。 io_can_chan_t 是抽象 CAN 通道接口;src/io2/linux/can_chan.c 是它在 Linux SocketCAN 上的具体后端,负责文件描述符、收发操作、I/O 就绪事件和写确认。 io_can_net_t 是桥接层,把 can_net_t、io_timer_t、io_tqueue_t 和 io_can_chan_t 连接起来,使同步的协议核心能够运行在异步 I/O 框架上。 lely::io::CanNet 只是 io_can_net_t* 的 C++ RAII 包装,不是另一套独立实现;核心机制仍然...
Lely CANopen:io_tqueue 与 pheap 的实现原理、运行流程
Lely CANopen:io_tqueue 与 pheap 的实现原理、运行流程及其与 Timer、can_net 的关系 @[toc] 一句话结论io_tqueue 是一个“多路逻辑定时器复用器”: 上层可以同时提交很多个不同绝对截止时间的 io_tqueue_wait; 中间用 pheap 维护“当前最早到期”的等待; 下层始终只占用 一个 io_timer_t; 底层 Timer 到期时,再回到 io_tqueue 批量完成所有 value <= now 的等待。 它与 can_net 串起来之后,又形成“两级最早截止时间压缩”: 123456789很多 can_timer_t ↓can_net.timer_heap ↓ 选出协议层最早一个io_tqueue.queue ↓ 再与其他 I/O 等待一起排序一个 io_timer_t ↓Linux timerfd / poll / executor 1. 为什么需要 io_tqueue如果没有 io_tqueue,最直观的设计是: 1234每一个逻辑等待 → 一个 io_tim...
Lely CANopen `spscring` 单生产者单消费者环形队列完整机制学习笔记
Lely CANopen spscring 单生产者单消费者环形队列完整机制学习笔记 @[toc] 1. 先明确边界:spscring 不是数据缓冲区SPSC 是 Single-Producer Single-Consumer,即单生产者、单消费者。 Lely 的 spscring 与常见“结构体内部直接包含数组”的环形队列不同。它只管理: 哪些索引可以由生产者写入; 哪些索引可以由消费者读取; 生产者何时把写入结果发布给消费者; 消费者何时把已读槽位归还给生产者; 队列由空变为可读或由满变为可写时,是否需要触发回调。 实际数据存储由调用者单独提供: 12struct spscring ring;struct io_can_frame *rxbuf; 两者的关系是: 12345spscring= 索引所有权与可见性控制器rxbuf= 真正保存 CAN 帧的内存数组 因此,调用 spscring_p_alloc() 只会得到一个可写索引,不会返回数据指针,也不会复制任何数据。 1234567flowchart LR Prod[Producer] -->|p...
Lely CANopen CAN 完整机制学习笔记
Lely CANopen IO2 CAN 与 SocketCAN 完整机制学习笔记 @[toc] 1. CANopen、liblely-co、io2 与 SocketCAN 的边界Lely CANopen 协议栈本身是被动状态机。它不直接拥有 Linux socket,也不自行创建线程。Linux 上的实际 I/O 由 liblely-io2 提供,任务调度由 liblely-ev 提供。 12345678910flowchart TB APP[业务代码 / CANopen Master] --> CO[liblely-co / coapp] CO --> NET[CAN network / protocol state machine] NET --> IO2[liblely-io2 abstract CAN API] IO2 --> CHAN[Linux CanChannel] CHAN --> SOCK[SocketCAN raw socket] SOCK --> KERNEL[Lin...








