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 如何用 MPU 做线程栈保护
RT-Thread 如何用 MPU 做线程栈保护 摘要:结合 RT-Thread 当前 Cortex-M4 实现,拆解 MPU 内存保护、线程双 Guard 区、上下文切换重装载以及 MemManage Fault 的完整运行链路。 在 Cortex-M 系列 MCU 上,线程栈溢出一直是最难排查的一类故障之一。它往往不是在“栈刚好用完”的那一刻表现为明确错误,而是先覆盖相邻内存,再以随机变量异常、链表损坏、HardFault、跑飞甚至数分钟后的非确定性故障出现。 RT-Thread 传统的 RT_USING_OVERFLOW_CHECK 可以对线程栈做软件检查,但软件检查本质上依赖检查时机:如果栈已经越界,在下一次检查发生之前,相邻内存仍可能先被破坏。 另一条路线是利用 Cortex-M 自带的 MPU(Memory Protection Unit)。RT-Thread 的 RT_USING_MEM_PROTECTION 提供了 MPU 抽象层,而 RT_USING_HW_STACK_GUARD 则进一步利用 MPU,在每个线程栈的上下边界放置不可访问区域。一旦 CPU...
GitHub push 失败:如何扫描并清理 Git 历史中的大文件
GitHub push 失败:如何扫描并清理 Git 历史中的大文件@[toc] 摘要:从 GitHub 100 MiB 大文件拒绝问题出发,说明为何删除文件后仍无法推送,并给出 PowerShell 扫描、历史清理、Git LFS 与防复发方案。 在把一个已有 Git 项目首次推送到 GitHub 时,可能会遇到如下错误: 1234remote: error: File vendor/example/.git.zip is 151.91 MB;remote: error: this exceeds GitHub's file size limit of 100.00 MBremote: error: GH001: Large files detected.! [remote rejected] master -> master (pre-receive hook declined) 这里最容易产生的误解是:既然问题文件已经不需要了,那么再新增一个 commit 把它删除,然后重新 git push 不就可以了吗? 答案是否定的。 GitHub 检查的不...
Lely CANopen 启动与从机联机后的运行机制
Lely CANopen 启动与从机联机后的运行机制:Executor、Loop、Timer、CAN 与 Future/Promise 摘要:梳理 Lely CANopen 主站启动、从机 boot 和稳定运行阶段实际存在的任务、事件循环、逻辑定时器、CAN 报文及 Future/Promise 完成链路。 @[toc] 结论以 Linux、SocketCAN、liblely-io2、liblely-ev、liblely-coapp 和 canopen::AsyncMaster 的典型主站为基线,可以先得到六个结论: 通常只有一个主 ev::Loop,不是每个从机一个 Loop。 多个从机的 NMT boot、SDO、Heartbeat 和 PDO 状态机可由同一个事件循环驱动。 通常只有一个 Loop executor。 AsyncMaster 将用户侧 OnBoot()、OnConfig()、OnState()、OnHeartbeat()、OnEmcy()、OnRpdoWrite() 等回调包装为 ev_task,再投递到相应 Driver 的 e...
Lely CANopen coapp Driver
Lely CANopen coapp Driver:BasicMaster 与 BasicDriver 的职责边界、注册表和事件流程 摘要:从 BasicMaster 的远程节点操作能力出发,解析 Driver 注册表、非拥有关系、事件分发,以及各类 Driver 的协作机制。 @[toc]Lely CANopen 的 coapp 层中,Driver 很容易被误解成 CAN 硬件驱动、协议状态机,或者由 Master 自动创建的“远程节点对象”。源码表达的关系并不是这样:BasicMaster 本身可以直接操作远程节点;BasicDriver 是绑定固定 Node-ID 和 Executor 的节点级应用适配器,同时也是 Master 分发节点事件的接收对象。 1. 先回答两个核心问题1.1 BasicMaster 能否直接操作远程节点可以。BasicMaster 的公开接口已经包含 Node-ID 参数,可以直接对指定远程节点执行操作,例如: Command(cs, id):发送 NMT 命令; Boot(id)、IsReady(id):启动并查询 NMT boot-s...
Lely CANopen Master
Lely CANopen coapp::Master:NMT 总控、SDO 仲裁与 Driver 事件分发机制 摘要:从 master.hpp 与 master.cpp 追踪 BasicMaster/AsyncMaster 如何组织 NMT 启动、SDO 所有权、配置握手及 Driver 事件分发。 @[toc]lely::canopen::BasicMaster 和 lely::canopen::AsyncMaster 是 Lely CANopen C++ 应用层中负责主站编排的核心对象。它们并不是简单地把 NMT、SDO、PDO API 包装成 C++ 成员函数,而是在 Node 的本地 CANopen 节点能力之上,进一步维护远端节点 Driver、节点启动状态、配置阶段状态以及 Client-SDO 使用权。 理解这两个类的关键,不是逐个记住 SubmitRead()、Command()、OnBoot() 等接口,而是建立下面这条主线: 12345本地主站 Node 启动 -> NMT master 发起或接管远端节点 boot slave ...
CANopen MPDO:动态对象寻址
CANopen MPDO:动态对象寻址 摘要:解析 MPDO 的 DAM/SAM 寻址、对象列表与报文流程,并结合 Lely、CANopenNode 和 CanFestival 源码说明实现差异及替代方案。 @[toc] 1. MPDO 解决了普通 PDO 的什么问题普通 PDO 的优势是协议开销小、实时性高,但它的对象映射通常在通信前确定:一个 PDO COB-ID 对应一组固定的对象字典条目。收到数据帧后,消费者按照 0x1600~0x17FF 中的映射,把第 1 段、第 2 段数据写到预先配置的本地对象。 当设备存在大量低频、稀疏变化的 8/16/32 位对象时,固定映射会遇到三个问题: 为每组对象分配 PDO,会增加通信参数、映射对象和 COB-ID 管理量。 反复动态重映射 PDO,需要先禁用 PDO、清空映射、修改条目、恢复映射,再重新启用,不能把它当成逐帧选择机制。 改用 SDO 虽然可以逐次携带 Index/Sub-index,但每次访问都有请求、响应和协议状态,语义更可靠,实时性和总线效率却不同于 PDO。 M...
Lely CANopen Node
Lely CANopen coapp::Node:CAN 网络、NMT 服务与 C++ 事件回调的装配机制 摘要:从源码追踪 coapp::Node 如何组合 CAN I/O、对象字典、NMT 服务、定时队列与 C++ 回调,并解释构造、复位和事件分发的完整流程。 @[toc] 1. Node 不是协议重写,而是装配中心阅读 lely-core/include/lely/coapp/node.hpp 和 lely-core/src/coapp/node.cpp 时,最重要的判断不是“Node 实现了多少 CANopen 服务”,而是: lely::canopen::Node 把 CAN I/O、时间源、本地对象字典、NMT 总控和 C++ 应用回调装配成一个可运行节点;具体 PDO、SYNC、TIME、EMCY、LSS 等协议状态机仍由 C 层服务对象实现。 这一判断可以直接从继承关系和内部对象得到: 12345class Node : public io::CanNet, public Device { // ... stru...
Lely CANopen `co_nmt_t`:主从 NMT 总控机制、状态机与运行流程
Lely CANopen co_nmt_t:主从 NMT 总控机制、状态机与运行流程 @[toc] co_nmt_t 不能只理解成“接收 CAN-ID 0x000 后切换 NMT 状态”的对象。Lely 官方库概览直接把它定位为 CANopen 设备的核心服务管理器:它维护本节点 NMT 状态,并按状态创建、启动、停止或销毁 SDO、PDO、SYNC、TIME、EMCY、LSS 等服务。新建对象初始停留在 Initialisation,不立即通信,应用可以先安装回调,再通过 Reset Node 启动完整 boot-up 链路。[1] 结合 src/co/nmt.c、include/lely/co/nmt.h 与 include/lely/co/nmt.hpp,可以把它概括为: 123456789co_nmt_t= 本节点 NMT 有限状态机+ 本地 CANopen 服务生命周期管理+ NMT 命令收发与发送抑制+ Heartbeat / Node Guarding / Life Guarding 总控+ 主站从节点状态表与启动策略+ 对象字典动态配置入口+ Boot Sla...
Lely CANopen LSS:主从状态机、Fastscan 与配置流程
Lely CANopen LSS:主从状态机、Fastscan 与配置流程 @[toc] LSS(Layer Setting Services)用于解决一个基础但特殊的问题:当设备还没有有效 Node-ID,或者整个网络需要切换 CAN 位率时,主站不能依赖普通 SDO 通道完成配置,因为 SDO 本身通常已经依赖有效 Node-ID。LSS 因此使用固定的 CAN-ID,并用对象字典 0x1018 的四个 32 位身份字段识别设备。 在 Lely CANopen 中,co_lss_t 同时承载 LSS master 和 LSS slave 两种角色。它不是一组“发送命令后阻塞等待结果”的同步函数,而是一个依附于 co_nmt_t、can_net_t 和 co_dev_t 的事件驱动有限状态机: 1234567891011应用提交 LSS 请求 ↓co_lss_*_req() 构造首帧或进入内部状态 ↓can_net_send() 发送 0x7E5 ↓can_recv_t 等待 0x7E4,can_timer_t 负责超时与帧间隔 ↓当前状态的 on_...








