防范业务逻辑死锁的系统健康监督与看门狗设计
嵌入式面试真题第 14 题:防范业务逻辑死锁的系统健康监督与看门狗设计 问题在多任务嵌入式系统、RTOS 固件、边缘网关、工业控制器、车载控制单元、消费电子设备或其他长期无人值守的软件系统中,通常会配置硬件看门狗,以便系统发生严重异常时自动复位。 传统实现往往由一个独立 Watchdog Task、Idle Hook、主循环或高优先级定时任务周期性喂狗。只要这个喂狗节点还能获得 CPU 时间,硬件看门狗就不会超时。然而,系统可能已经出现以下“进程还活着、业务却不再工作”的假活状态: 两个或多个任务形成循环等待,业务路径死锁。 高优先级任务持续运行,低优先级关键任务长期饥饿。 任务不断重试或相互唤醒,但业务状态不再前进,形成活锁。 消息队列、缓冲区或对象池耗尽,生产者和消费者互相等待。 状态机卡在某个中间状态,周期函数仍在调用,但事务永远无法完成。 外设、总线、文件系统、网络栈或协处理器请求悬挂,任务仍在等待或轮询。 某个 CPU 核、调度 tick、关键中断或时间基准失效,而其他核仍能继续喂狗。 看门狗任务本身优先级过高、依赖过少,反而绕过了真正的业务健康状态。 面对这种...
单硬件 Timer 下的高精度多路软件定时器架构设计
嵌入式面试真题第 13 题:单硬件 Timer 下的高精度多路软件定时器架构设计 问题在资源受限的实时系统、嵌入式设备、工业控制器、音视频终端、通信协议栈或边缘计算节点中,硬件可能只允许软件独占一个可编程高精度 Timer,或者虽然芯片内部存在多个 Timer,但其他通道已经被 PWM、输入捕获、编码器、操作系统 Tick、协议时基等功能占用。 与此同时,系统内部往往存在数量不定、周期跨度很大、实时等级不同的软件时间事件,例如:协议超时、传感器采样、控制环触发、音频帧节拍、设备状态机延时、重传定时、去抖、看门狗喂狗窗口、异步操作截止时间、短脉冲控制、统计采样和低功耗唤醒等。部分事件要求微秒级时间基准,部分事件只要求毫秒级;部分事件只需记录“已到期”,部分事件需要尽快执行;还有少数事件可能具有硬实时属性。 如果每个模块各自占用硬件 Timer,硬件资源很快就会耗尽;如果全部依赖 RTOS Tick,分辨率、抖动和长周期漂移又可能无法满足要求;如果直接在 Timer ISR 中遍历全部定时器并执行回调,则一次集中到期、复杂回调或异常路径就可能拉长中断时间,阻塞更高优先级的数据采集...
资源受限长期运行系统的确定性内存管理与内存池架构设计
嵌入式面试真题第 12 题:资源受限长期运行系统的确定性内存管理与内存池架构设计 问题在资源受限或对实时性、可靠性有严格要求的系统中,运行期通常同时存在多种内存需求:任务和协议对象的创建销毁、通信报文收发、音视频或传感器数据流、日志与诊断记录、文件系统缓存、DMA 缓冲、临时算法工作区,以及不同模块之间的零拷贝传递。 如果所有需求都直接依赖通用 malloc/free,系统可能在短期测试中表现正常,但在长时间运行、突发流量、异常重连、并发超时、模块反复启停或错误恢复后,出现外部碎片、内存泄漏、分配延迟抖动、优先级反转、关键路径资源被非关键模块耗尽等问题。即使“剩余总内存”看起来仍然充足,也可能因为缺少满足尺寸和对齐要求的连续块而分配失败。 请设计一套适用于裸机、RTOS、嵌入式 Linux 用户态组件以及其他受限运行环境的通用内存管理架构。要求说明: 如何从系统需求和对象生命周期出发选择静态分配、固定块池、分级尺寸池、专用对象池、环形缓冲、Arena/Region、Buddy、TLSF 或普通堆。 如何从架构上避免外部碎片,而不是只在崩溃后扩大堆空间。 如何处理并...
用 POSIX Signal 唤醒 epoll 事件循环:原理、逐行解析与实践
用 POSIX Signal 唤醒 epoll 事件循环:原理、逐行解析与实践 本文面向已经掌握 C 语言、线程和文件描述符基础,但对 POSIX Signal 与事件轮询协作机制还不熟悉的开发者。 核心结论:这里的 signal 不是业务数据,也不是 I/O 事件本身,而是一个“唤醒通知”。它用于中断阻塞中的 epoll_pwait(),让轮询线程及时重新检查停止标志、任务队列或监听集合。 @[toc] 1. 先建立整体认识一个事件轮询线程通常会长时间阻塞: 1n = epoll_wait(epfd, events, maxevents, -1); 最后一个参数为 -1 时,线程会一直等待,直到某个文件描述符就绪。问题是,另一个线程可能需要它立即醒来,例如: 请求事件循环停止; 投递了新的异步任务; 修改了共享状态; 要求重新计算下一次超时时间; 调整了监听集合,但当前没有就绪事件。 因此,事件循环需要一条独立于普通 I/O 的“敲门通道”。这段实现选择 POSIX Signal 作为敲门机制。 123456789控制线程 ...
linux glibc 中 errno 的原理、线程隔离与实现路径
Linux/glibc 中 errno 的原理、线程隔离与实现路径@[toc] 本文面向已经接触 C、Linux 系统调用、pthread 或 RTOS,但对错误码如何产生、传递和隔离仍有疑问的开发者。文章从用户态接口、Linux 内核、C 运行库和 RTOS 四个层次,逐步说明 errno 的宏展开、线程局部存储、系统调用错误转换,以及不同操作系统的错误返回模型。 结论先行1errsv = errno; 这行代码不会在执行时向 Linux 内核查询最新错误码。 在 glibc 环境中,errno 通常是一个宏: 1#define errno (*__errno_location()) 因此,代码近似展开为: 1errsv = *__errno_location(); __errno_location() 返回当前线程专属的 errno 存储地址,解引用后得到该线程当前保存的错误码。 这个错误码通常已经由下列某一方写入: glibc 的系统调用包装层; 某个纯用户态库函数; 应用程序自身; 某个将其他错误模型转换为 errno 模型的兼容层。 所以最准...
Lely `dcf-tools` 与 `master
Lely dcf-tools 与 master.yml 配置教程:从 EDS 生成可用的主站 DCF @[toc] 适用版本:原生 Lely CANopen 2.4.0 dcfgen。本文使用上游 master/options/<slave> 结构,不适用于 ROS 2 或其他 downstream 项目自定义的 defaults/nodes YAML 格式。 本文解决什么问题Lely 主站通常不是直接读取从机 EDS 后运行,而是先在开发机上通过 dcfgen 合并主站策略、从机 EDS 和 PDO/SDO 配置,生成 master.dcf 以及按需生成的 concise DCF 二进制文件。 本文给出一条可复现的配置路径: 在 Ubuntu 开发机安装与目标 Lely 源码匹配的 dcf-tools; 准备从机 EDS 和 master.yml; 逐项理解 options、master 和从机 section; 生成并检查 master.dcf; 使用一份完整的 demo.yml 作为字段字典,其中非必需字段全部保留为注释。 本文示例环境: ...
Lely canopen:用 EDS 和 `master
Lely canopen:用 EDS 和 master.yml 生成 CANopen 主站 DCF 本文以 Lely CANopen 2.4.0、Ubuntu 20.04 和 CANopenNode 从站为例,演示如何在开发机上安装 dcf-tools,编写原生 Lely master.yml,并从 EDS 生成可供主站程序使用的 master.dcf。 本文要解决的问题在嵌入式 CANopen 项目中,经常会同时存在两套运行环境: 目标板运行交叉编译后的 Lely C/C++ 库; 开发机运行 Python 版 dcf-tools,用于检查 EDS/DCF 和生成主站配置。 这两部分相互配合,但不需要安装到同一个系统,也不要求使用同一种架构。目标板可以继续使用 --disable-python --disable-cython 构建 Lely;dcf-tools 只安装在 Ubuntu 开发机上即可。 完成本文后,你将得到: 123456789config/├── project.eds # 原始从站 EDS├──...
RTOS 优先级翻转与实时任务阻塞的通用治理
嵌入式面试真题第 11 题:RTOS 优先级翻转与实时任务阻塞的通用治理 123456flowchart LR H[高优先级实时任务\n控制 / 音频 / 通信 / 采样] -->|请求共享资源| R{共享资源} L[低优先级后台任务\n日志 / 存储 / 维护] -->|已经持有| R M[中优先级任务\nUI / 协议 / 计算] -->|持续占用 CPU| L R --> P[阻塞时间不可控\n高优先级任务错过期限] P --> S[治理目标\n有界阻塞 + 可分析 + 可降级] 问题在采用固定优先级抢占调度的 RTOS 系统中,通常同时存在硬实时或准实时任务、普通业务任务和后台维护任务。系统还会共享 SPI、I2C、Flash、文件系统、网络控制器、内存分配器、日志通道、配置数据库、图形缓冲区、硬件加速器或其他软硬件资源。 某次压力测试中,高优先级任务出现周期抖动、数据断流、控制超时、音频卡顿、通信丢包或看门狗复位。初步分析发现,高优先级任务正在等待一个由低优先级任务持有的资源;与此同...
高优化等级下共享状态可见性、内存模型与系统级同步设计
嵌入式面试真题第 10 题:高优化等级下共享状态可见性、内存模型与系统级同步设计 问题在一个带有 RTOS 的嵌入式系统中,某个共享状态在调试版本或 -O0 下工作正常,但切换到 -O2、-O3、LTO,或迁移到带数据 Cache、多核 CPU、DMA 和总线主设备的新平台后,消费者偶发看不到生产者刚刚写入的数据,或者出现“标志位已经变化,但数据体仍是旧值”“中断已经发生,任务仍在空转”“DMA 已完成,CPU 读取的缓冲区却没有更新”“单核正常,多核失效”等问题。 生产者可能来自按键扫描任务、设备驱动中断、协议接收线程、DMA、另一个 CPU 核、协处理器或外部总线主设备;消费者可能是状态机、控制任务、日志线程、UI、音视频处理线程或安全监控任务。共享对象也不一定只是一个布尔标志,它可能是一组状态位、计数器、描述符、环形缓冲区索引、消息结构体、双缓冲区、控制块或一段 DMA 共享内存。 请不要把问题简化为“加一个 volatile”。需要从 C/C++ 抽象机、编译器优化、寄存器分配、CPU 乱序执行、Store Buffer、Cache 一致性、DMA 非一致性...
非易失性存储局部失效下的通用持久化容错架构设计
嵌入式面试真题第 09 题:非易失性存储局部失效下的通用持久化容错架构设计 问题在一款需要长期运行、频繁保存配置、日志、计量数据、资源索引、模型参数、升级状态或业务文件的嵌入式设备中,底层非易失性存储可能是片内 Flash、外部 SPI NOR、原始 NAND、QSPI/OSPI Flash,也可能是带内部控制器的 eMMC、UFS、SD 卡或其他块设备。 产品在量产、老化、运输、现场升级和多年使用过程中,可能出现以下任一种异常: 某个擦除单元无法擦成全擦除态; 某个编程单元写入后读回不一致; 某页出现不可纠正 ECC; 某次写入被掉电、复位或看门狗打断,只完成了一部分; 某个元数据块长期高频更新后提前磨损; 底层控制器偶发超时、忙状态不退出或返回瞬态错误; 映射表、目录、超级块或日志头部自身损坏; 可用备用空间持续下降,最终无法完成垃圾回收或数据迁移。 如果这些故障直接透传给上层,轻则丢失单条配置或日志,重则整个分区无法挂载、固件无法启动、设备反复重启甚至永久“变砖”。 你会如何设计一套通用的持久化容错架构,使局部介质失效不会立即演变成卷级损坏,并做到: 已...









