当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]你已经经历过这种情况了。你的ESP32产品在客户现场运行了6小时后突然崩溃。设备会自动重启——因为这是你编程时设置的默认行为——而日志中留下的只有这些内容:

你已经经历过这种情况了。你的ESP32产品在客户现场运行了6小时后突然崩溃。设备会自动重启——因为这是你编程时设置的默认行为——而日志中留下的只有这些内容:

JTAG 没有连接。你无法在实验台上复现它。客户很生气,而你却完全不知道发生了什么。

这是固件调试问题,没人有好的解决方案。像Memfault这样的商业方案每月起价约300美元,且需要通过销售电话联系。因此,大多数固件工程师什么也不做——他们只是等待问题再次出现,然后希望能及时发现并解决。

我花了三周时间调试其中一次崩溃问题——这是一台在客户现场运行的设备,没有JTAG接口,无法在测试台上复现。该设备运行了4个多小时才发生崩溃。最终我找到了原因:一个传感器任务中出现了空指针解引用,而这种问题仅由特定的一系列电源欠压恢复事件触发。但整个过程耗费了数天时间,包括阅读日志、添加调试输出和重新刷写固件。

之后,我开发了Firmware Sentry:一个基于Apache-2.0的SDK,它在设备复位前捕获完整的故障状态,能够存活重启过程,将崩溃信息发送到云端,并利用Claude AI以通俗易懂的语言输出根本原因。

本文将介绍其技术原理,并说明如何在30分钟内将其集成到您的ESP32项目中。

工作原理:核心洞察

关键在于时机。当ESP32发生崩溃时,在故障和复位之间存在一个窗口——微秒级的时间——CPU仍处于恐慌处理程序中运行。这个窗口足够长,足以:

•读取所有故障寄存器(PC、SP、LR、EXCCAUSE、EXCVADDR)

•获取当前 FreeRTOS 任务名称

•捕获堆栈快照

•复制您应用记录的最后10个面包屑事件

•将所有内容写入RTC NOINIT内存

最后一步是关键所在。ESP-IDF 中的 RTC_NOINIT_ATTR 变量在软件复位(SW_CPU_RESET)后仍然保留。它们存储在 RTC RAM 中,而 C 启动代码在重启时不会清零该内存区域。因此,当设备重新启动时,崩溃数据仍会存在,等待发送。

The Panic Handler Hook

该SDK通过GNU链接器的--wrap选项,将ESP-IDF的崩溃处理程序进行挂钩。在链接时,它用我们的版本替换esp_panic_handler——无需对ESP-IDF源码进行任何修改。

在根目录的 CMakeLists.txt 中添加了 --wrap 标志:

如果没有这个标志,SDK 会安装但永远不会捕获崩溃。

RTC NOINIT:它为何有效

碰撞数据存储在 RTC_NOINIT_ATTR 变量中:

总计使用了约601字节的RTC内存。ESP32有8KB可用空间,因此没问题。

下次启动时,我们会检查魔数:

如果匹配到魔法,就会捕获一个崩溃并需要发送。发送后,我们将其清除:

需要注意的一点:这仅适用于软件复位(如看门狗、esp_restart())。电源复位(如欠压、硬复位)会清空RTC内存,这是正常的行为。而电源循环并不会导致崩溃。

面包屑:该设备在做什么?

现场调试最有用的功能并非寄存器,而是了解设备在崩溃前正在做什么。

环形缓冲区可存储最多10个事件,每个事件最多47个字符。它以RTC_NOINIT_ATTR方式存储,因此在复位时仍能保留,并与崩溃寄存器一同保存。线程安全,中断服务例程(ISR)安全,零内存分配。

AI诊断接收完整的调用栈信息,并利用这些信息推断设备崩溃时的运行状态——这通常比仅依赖寄存器更有用。

DWARF 符号解析:程序计数器 → 函数名

像 0x400D2A4C 这样的原始程序计数器地址没有用处。你需要的是 sensor.c 文件中第 87 行的 sensor_read() 函数。

SDK 会捕获 PC 地址。云端使用 pyelftools 遍历您 ELF 二进制文件中的 DWARF 调试表,并将其解析为确切的函数、文件和行号。每次固件构建时上传一次 ELF 文件,仪表板会在每次崩溃时自动完成其余工作。

使用 -g3 构建以获得最佳符号解析:

AI诊断:你真正得到的是什么

以下是空指针崩溃时仪表板中显示的内容示例:

AI接收所有捕获的寄存器、DWARF解析后的函数/文件/行、面包屑路径以及故障分类信息。无需JTAG,无需复制,仅提供答案。

