当前位置: 首页 > backend >正文

鸿蒙 BLE 蓝牙智能设备固件升级之DFU升级方式(Nordic芯片)

前言:近期接入 DFU 的 OTA 升级,虽然 OpenHarmony 上面有第三方库,但是按照步骤导入三方库,并不能实现 OTA 升级,存在卡死问题,升级无响应等一系列问题,这个时候呢,我自己找到源码,进行了修改,下面是我修改后的工具类和遇到的问题点。

一:问题
(1)开始升级,crc 校验不通过

解码压缩包,发送 op code3 的时候,包校验不通过,直接卡死在 crc 校验不通过,这个是因为这个地方设置的有问题,在 writeInitData 里面的 writeInitPacket ,把写入方式修改为 await this.mGatt.writeCharacteristicValue(characteristic, ble.GattWriteType.WRITE_NO_RESPONSE);

(2)写入包的时候,由于写入过快,会导致丢包,固件接收到的包总数有问题,会导致升级失败

只需要在 BaseCustomDfuImpl 的 onCharacteristicWrite 里面添加发送包的延迟操作。

二:工具类

import { DfuProgressListener, DfuServiceInitiator, DfuServiceListenerHelper } from "ohos_dfu_library"

import { DfuEvent } from "./DfuEvent"

/**

* dfu 升级管理类

*/

export class DfuController{

private static instance : DfuController

private static eventListener: ((event: DfuEvent) => void) | null = null

public static getInstance() : DfuController{

if(!DfuController.instance){

DfuController.instance = new DfuController()

}

return DfuController.instance

}

public static setEventListener(listener: (event: DfuEvent) => void) {

DfuController.eventListener = listener

}

private static sendEvent(event: DfuEvent) {

console.log("DFU Event:", event)

if (DfuController.eventListener) {

DfuController.eventListener(event)

}

}

private listener: ProgressListener = new ProgressListener()

constructor() {

DfuServiceListenerHelper.registerProgressListener(this.listener)

}

static pageName : string = ""

public static SendMessage(msg:string){

if(!Boolean(DfuController.pageName)) return

console.log('sophie','---SendMessage---'+msg)

}

public startDFU(pageName:string, address:string, url: string){

DfuController.pageName = pageName

console.log('sophie','---startDFU---'+pageName+'===='+url)

new DfuServiceInitiator(address).setZipUri(url)

.setDeviceName(pageName)

.setKeepBond(true)

.setForceDfu(false)

.setPrepareDataObjectDelay(400)

.setForeground(false)

.start()

}

//给 ProgressListener

public static notify(event: DfuEvent) {

DfuController.sendEvent(event)

}

}

class ProgressListener implements DfuProgressListener {

progressInt: number = 0

dispose(): ESObject {

console.error("Dispose called")

return {}

}

onDeviceConnecting(address: string): ESObject {

DfuController.notify({ type: 'connecting', address })

return {}

}

onDeviceConnected(address: string): ESObject {

DfuController.notify({ type: 'connected', address })

return {}

}

onDfuProcessStarting(address: string): ESObject {

DfuController.notify({ type: 'dfu_starting', address })

return {}

}

onDfuProcessStarted(address: string): ESObject {

this.progressInt = 0

DfuController.notify({ type: 'dfu_started', address })

return {}

}

onEnablingDfuMode(address: string): ESObject {

DfuController.notify({ type: 'onEnablingDfuMode', address})

return {}

}

onProgressChanged(address: string, percent: number): ESObject {

const intPercent = Math.floor(percent)

if (intPercent > this.progressInt && intPercent < 100) {

this.progressInt = intPercent

DfuController.notify({ type: 'progress', value: this.progressInt })

} else if (intPercent >= 100) {

DfuController.notify({ type: 'completed', address })

}

return {}

}

onFirmwareValidating(address: string): ESObject {

DfuController.notify({ type: 'onFirmwareValidating', address })

return {}

}

onDeviceDisconnecting(address: string): ESObject {

DfuController.notify({ type: 'onDeviceDisconnecting',address })

return {}

}

onDeviceDisconnected(address: string): ESObject {

DfuController.notify({ type: 'onDeviceDisconnected', address })

return {}

}

onDfuCompleted(address: string): ESObject {

DfuController.notify({ type: 'completed', address })

return {}

}

onDfuAborted(address: string): ESObject {

DfuController.notify({ type: 'aborted', address })

return {}

}

onError(address: string, error: number, errorType: number, message: string): ESObject {

DfuController.notify({ type: 'error', address, message })

console.error("DFU Error:", message)

return {}

}

}

文件二:

interface GeneratedTypeLiteralInterface_1 {

type: 'connecting';

address: string;

}

interface GeneratedTypeLiteralInterface_2 {

type: 'connected';

address: string;

}

interface GeneratedTypeLiteralInterface_3 {

type: 'dfu_starting';

address: string;

}

interface GeneratedTypeLiteralInterface_4 {

type: 'dfu_started';

address: string;

}

interface GeneratedTypeLiteralInterface_5 {

type: 'progress';

value: number;

}

interface GeneratedTypeLiteralInterface_6 {

type: 'completed';

address: string;

}

interface GeneratedTypeLiteralInterface_7 {

type: 'aborted';

address: string;

}

interface GeneratedTypeLiteralInterface_8 {

type: 'error';

address: string;

message: string;

}

interface GeneratedTypeLiteralInterface_9 {

type: 'onEnablingDfuMode';

address: string;

}

interface GeneratedTypeLiteralInterface_10 {

type: 'onFirmwareValidating';

address: string;

}

interface GeneratedTypeLiteralInterface_11 {

type: 'onDeviceDisconnecting';

address: string;

}

interface GeneratedTypeLiteralInterface_12 {

type: 'onDeviceDisconnected';

address: string;

}

//外部调用

export type DfuEvent =

| GeneratedTypeLiteralInterface_1

| GeneratedTypeLiteralInterface_2

| GeneratedTypeLiteralInterface_3

| GeneratedTypeLiteralInterface_4

| GeneratedTypeLiteralInterface_5

| GeneratedTypeLiteralInterface_6

| GeneratedTypeLiteralInterface_7

| GeneratedTypeLiteralInterface_8

| GeneratedTypeLiteralInterface_9

| GeneratedTypeLiteralInterface_10

| GeneratedTypeLiteralInterface_11

| GeneratedTypeLiteralInterface_12

使用方法:

1.监听方法

DfuController.setEventListener((event: DfuEvent) => {switch (event.type) {case 'progress':console.log(`升级进度:${event.value}%`)breakcase 'completed':this.isSuccessOta = trueconsole.log(`升级完成!设备地址:${event.address}`)breakcase 'aborted':console.warn(`升级被中止,设备:${event.address}`)breakcase 'error':console.error(`升级失败: ${event.message} (设备: ${event.address})`)breakcase 'dfu_starting':console.log(`状态:${event.type} 设备:${event.address}`)break}
})

2.开始升级

DfuController.getInstance().startDFU(this.connectedDeviceInfo._currentDevice.mDeviceName, this.mac, filePath)

下面是我上传的全部升级库源码

http://www.xdnf.cn/news/20288.html

相关文章:

  • macbook intel 打开cursor会闪退
  • MySQL集群高可用架构(MHA高可用架构)
  • Process Explorer进阶(第三章3.3):深入理解进程详情
  • [Windows] AdGuard.v7.21.5089.0 中文直装电脑版
  • cds序列转换为pepperl脚本详细解读及使用
  • Python多线程编程全面指南
  • web自动化测试
  • Elasticsearch优化从入门到精通
  • 线代:排列与逆序
  • 从机器学习的角度实现 excel 中趋势线:揭秘梯度下降过程
  • PageHelper的使用及底层原理
  • WordPress如何绑定多个域名 WordPress实现多域名访问
  • 新的打卡方式
  • GPIO介绍
  • java接口和抽象类有何区别
  • ICPC 2023 Nanjing R L 题 Elevator
  • 用Android studio运行海外极光推送engagelab安卓的SDK打apk安装包
  • Ribbon和LoadBalance-负载均衡
  • 从Java全栈到前端框架:一次真实面试的深度复盘
  • 验证平台中所有的组件应该派生自UVM中的类
  • 设计艺术~缓存结构设计
  • 【Go项目基建】GORM框架实现SQL校验拦截器(完整源码+详解)
  • C++和OpenGL实现3D游戏编程【连载30】——文字的多行显示
  • MySQL集群——主从复制进阶
  • 2025年上海市星光计划第十一届职业院校技能大赛高职组“信息安全管理与评估”赛项交换部分前6题详解(仅供参考)
  • FlashAttention:突破Transformer内存瓶颈的IO感知革命
  • Web漏洞挖掘篇(二)—信息收集
  • 浪潮CD1000-移动云电脑-RK3528芯片-2+32G-安卓9-2种开启ADB ROOT刷机教程方法
  • Chat with RTX-NVIDIA推出的本地AI聊天机器人
  • .NET Core 应用部署深度解析:从 IIS 到 Docker+Kestrel 的迁移与性能优化实战