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: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...
Lely CANopen 事件调度机制详解:从 `ev_task`、Executor、`std_exec` 到 `ev_loop`、Future 与 Poll
Lely CANopen 事件调度机制详解:从 ev_task、Executor、std_exec 到 ev_loop、Future 与 Poll @[toc] 0. 阅读前先记住六个结论 ev_task 只是“可执行工作”的载体,不负责排队、线程切换或等待。 ev_exec_t 是抽象 Executor 接口,本质是 C 语言虚函数表。 ev_std_exec 不是另一个事件循环,而是一个适配层:只要求后端实现 post/abort/on_task_init/on_task_fini,它补齐 dispatch/defer/run。 ev_loop 才拥有真正的全局任务队列、等待线程、Poll 线程和 outstanding work 状态。 ev_exec_run() 的关键价值不是简单调用回调,而是建立“当前线程正在这个 Executor 内执行任务”的 TLS 上下文。 Future、I/O、定时器最终都不会直接“执行用户逻辑”;它们把 ev_task 投递给 Executor,由 ev_loop 取出并运行。 可以先把整个系统压缩成下面这条链: 1234...
Lely CANopen Future Promise 机制原理与源码详解
Lely CANopen Future/Promise 机制原理与源码详解 @[toc] 1. 先给结论:Lely Future 到底是什么Lely 的 Future/Promise 不是一个“阻塞等待结果”的线程同步工具,而是一个和 executor、task、event loop 深度结合的一次性异步完成通知与结果共享机制。 可以先记住以下五句话: ev_promise_t 是异步结果的生产端,负责把共享状态从未完成推进到完成; ev_future_t 是观察端,负责检查结果是否完成、读取结果、登记完成后的任务; Future 本身不会执行 I/O,也不会主动运行回调;真正执行回调的是 task 所属的 executor; ev_future_submit() 不阻塞,而是把 task 暂存在 Future 内部队列,Future ready 后再提交给 executor; Promise 和 Future 不是两个独立对象,它们共享同一块内存、同一个引用计数和同一个生命周期。 官方 C 接口头文件直接强调:与 C++11 的 Futur...
Lely CANopen `ev_loop` 详解
Lely CANopen ev_loop 详解 @[toc] 1. 先区分三个容易混淆的“停止”状态loop.c 中至少存在三类停止或完成状态: 状态 所属范围 作用 loop->stopped 每个 ev_loop_t 整个事件循环是否处于 stopped 状态;ev_loop_stop() 会影响所有正在运行该 loop 的线程。 ev_loop_thrd.stopped 每个线程 中断该线程当前最内层的一次 run/wait 调用;返回后通常会清零,以便下次重新运行。 ctx->ready 每个等待 context 表示正在等待的 future 已经 ready,应结束本次等待。 不能把它们当作同一个状态: 12345678loop->stopped= loop 级停止thread-local stopped= 线程级、单次运行中断ctx->ready= 本次等待目标已经完成 ev_loop_ctx_wait_one() 的主循环实际同时检查这些条件: 12345loop 没有全局停止并且当前线程没有被 kill并且fu...