集成:从零到第一次崩溃的30分钟

1 — 注册并创建设备

•免费注册 firmwaresentry.io(无需信用卡)

•仪表板 → 组别 → 新建组 → ESP32 → 开发者模式

•添加设备 → 复制设备API密钥

2 — 添加 SDK

•选项 A — 组件(推荐用于 ESP-IDF 项目):

•选项B — 合并(两个文件,可随意放置):

将 dist/firmware_sentry.h 和 dist/firmware_sentry.c 复制到你的 main/ 目录中。

3 — 更新 CMakeLists.txt

4 — 在 app_main() 中集成

5 — 快速触发并测试崩溃

Bash

在代码的任何位置触发崩溃:

设备崩溃、重启,发送崩溃信息,约41秒后AI诊断将出现在你的仪表盘上。

Zero-Touch Provisioning for Production Fleets

在生产环境中,您不希望硬编码设备API密钥。SDK支持零接触配置:每个设备在首次启动时会使用编译进固件中的共享烧录密钥进行自助注册。

每个设备根据其硬件MAC地址获得唯一的API密钥。每个密钥的注册速率限制为每分钟50次。配置窗口可设为时间限制,并在出厂运行后关闭。

这意味着一个固件二进制文件、一个闪存步骤,零个设备配置。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

为了探索低成本替代方案是否能提供有用的信息,我基于ESP32开发了一款水质分析仪。该设备结合了三个不同传感器(pH值、电导率和浊度)的测量数据,以评估河流、溪流和湖泊等淡水水源的整体状况。

关键字: 传感器 升压转换器 ESP32

冰壶运动员在比赛中使用秒表来判断冰球滑下冰面的速度。计时过程还能为运动员提供有关冰面“速度”的信息,即冰球与冰面之间的摩擦力大小。大多数传统秒表在冰壶运动中给运动员带来两个挑战:

关键字: 计时器 蜂鸣器 ESP32

本项目的设计灵感源自经典飞机驾驶舱仪表,这些仪表用于导航、定位和飞行监控。在航空领域,人工水平仪、磁罗盘、高度计和姿态指示器等仪器发挥着关键作用,为飞行员提供有关飞机姿态、航向和高度的实时信息。

关键字: 编码器 加速度计 ESP32

我们常常将地球视为被动的背景,却忘记了自己身体的本质正是由地球的物质构成。《消失的地球回忆录》是一个沉浸式艺术项目,通过触觉的亲密体验弥合这一鸿沟。借助一台定制乐器,我们将人体与不断变化、受损的景观之间产生的电振荡转化为...

关键字: 开发板 ESP32 传感器

辐射霜冻现象在植被叶片结构向晴朗的夜空辐射热能矢量时悄然显现,其温度低于标准环境温度分布。传统的宏观尺度天气预报API完全无法解析这些局部农业地形区域内的关键微气候差异。

关键字: 寄存器 路由器 ESP8266

Brookstone Rover 是一款通过 Wi-Fi 控制的履带式“间谍坦克”,可将视频流传输到旧版 iOS 应用程序上。虽然该应用程序早已失效,但其底盘却是极佳的捐赠硬件:坚固的橡胶履带、两个齿轮直流电机,以及一个...

关键字: 电机驱动器 机器人 ESP32 DRV8833

上海2026年7月14日 /美通社/ -- 随着 HarmonyOS 7 发布、鸿蒙智能体框架 2.0 把 Agent 能力放到客户端,越来越多开发者开始在自己的 App 里嵌入 Agent。一个电商 App,可能只是在...

关键字: SDK 鸿蒙 TI THINKING

BACnet 是一种国际标准的楼宇自动化通信协议,可使来自不同制造商的设备(如供暖、通风、空调、照明和安防系统)能够相互通信。目前的 BACnet 系统通常使用以太网作为传输介质(BACnet/IP),而较早的系统则通常...

关键字: 服务器 开发板 楼宇自动化 ESP32

随着智能家居设备(IoT)的普及,我们的家庭和企业网络已成为静默漏洞的高危地带。智能电视、老旧的IP摄像头以及路由器经常运行未经加密的旧式服务,例如Telnet(端口23)或FTP(端口21)。

关键字: 智能家居 摄像头 路由器 ESP32

我的歌唱机器人是一种交互式音乐表演系统,由手持控制器、四个无线机器人节点和一台笔记本电脑图形用户界面组成。用户可通过4步音序器开启或关闭每个机器人,调节节拍(BPM),并使用控制器上的旋转编码器改变各机器人的音高,来创作...

关键字: 机器人 LED灯 扬声器 ESP32
关闭