一台 ESP32 矿机上电后,究竟发生了什么?

「ESP32 矿机固件深度解析」第 1/15 篇

按下电源键之后,联网、矿池握手、作业构造、ASIC 初始化和散热控制几乎同时开始。任何一个环节的时序不对,最终表现都可能只是“没有算力”。这篇文章从入口函数出发,把 ESP-Miner 的完整运行链路还原出来。

先说结论:ESP-Miner 不是一段驱动 ASIC 的循环,而是控制平面与高吞吐数据平面共同运行的实时系统。


从入口函数看系统边界

入口位于 main/main.c。启动顺序大致如下:

PSRAM 检查  -> I2C 初始化并保持 ASIC Reset  -> ADC、NVS、eFuse 身份初始化  -> 识别设备型号和硬件版本  -> 自检/量产模式分流  -> Wi-Fi、云端客户端、显示和电源外设  -> 电源管理、运行时诊断、REST、TCP、BAP  -> 等待网络  -> ASIC 初始化  -> Stratum、作业生成、ASIC 收发、算力统计任务
这个次序体现了两个重要原则。第一,ASIC 在基础配置完成前始终保持复位,避免未知电压下运行;第二,管理平面先于挖矿数据平面启动,因此设备即使暂时不能出算,也仍具备诊断和升级能力。

app_main() 还把 cJSON 的分配器优先指向 PSRAM,失败后回退内部 RAM。JSON、证书和网络缓冲属于容量敏感而时延不敏感的数据,放入 PSRAM 可以把片上 SRAM 留给 UART、I2C 和实时任务。这是 ESP32-S3 产品化固件中很实用的内存分层。


GlobalState:便利的共享上下文

main/global_state.h 中的 GlobalState 聚合了:

SystemModule

:网络、矿池、Share、升级和故障状态;

DeviceConfig

:板型、ASIC、传感器、电源芯片;

PowerManagementModule

:电压、功率、温度、风扇和目标算力;

HashrateMonitorModule

:寄存器计数和统计窗口;

两条工作队列、当前作业表、传输锁及 ASIC 初始化标志。

集中状态让各任务的函数签名保持简单,也方便 REST 接口一次性汇总。但它不是无代价的:大量字段被不同任务读写,只有 transport_lock、valid_jobs_lock 等少数字段显式加锁。32 位标量通常能够原子读写,不代表复合状态具有一致快照。例如 URL、端口和 is_using_fallback 若跨多个语句更新,观察者可能读到组合不一致的状态。

更稳健的演进方式不是立刻拆掉 GlobalState,而是逐步定义所有权:Stratum 任务拥有连接状态,电源任务拥有电源遥测,其他模块通过快照 API 读取。这样可以保留现有结构,同时减少隐式耦合。


控制平面与数据平面

ESP-Miner 可以按职责划分为两条路径。

数据平面追求吞吐和连续性:

矿池 JSON -> mining_notify -> bm_job -> ASIC UARTASIC Nonce -> 难度计算 -> mining.submit
控制平面追求安全和可维护性:

NVS/REST/BAP -> 频率、电压、风扇、矿池参数传感器/PMBus -> 热控、故障系统、Web 状态、量产判定OTA -> 停止挖矿、关闭电源、写分区、切换启动分区
当前实现已经在关键处建立隔离。例如 OTA 会先静默 Stratum 和 ASIC;睡眠模式会让挖矿任务退出;过热恢复通过 asic_initialize() 统一走冷启动/恢复逻辑。


任务优先级透露出的实时需求

ASIC 结果任务优先级为 15,作业发送与作业生成是 10,Stratum 管理为 5,统计为 3。这个排序合理:ASIC UART 缓冲是最容易溢出的边界,Nonce 处理必须优先;统计允许延后;网络连接管理虽然重要,却不能阻塞结果接收。

需要注意,多个任务使用 8192 字节栈,部分任务优先尝试 PSRAM 栈。统一的大栈减少了早期栈溢出风险,但掩盖了真实水位。生产固件应定期记录 uxTaskGetStackHighWaterMark(),随后按任务缩减,避免 PSRAM 不可用时内部 RAM 突然耗尽。


架构亮点与改进方向

值得肯定的设计包括:硬件抽象覆盖多代 ASIC 和电源芯片;挖矿任务与 Web/云端解耦;启动时对 ASIC 做安全复位;具备主备矿池、TLS、运行时错误和工厂测试。

优先改进项有三点:

  1. 为共享状态建立单写者和快照约定,避免靠“通常不会同时发生”维持正确性。

  2. 把启动流程显式建模为状态机,替代散落的布尔量和等待循环。

  3. 建立统一资源生命周期:任务创建、队列初始化、睡眠退出和恢复重建应成对出现。

ESP-Miner 的价值不只在于驱动了一颗 ASIC。它展示了如何把矿池协议、硬件控制和产品运维压缩到一颗 ESP32-S3 中,而后续工程质量的关键,是让这些模块之间的契约从“代码约定”升级为“明确接口”。


写在最后

读懂启动链路的意义,是先建立一张系统地图。以后遇到无算力、连接抖动或者功率故障时,才能判断问题发生在网络、作业、ASIC 还是控制策略,而不是盯着最后一条日志猜原因。

下一篇我们继续拆解:矿机不会排队就会乱:FreeRTOS 挖矿流水线拆解

本文基于仓库当前代码进行工程分析。涉及超频、电压、电流与温度保护的修改,应结合原理图、器件规格书、示波器波形和温升测试验证,不能仅凭软件日志调整安全阈值。

发表评论