流程
固件更新的触发
- 通过OCPP协议,充电桩会收到来自中央系统的固件更新请求(UpdateFirmwareRequest)
- 请求中包含以下关键信息:
- location: 固件包的下载地址
- retrieveDate: 指定的下载时间
- retries: 重试次数(可选)
- retryInterval: 重试间隔(可选)
- signature: 固件包签名(签名固件更新时必需)
- signingCertificate: 签名证书(签名固件更新时必需)
请求处理流程
sequenceDiagram
participant CS as 中央系统
participant OCPP as OCPP模块
participant System as System模块
participant Security as Security模块
CS->>OCPP: UpdateFirmwareRequest
OCPP->>OCPP: 转换请求格式
OCPP->>System: call_update_firmware()
alt 签名固件更新
System->>Security: 验证证书
Security-->>System: 验证结果
end
System->>System: 创建临时文件
System->>System: 启动下载线程
System-->>OCPP: UpdateFirmwareResponse
OCPP-->>CS: 响应结果
loop 固件下载过程
System->>System: 下载固件包
System->>OCPP: 发布状态更新
OCPP->>CS: FirmwareStatusNotification
end
状态流转
固件更新过程中会经历以下状态:
stateDiagram-v2
[*] --> Idle
Idle --> DownloadScheduled: 收到更新请求
DownloadScheduled --> Downloading: 开始下载
Downloading --> Downloaded: 下载成功
Downloading --> DownloadFailed: 下载失败
Downloading --> DownloadPaused: 下载暂停
Downloaded --> Installing: 开始安装
Installing --> Installed: 安装成功
Installing --> InstallationFailed: 安装失败
Installing --> InstallVerificationFailed: 验证失败
Installing --> InstallRebooting: 重启安装
Installed --> [*]
模块交互
OCPP模块
- 负责与中央系统通信
- 处理固件更新请求
- 转换请求格式
- 发送状态通知
// OCPP模块中注册固件更新回调
this->charge_point->register_update_firmware_callback([this](const ocpp::v16::UpdateFirmwareRequest msg) {
types::system::FirmwareUpdateRequest firmware_update_request;
firmware_update_request.location = msg.location;
firmware_update_request.request_id = -1; // 标准更新
firmware_update_request.retrieve_timestamp.emplace(msg.retrieveDate.to_rfc3339());
if (msg.retries.has_value()) {
firmware_update_request.retries.emplace(msg.retries.value());
}
if (msg.retryInterval.has_value()) {
firmware_update_request.retry_interval_s.emplace(msg.retryInterval.value());
}
this->r_system->call_update_firmware(firmware_update_request);
});
// 签名固件更新回调
this->charge_point->register_signed_update_firmware_callback([this](ocpp::v16::SignedUpdateFirmwareRequest msg) {
types::system::FirmwareUpdateRequest firmware_update_request;
firmware_update_request.request_id = msg.requestId;
firmware_update_request.location = msg.firmware.location;
firmware_update_request.signature.emplace(msg.firmware.signature.get());
firmware_update_request.signing_certificate.emplace(msg.firmware.signingCertificate.get());
// ...其他参数设置
const auto system_response = this->r_system->call_update_firmware(firmware_update_request);
return conversions::to_ocpp_update_firmware_status_enum_type(system_response);
});状态通知和监控:
// OCPP模块订阅固件更新状态
r_system->subscribe_firmware_update_status([this](const types::system::FirmwareUpdateStatus status) {
this->charge_point->on_firmware_update_status_notification(
status.request_id,
conversions::to_ocpp_firmware_status_enum(status.firmware_update_status));
});System模块
- 负责实际的固件下载和安装
- 管理固件更新状态
- 执行固件安装脚本
- 处理重试逻辑
System模块执行固件更新:
通过request_id是否为-1判断更新类型是否为安全更新。
// System模块执行固件更新
types::system::UpdateFirmwareResponse
systemImpl::handle_update_firmware(types::system::FirmwareUpdateRequest& firmware_update_request) {
if (firmware_update_request.request_id == -1) {
return this->handle_standard_firmware_update(firmware_update_request);
} else {
return this->handle_signed_fimware_update(firmware_update_request);
}
}标准固件更新流程:
//标准固件更新流程
void systemImpl::standard_firmware_update(const types::system::FirmwareUpdateRequest& firmware_update_request) {
this->standard_firmware_update_running = true;
// 创建临时文件存储固件
const auto firmware_file_path = create_temp_file(fs::temp_directory_path(),
"firmware-" + date_time);
// 启动更新线程
this->update_firmware_thread = std::thread([this, firmware_update_request, firmware_file_path, constants]() {
const auto firmware_updater = this->scripts_path / FIRMWARE_UPDATER;
// 重试逻辑
int32_t retries = 0;
const auto total_retries = firmware_update_request.retries.value_or(this->mod->config.DefaultRetries);
while (firmware_status.firmware_update_status == types::system::FirmwareUpdateStatusEnum::DownloadFailed &&
retries <= total_retries) {
// 执行下载脚本
boost::process::child cmd(firmware_updater.string(),
boost::process::args(args),
boost::process::std_out > stream);
// 更新状态并通知
this->publish_firmware_update_status(firmware_status);
if (firmware_status.firmware_update_status == types::system::FirmwareUpdateStatusEnum::DownloadFailed) {
std::this_thread::sleep_for(std::chrono::seconds(retry_interval));
}
}
});
}固件安装流程:
void systemImpl::install_signed_firmware(const types::system::FirmwareUpdateRequest& firmware_update_request,
const fs::path& firmware_file_path) {
if (!this->firmware_installation_running) {
this->firmware_installation_running = true;
// 执行安装脚本
const auto firmware_installer = this->scripts_path / SIGNED_FIRMWARE_INSTALLER;
boost::process::child install_cmd(firmware_installer.string(),
boost::process::args(install_args),
boost::process::std_out > install_stream);
// 监控安装状态
while (std::getline(install_stream, temp)) {
firmware_status.firmware_update_status = types::system::string_to_firmware_update_status_enum(temp);
this->publish_firmware_update_status(firmware_status);
}
}
}Security模块
- 验证固件签名
- 管理证书
- 处理OCSP请求
签名固件校验流程(具体流程):
void systemImpl::download_signed_firmware(const types::system::FirmwareUpdateRequest& firmware_update_request) {
// 验证签名证书
if (!firmware_update_request.signing_certificate.has_value()) {
EVLOG_warning << "Signing certificate is missing in FirmwareUpdateRequest";
this->publish_firmware_update_status(
{types::system::FirmwareUpdateStatusEnum::DownloadFailed, firmware_update_request.request_id});
return;
}
// 处理并发下载
if (this->firmware_download_running) {
this->interrupt_firmware_download.exchange(true);
std::unique_lock<std::mutex> lk(this->firmware_update_mutex);
this->firmware_update_cv.wait(lk, [this]() { return !this->firmware_download_running; });
}
// 下载和验证过程
while (firmware_status.firmware_update_status == types::system::FirmwareUpdateStatusEnum::DownloadFailed &&
retries <= total_retries && !this->interrupt_firmware_download) {
// 执行下载和验证
boost::process::child download_cmd(firmware_downloader.string(),
boost::process::args(download_args),
boost::process::std_out > download_stream);
// 更新状态
this->publish_firmware_update_status(firmware_status);
}
// 如果验证成功,初始化安装
if (firmware_status.firmware_update_status == types::system::FirmwareUpdateStatusEnum::SignatureVerified) {
this->initialize_firmware_installation(firmware_update_request, firmware_file_path);
}
}// Security模块验证证书
ocpp::CertificateValidationResult verify_certificate(const std::string& certificate_chain,
const ocpp::LeafCertificateType& certificate_type);安全机制
- 签名验证:对签名固件进行验证
- 证书管理:维护和验证证书链
- 状态监控:全程监控更新状态
- 失败处理:包含重试机制和错误恢复
关键配置
- DefaultRetries:默认重试次数
- DefaultRetryInterval:重试间隔
- ResetDelay:重置延迟
错误处理
- 下载失败:自动重试
- 验证失败:终止更新
- 安装失败:回滚或保持当前版本
- 网络问题:重试机制
完成流程
- 下载完成后验证
- 等待所有连接器空闲
- 执行安装
- 必要时重启设备
- 向中央系统报告最终状态
这个固件更新流程展示了EVerest项目中模块间的紧密协作,确保了固件更新过程的可靠性和安全性。整个过程是异步的,通过状态机和事件通知机制来管理,同时提供了完善的错误处理和恢复机制。