本文档系统性地剖析 otxFlash 模块中刷写器(Flasher)的完整继承体系——从最顶层的纯抽象接口 ECUFlasher 出发,经 ECUFlasherImpl 提供公共实现骨架,到 SingleECUFlasher、MultipleECUFlasher、SequenceECUFlasher、ParallelECUFlasher 逐级扩展行为,最终由 ECUFlasherManager 完成多优先级分组并行调度。理解这一体系是掌握整个刷写流程、事件驱动模型、以及后续 Manager/ParallelECUFlasher 等子专题的前提。
核心继承体系
整个刷写器类族围绕 virtual public 菱形继承 构建——所有叶子类通过 virtual 关键字确保基类子对象唯一,这在 ECUFlasherManager 同时继承 ECUFlasherImpl 与 ECUFlasherEventHandler(后者又间接依赖前者的上下文)时至关重要。
classDiagram
class ECUFlasher {
<<interface>>
+download()* bool
+getRemainTime(ECU*)* unsigned long long
+addEventHandler(ECUFlasherEventHandler*)*
+clearEventHandlers()*
}
class ECUFlasherImpl {
-vector~ECUFlasherEventHandler*~ mEventHandlers
-size_t mTotalSize
-volatile size_t mDownloadedSize
-unsigned long long mStartTime
-mutex mFieldLock
+addEventHandler()
+clearEventHandlers()
+getRemainTime(ECU*)
#downloadFile(ECU*, File*) bool
#postECUDownloadStart()
#postECUDownloadEnd()
#postECUResetStart()
#postECUResetEnd()
#postFileDownloadStart()
#postFileDownloadEnd()
#postFileDownloadProgress()
}
class SingleECUFlasher {
-ECU* mECU
+download() bool
+getECU() ECU*
+setECU(ECU*)
}
class MultipleECUFlasher {
-vector~ECU*~ mECUs
+getECUs() vector~ECU*~*
+addECU(ECU*)
}
class SequenceECUFlasher {
+download() bool
-downloadECU(ECU*) bool
}
class ParallelECUFlasher {
-TaskPool* mPool
-atomic~int~ mCompletedECUs
+download() bool
-downloadECU(ECU*)
-ecuReady(ECU*) bool
-reset(ECU*) bool
-securityAccess(int) bool
-exitFota(int) bool
+FinishProgram(ECU*)$ bool
+taskWork(Task*)$
+taskCancel(Task*)$
}
class ECUFlasherManager {
-map~int, vector~ECU*~*~ mPriorityECUs
-map~string, ECU*~ mECUs
-bool mStarted
-TaskPool* mPool
+download() bool
+addECU(...)
+addECUFile(...)
+onECUDownloadStart()
+onECUDownloadEnd()
+onFileDownloadStart()
+onFileDownloadEnd()
+onFileDownloadProgress()
}
ECUFlasher <|.. ECUFlasherImpl : virtual
ECUFlasher <|.. SingleECUFlasher : virtual
ECUFlasher <|.. MultipleECUFlasher : virtual
ECUFlasherImpl <|.. SingleECUFlasher : virtual
ECUFlasherImpl <|.. MultipleECUFlasher : virtual
MultipleECUFlasher <|-- SequenceECUFlasher : virtual
MultipleECUFlasher <|-- ParallelECUFlasher : virtual
ECUFlasherImpl <|.. ECUFlasherManager : virtual
ECUFlasherEventHandler <|.. ECUFlasherManager : virtual
ECUFlasherManager ..> ParallelECUFlasher : creates & uses
ParallelECUFlasher ..> TaskPool : submits to菱形继承的关键设计决策:SingleECUFlasher 和 MultipleECUFlasher 都通过 virtual public ECUFlasher 和 virtual public ECUFlasherImpl 继承,而非普通继承。这意味着当 SequenceECUFlasher 和 ParallelECUFlasher 进一步继承 MultipleECUFlasher 时,ECUFlasher 的虚函数表指针在整个对象中只存在一份。ECUFlasherManager 同时继承 ECUFlasherImpl 和 ECUFlasherEventHandler,前者提供事件发布能力,后者提供事件接收接口,使得 Manager 既能作为被观察者向外部转发事件,又能内部消费来自子 Flasher 的事件。
Sources: ECUFlasher.hpp, ECUFlasherImpl.hpp, SingleECUFlasher.hpp, MultipleECUFlasher.hpp, SequenceECUFlasher.hpp, ParallelECUFlasher.hpp, ECUFlasherManager.hpp
各层职责分解
第一层:ECUFlasher — 纯抽象契约
ECUFlasher 是刷写器体系的最顶层接口,仅声明四个纯虚函数作为所有刷写器的行为契约:
| 方法 | 语义 | 同步性 |
|---|---|---|
download() | 执行刷写,返回整体成功/失败 | 同步(调用方阻塞直到完成) |
getRemainTime(ECU*) | 基于当前传输速率估算指定 ECU 剩余时间(微秒) | 线程安全(内部加锁) |
addEventHandler(ECUFlasherEventHandler*) | 注册生命周期事件监听器 | 非线程安全 |
clearEventHandlers() | 清空所有已注册监听器 | 非线程安全 |
构造函数和赋值运算符均为 protected,确保只能通过派生类实例化——这是典型的接口隔离设计。
Sources: ECUFlasher.hpp
第二层:ECUFlasherImpl — 公共骨架实现
ECUFlasherImpl 以 virtual 方式实现 ECUFlasher,提供所有刷写器共用的基础设施:
事件发布机制:内部维护 std::vector<ECUFlasherEventHandler *> mEventHandlers,通过七个 post* 方法遍历所有已注册的 handler 并逐个回调。这七个方法覆盖了 ECU 级别(下载开始/结束、复位开始/结束)和文件级别(下载开始/结束、进度更新)的完整生命周期。
进度与时间估算:mTotalSize(所有文件总大小)、mDownloadedSize(已下载累积量)和 mStartTime(下载开始时的时间戳)三者结合完成剩余时间计算。getRemainTime() 通过线性速率模型估算:剩余时间 = 剩余字节数 / (已下载字节数 / 已耗时)。该计算受 mFieldLock 互斥锁保护。
文件下载委托:downloadFile(ECU*, File*) 是文件级别下载的核心实现,通过编译期宏 FLASHER_USE_MCD_METHOD 控制两套策略:
- MCD 模式(生产):根据 ECU 名称判断文件格式——名称含
TCAM、BGM、CDC、ACU的域控制器使用BinFileDownloader(二进制格式直传),其余使用VbfFileDownloader(VBF 格式,需解析块结构后逐块传输)。 - 模拟模式:以 10% 步长模拟进度推进,每步间隔 200ms,用于离线测试。
Sources: ECUFlasherImpl.hpp, ECUFlasherImpl.cpp
第三层:SingleECUFlasher — 单 ECU 同步刷写
SingleECUFlasher virtual 继承 ECUFlasher 和 ECUFlasherImpl,持有单一 ECU* mECU 指针。其 setECU() 方法在设置 ECU 引用时同时累加所有文件的 mTotalSize,为剩余时间计算提供基准。
download() 的执行流程是顺序嵌套的同步模型:
FOR each File in ECU.files:
downloadFile(ecu, &file) ← 委托给 ECUFlasherImpl::downloadFile()
IF failed: BREAK
向外部 postECUDownloadEnd(status)关键约束:download() 是同步阻塞方法——调用方线程将一直阻塞直至该 ECU 的所有文件传输完成,适用于不需要并发的简单场景或作为更复杂刷写器的原子执行单元。
Sources: SingleECUFlasher.hpp, SingleECUFlasher.cpp
第四层:MultipleECUFlasher — 多 ECU 管理能力
MultipleECUFlasher 将单 ECU 概念扩展为多 ECU 集合,新增 std::vector<ECU *> mECUs 容器及 addECU() 方法。每次添加 ECU 时调用 ecu->getTotalSize() 累加到 mTotalSize(该值由 ECU 内部维护,在文件添加时自动计算)。
它是 SequenceECUFlasher 和 ParallelECUFlasher 的共同基类,但本身不实现 download()——仅提供 ECU 集合管理,将具体调度策略留给派生类决定。
Sources: MultipleECUFlasher.hpp, MultipleECUFlasher.cpp
第五层 A:SequenceECUFlasher — 顺序调度
SequenceECUFlasher virtual 继承 MultipleECUFlasher,实现FIFO 顺序刷写策略。其 download() 按 mECUs 的添加顺序逐一调用 downloadECU(ecu),每个 ECU 内部又以同步方式遍历其所有文件。
这种行为等价于多次调用 SingleECUFlasher::download(),但共享同一个事件系统和进度追踪上下文。适合对刷写顺序有严格依赖关系的场景(例如必须先刷写网关 ECU 再进行下游 ECU 刷写)。
Sources: SequenceECUFlasher.hpp, SequenceECUFlasher.cpp
第五层 B:ParallelECUFlasher — 并行调度引擎
ParallelECUFlasher 是刷写体系中最复杂的派生类,virtual 继承 MultipleECUFlasher,通过 TaskPool 线程池实现多 ECU 并发刷写。
架构:构造时接收外部 TaskPool*(生命周期由调用方管理),每个 ECU 的刷写被封装为独立的 Task 提交到线程池。FlashTaskArg 结构体作为桥接:持有 ParallelECUFlasher* 回指指针和 ECU* 目标,使得静态回调函数 taskWork() 能够访问刷写器实例的方法。
并行调度流程:
sequenceDiagram
participant Caller as 调用方线程
participant PF as ParallelECUFlasher
participant TP as TaskPool
participant TW as TaskPool 工作线程 (x N)
participant ECU as ECU 诊断通信
Caller->>PF: download()
PF->>PF: 记录 mStartTime
loop 每个 ECU
PF->>PF: downloadECU(ecu)
PF->>TP: addTask(new Task(taskWork, taskCancel, arg))
TP->>TP: 若当前并发数 < mParallelSize,创建新线程
TP->>TP: 任务入队 mTasks
end
Note over PF: 主线程进入 busy-wait 循环
loop while mCompletedECUs < mECUs.size()
PF->>PF: spin-wait (无 sleep)
end
par 工作线程 1
TW->>TW: 从队列取出 Task
TW->>PF: taskWork(task)
PF->>PF: postECUDownloadStart
PF->>PF: ecuReady(ecu) → 安全访问 + 签名模式检测
loop 每个 File
PF->>PF: downloadFile(ecu, &file)
end
PF->>PF: FinishProgram(ecu)(可选)
PF->>PF: reset(ecu)(域控制器)
PF->>PF: postECUDownloadEnd
PF->>PF: mCompletedECUs.fetch_add(1)
and 工作线程 2
TW->>TW: 从队列取出另一个 Task
TW->>PF: taskWork(task) ...
end
PF->>Caller: return true(所有 ECU 完成)安全访问前序(ecuReady):在正式传输文件前,工作线程会执行一系列诊断准备操作——EnterSystem() 进入系统会话、检测签名模式(prod/dev)、根据 securityAccessMode 选择 SecurityAccess 策略(优先 PinCode 或优先 FFFFFFFFFF)。这些操作都通过 MCDCmdTrans 封装的标准 UDS 诊断命令完成。
刷写后处理:文件传输成功后调用 FinishProgram() 执行安装校验(通过 RoutineControl 0x31 01 42 89 退出 FOTA 模式),域控制器(TCAM/BGM/CDC/ACU)额外执行 ECU 复位——BGM 通过广播方式复位后还需 otx_reconnect_vehicle_ex() 重建车辆连接。
原子计数器:mCompletedECUs 使用 std::atomic<int> 配合 memory_order_relaxed(因为仅用作计数信号,无需同步其他内存操作),工作线程完成后 fetch_add(1),主线程在 download() 末尾的 busy-wait 循环中轮询直到计数值等于 ECU 总数。
Sources: ParallelECUFlasher.hpp, ParallelECUFlasher.cpp
第六层:ECUFlasherManager — 优先级分组调度与事件中继
ECUFlasherManager 是刷写体系的最外层门面,同时 virtual 继承 ECUFlasherImpl(获得事件发布能力)和 ECUFlasherEventHandler(获得事件接收能力),承担三个核心职责:
1. ECU 注册与文件绑定:addECU() 创建 ECU 对象并按 priority 分组插入 std::map<int, std::vector<ECU*>*>——C++ std::map 按 key 升序自动排序,天然实现优先级从低到高的调度。同时维护 std::map<std::string, ECU*> mECUs 用于按名称检索,以及 std::vector<std::string> mSequenceECUNames 记录添加顺序。addECUFile() 提供两种重载:一种接收已解析的 VBFParserSmall*(直接从 VBF 解析结果填充),另一种接收文件路径和大小(延迟解析)。两者均在 mStarted 为 false 时方可调用,通过抛异常 -1 保证配置阶段的不可变性。
2. 优先级分组并行调度:download() 按优先级分组逐组执行——外层循环按 mPriorityECUs 的 key 升序迭代每个优先级组,组内创建 ParallelECUFlasher 实例并将该组所有 ECU 添加进去,调用 flasher.download() 等待该组全部完成后再进入下一组。这种设计实现了组间顺序、组内并行的两级调度策略。ECU 优先级数值越小越先执行(std::map 默认升序),若需调整执行顺序,只需改变 ECU 的 priority 值。
3. 事件双向中继:Manager 将自己注册为 ParallelECUFlasher 的事件监听器(flasher.addEventHandler(this)),在 on* 回调中直接转发至 post* 方法,形成 ParallelECUFlasher → ECUFlasherManager → 外部监听器 的事件链。onFileDownloadEnd() 额外处理了进度补偿逻辑:如果文件下载完成时 downloadedSize < size(下载引擎可能跳过最后 1% 的进度回调直接报告完成),则手动补齐差值,确保剩余时间计算准确。
TaskPool 生命周期:构造时创建 TaskPool(并发度可配置,范围 [1, 7],默认 5),析构时调用 pool->shutdown() 等待所有工作线程 join 并回收内存。
Sources: ECUFlasherManager.hpp, ECUFlasherManager.cpp
数据模型
刷写器体系涉及两个核心领域对象,它们之间的关系决定了刷写流程的粒度层级:
classDiagram
class ECU {
-string mName
-string mId
-string mDbLogicalLinkName
-int mPriority
-int securityAccess
-int installVerify
-int signatureMode
-int mSecurityAccessMode
-string activeSBLAddress
-vector~File~ mFiles
-vector~string~ m_vecCmd
-size_t mTotalSize
-size_t mDownloadedSize
-bool isProd
}
class File {
-string mPath
-size_t mSize
-int mFileType
-string mPinCode
-string mKeyInfo
-size_t mDownloadedSize
-size_t mLastDownloadedSize
+VBFParserSmall parser
}
ECU "1" -- "*" File : 包含ECU 是刷写的最小调度单元,每条记录对应车辆上的一个物理 ECU。关键字段说明:
| 字段 | 类型 | 用途 |
|---|---|---|
mName / mId | string | 友好名称与唯一标识符 |
mDbLogicalLinkName | string | MCD 诊断数据库中的逻辑链路名,用于建立 DoIP 连接 |
mPriority | int | 优先级,数值越小越先执行(在 Manager 中作为 map key) |
securityAccess | int (bool) | 是否需要执行 SecurityAccess(27 服务)解锁 |
installVerify | int (bool) | 刷写后是否需要 FinishProgram 安装校验 |
signatureMode | int | 签名模式:0=同时支持 prod/dev,1=仅 dev,2=仅 prod |
mSecurityAccessMode | int | 安全访问策略:0=优先 PinCode,1=优先 FFFFFFFFFF(换件刷写) |
mTotalSize / mDownloadedSize | size_t | 文件总大小 / 已下载大小,用于进度和剩余时间计算 |
isProd | bool | 运行时检测到的签名环境标记 |
File 是刷写的最小传输单元,描述一个待刷写的数据文件:
| 字段 | 类型 | 用途 |
|---|---|---|
mPath | string | 文件路径 |
mSize | size_t | 文件大小(字节) |
mFileType | int | 文件类型:1/2/3(如 PBL、SBL、App),类型 3 的 PBL 文件刷写后跳过安装校验 |
mPinCode | string | SecurityAccess 解锁 PinCode(ECOS 模式) |
mKeyInfo | string | 签名验证的公钥信息 |
parser | VBFParserSmall | VBF 解析器实例(按值拷贝),携带 header、blocks 和文件缓冲区 |
事件驱动模型
刷写器通过 Observer 模式解耦刷写进度通知与业务逻辑。事件的完整生命周期如下:
flowchart LR
subgraph 发布者
PCI[ParallelECUFlasher::taskWork]
DFF[ECUFlasherImpl::downloadFile]
end
subgraph 事件类型
E1[ECUFlasherECUEventArg<br/>ECU下载 开始/结束]
E2[ECUFlasherECUEventArg<br/>ECU复位 开始/结束]
E3[ECUFlasherFileEventArg<br/>文件下载开始]
E4[ECUFlasherFileDownloadProgressEventArg<br/>文件下载进度]
E5[ECUFlasherFileDownloadEndEventArg<br/>文件下载结束]
end
subgraph 中继者
MGR[ECUFlasherManager<br/>实现 ECUFlasherEventHandler]
end
subgraph 外部消费者
EXT[外部监听器<br/>如 ReportRecordCollector]
end
PCI -->|postECUDownloadStart/End| E1
PCI -->|postECUResetStart/End| E2
DFF -->|postFileDownloadStart| E3
DFF -->|postFileDownloadProgress| E4
DFF -->|postFileDownloadEnd| E5
E1 & E2 & E3 & E4 & E5 --> MGR
MGR -->|转发 post*| EXT事件参数类的继承关系反映了文件事件的层级扩展:
- ECUFlasherECUEventArg:携带
ECUFlasher* sender(发起者)、ECU* ecu(目标 ECU)、bool status(仅 End 事件有效) - ECUFlasherFileEventArg:基类,额外携带
File* file - ECUFlasherFileDownloadProgressEventArg (virtual extends FileEventArg):新增
int mProgress(0-100 百分比) - ECUFlasherFileDownloadEndEventArg (virtual extends FileEventArg):新增
int mErrorCode和std::string mMessage
ECUFlasherManager 的 onFileDownloadEnd() 回调中有一个关键修复:当文件下载完成事件触发但 ecuFile->getDownloadedSize() < ecuFile->getSize() 时(表明最后 1% 的进度回调被跳过),会手动补齐 ecu->setDownloadedSize() 中的差值,防止剩余时间计算失真。
Sources: ECUFlasherEventHandler.hpp, ECUFlasherECUEventArg.hpp, ECUFlasherFileEventArg.hpp, ECUFlasherFileDownloadProgressEventArg.hpp, ECUFlasherFileDownloadEndEventArg.hpp
文件下载委托链
downloadFile() 在 ECUFlasherImpl 中根据 ECU 类型分派到不同的下载器实现:
| 条件 | 下载器 | 文件格式 | 传输方式 |
|---|---|---|---|
ECU 名称含 TCAM/BGM/CDC/ACU | BinFileDownloader | 原始二进制 | MCD 逐帧传输(RequestDownload → TransferData → RequestTransferExit) |
| 其他 ECU | VbfFileDownloader | VBF 结构化格式 | MCD 逐块传输(需解析 VBF header 和 blocks) |
两个下载器都实现 asam::mcd::MCDEventHandler 以接收 MCD3D 诊断通信库的底层事件回调(链路状态变化、原语执行结果等),同时持有回指 ECUFlasher* 的指针以访问 friend 声明的 ECUFlasherImpl 内部状态(事件处理器列表、下载进度字段)。
下载完成后,由下载器构造 ECUFlasherFileDownloadEndEventArg 携带 errorCode 和 message,调用 postFileDownloadEnd() 通知所有监听器。
Sources: ECUFlasherImpl.cpp, BinFileDownloader.hpp, VbfFileDownloader.hpp
TaskPool 线程池
TaskPool 是 ParallelECUFlasher 实现并发的底层引擎,设计要点:
- 并发度窗口:
mParallelSize限制同时运行的工作线程数(范围 1-7),mCurrentParallelSize跟踪当前活跃线程数 - 惰性线程创建:
addTask()仅在mCurrentParallelSize < mParallelSize时创建新线程,之后任务入队等待空闲线程拉取 - 工作线程循环:每个线程在
threadWork()中进入 while 循环,持续从mTasks队列拉取任务并执行task->execute(),队列为空时 sleep 20ms - 任务自销毁:
Task的execute()(即taskWork回调)末尾负责delete arg; delete task;——调用方将任务提交后即放弃所有权 - 优雅关闭:
shutdown()设置原子标志mShutdown,取消队列中所有待执行任务(调用其cancel回调释放内存),然后 join 所有工作线程
Sources: TaskPool.hpp, TaskPool.cpp, Task.hpp
诊断通信支撑
MCDCmdTrans 和 MCDCmdBoardcast 是刷写过程中与 ECU 进行 UDS 诊断通信的核心工具类,它们封装了 MCD3D(ISO 22900-3)API:
- MCDCmdTrans:点对点诊断通信,支持
sendCommand()(发送原始 UDS 命令并接收响应)、SecurityAccess()(27 服务解锁)、RequestDownload()/TransferData()/RequestTransferExit()(34/36/37 服务文件传输)、FinishProgram()(31 服务安装校验)、EnterSystem()(10 服务会话切换)、SeedToKey()(安全访问密钥计算)等 - MCDCmdBoardcast:单例模式的广播通信,用于同时向所有 ECU 发送命令(如批量进入编程模式),通过
getInstance()获取全局唯一实例
两者的逻辑链路通过 ECU::mDbLogicalLinkName 定位,这是 MCD 项目数据库中定义的逻辑链路标识符。
Sources: MCDCmdTrans.hpp, MCDCmdBoardcast.hpp
刷写流程全景
以下流程图汇总了从 ECUFlasherManager::download() 到单个文件传输完成的完整调用链:
flowchart TD
MGR_DL[ECUFlasherManager::download] --> BC_CHECK{MCDCmdBoardcast<br/>可用?}
BC_CHECK -->|否| FAIL_ALL[所有 ECU 标记失败]
BC_CHECK -->|是| PRIORITY_LOOP[遍历 mPriorityECUs<br/>按 key 升序]
PRIORITY_LOOP --> CREATE_PF[创建 ParallelECUFlasher<br/>注册 this 为 EventHandler]
CREATE_PF --> ADD_ECUS[将该优先级组所有 ECU<br/>添加到 flasher]
ADD_ECUS --> PF_DL[ParallelECUFlasher::download]
PF_DL --> SUBMIT_ALL[为每个 ECU 创建 Task<br/>提交到 TaskPool]
SUBMIT_ALL --> BUSY_WAIT[主线程 busy-wait<br/>mCompletedECUs == size]
subgraph 工作线程_x
TASK_WORK[taskWork] --> POST_START[postECUDownloadStart]
POST_START --> READY{ecuReady?}
READY -->|是| FILE_LOOP[遍历 ECU.files]
READY -->|否| FAIL_ECU[标记失败]
FILE_LOOP --> DL_FILE[ECUFlasherImpl::downloadFile<br/>→ BinFileDownloader / VbfFileDownloader]
DL_FILE --> NEXT_FILE{还有文件?}
NEXT_FILE -->|是| FILE_LOOP
NEXT_FILE -->|否| FINISH{需要 FinishProgram?}
FINISH -->|是| FP[FinishProgram<br/>UDS 31 01 42 89]
FINISH -->|否| RESET_CHECK{域控制器?}
FP --> RESET_CHECK
RESET_CHECK -->|是| ECU_RESET[ECU 复位 + 重连]
RESET_CHECK -->|否| POST_END[postECUDownloadEnd]
ECU_RESET --> POST_END
POST_END --> ATOMIC_INC[mCompletedECUs++]
FAIL_ECU --> POST_END
end
BUSY_WAIT --> NEXT_PRIORITY{还有优先级组?}
NEXT_PRIORITY -->|是| PRIORITY_LOOP
NEXT_PRIORITY -->|否| RETURN_TRUE[返回 true]继承体系对比总结
| 维度 | ECUFlasher | ECUFlasherImpl | SingleECUFlasher | MultipleECUFlasher | SequenceECUFlasher | ParallelECUFlasher | ECUFlasherManager |
|---|---|---|---|---|---|---|---|
| 角色 | 纯接口 | 骨架实现 | 单 ECU 刷写 | 多 ECU 容器 | 顺序调度 | 并行调度 | 门面 + 优先级调度 |
| ECU 数量 | 未定义 | 未定义 | 1 | N | N | N | N(分组并行) |
| 调度策略 | 无 | 无 | 同步直接 | 无 | FIFO 顺序 | TaskPool 并发 | 组间顺序 + 组内并行 |
| 事件发布 | 无 | 提供 post* | 继承 | 继承 | 继承 | 继承 | 继承 + 中继 |
| 事件消费 | 无 | 无 | 无 | 无 | 无 | 无 | 实现 ECUFlasherEventHandler |
| 线程安全 | 无保证 | mFieldLock | 继承 | 继承 | 继承 | atomic mCompletedECUs | 继承 + mStarted 状态锁 |
| 实例化 | 禁止 | 禁止 | 直接 | 直接 | 直接 | 需传 TaskPool | 直接(可选并发度) |
阅读建议
本文档是 otxFlash 刷写框架的总览入口。完成阅读后,建议按以下路径深入:
- 调度机制:
[ECUFlasherManager:ECU 注册、刷写文件绑定与优先级调度](12-ecuflashermanager-ecu-zhu-ce-shua-xie-wen-jian-bang-ding-yu-you-xian-ji-diao-du)— 详细了解 Manager 的 addECU/addECUFile 接口和优先级分组逻辑 - 并行引擎:
[ParallelECUFlasher:基于 TaskPool 的多 ECU 并行刷写引擎](13-parallelecuflasher-ji-yu-taskpool-de-duo-ecu-bing-xing-shua-xie-yin-qing)— 深入 ecuReady、securityAccess、taskWork 的线程执行细节 - 诊断通信:
[MCDFileDownloader:基于 MCD3D 协议的 DoIP 文件下载与诊断通信](14-mcdfiledownloader-ji-yu-mcd3d-xie-yi-de-doip-wen-jian-xia-zai-yu-zhen-duan-tong-xin)— 了解 MCD3D 底层通信和文件传输流程 - 事件模型:
[事件驱动模型:刷写生命周期事件的发布与订阅机制](15-shi-jian-qu-dong-mo-xing-shua-xie-sheng-ming-zhou-qi-shi-jian-de-fa-bu-yu-ding-yue-ji-zhi)— 掌握事件系统如何驱动 ReportTransporter 和 ReportRecordCollector - 顺序模式:
[SequenceECUFlasher 与 SingleECUFlasher:顺序刷写与单 ECU 刷写模式](16-sequenceecuflasher-yu-singleecuflasher-shun-xu-shua-xie-yu-dan-ecu-shua-xie-mo-shi)— 对比顺序与并行模式的适用场景 - 文件下载器:
[BinFileDownloader 与 VbfFileDownloader:不同格式刷写文件下载器](18-binfiledownloader-yu-vbffiledownloader-bu-tong-ge-shi-shua-xie-wen-jian-xia-zai-qi)— 深入两种文件格式的下载实现 - VBF 解析:
[VBF 文件解析器:VBFHeader、VBFBlock 与 RSA 签名验证](17-vbf-wen-jian-jie-xi-qi-vbfheader-vbfblock-yu-rsa-qian-ming-yan-zheng)— 刷写前的文件结构化解析