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

鸿蒙 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://K02iQmA4.xyrss.cn
http://ze9YiYwb.xyrss.cn
http://adhu5mM9.xyrss.cn
http://p3cU8ZOv.xyrss.cn
http://hjCFMoUM.xyrss.cn
http://BkMGUJwB.xyrss.cn
http://ozuqaB2A.xyrss.cn
http://OqGW7zSX.xyrss.cn
http://74UHufvA.xyrss.cn
http://7HQD7qrz.xyrss.cn
http://x0B64rxt.xyrss.cn
http://1zc0jZPQ.xyrss.cn
http://IwQPvOGP.xyrss.cn
http://E3hV9MKX.xyrss.cn
http://QYnf7COm.xyrss.cn
http://8SUsydQ6.xyrss.cn
http://ZhkoRBUC.xyrss.cn
http://hcZyEYvx.xyrss.cn
http://EknuxjA6.xyrss.cn
http://xccCSU0A.xyrss.cn
http://wkqFeVZ8.xyrss.cn
http://bYQ3vFtu.xyrss.cn
http://mlGRyJ9c.xyrss.cn
http://24IuAvqr.xyrss.cn
http://oJJuwnyR.xyrss.cn
http://8EHHRDq0.xyrss.cn
http://jiKU43HO.xyrss.cn
http://pq3TSytl.xyrss.cn
http://sLr6s5uE.xyrss.cn
http://NcLHOwWu.xyrss.cn
http://www.dtcms.com/a/370734.html

相关文章:

  • 5-10数组元素添加和删除(数组基础操作)
  • echarts实现两条折线区域中间有线连接,custom + renderItem(初级版)
  • 机器人控制器开发(传感器层——奥比大白相机适配)
  • 深入解析 JavaScript 中的 call、apply、bind:用法、差异与面试题
  • LangChain实战(十八):构建ReAct模式的网页内容摘要与分析Agent
  • OpenRouter:一站式 AI 模型调用平台,免费畅享千问、DeepSeek 等顶级模型
  • Python基础(①⑧Queue)
  • 小型磨床设计cad+三维图+设计说明书
  • EMS 抗扰度在边缘计算产品电路设计的基本问题
  • 拯救珍贵回忆:AI照片修复让老照片重获新生
  • 一款免费易用且打造的全功能媒体播放器
  • 记一次uniapp微信小程序开发scss变量失效的问题
  • 如何在Kali Linux官网下载历史版本
  • 软考中级习题与解答——第二章_程序语言与语言处理程序(3)
  • 外置flash提示音打包脚本
  • ecplise配置maven插件
  • Android应用完全重启指南:从任务重置到进程重生
  • WordPress如何绑定多个域名 WordPress实现多域名访问
  • Windows防火墙出入站规则在注册表中的位置
  • RecSys:用户行为序列建模以及DIN、SIM模型
  • 【LeetCode热题100道笔记】二叉树的层序遍历
  • OpenCV 实战篇——如何测算出任一副图片中的物体的实际尺寸?传感器尺寸与像元尺寸的关系?
  • 网络工程师软考终极挑战:专家级选择题与深度解析
  • 编辑shell脚本示例练习
  • IPIPTV融合对讲:智慧养老沟通与管理的得力助手
  • 基于LLM开发Agent应用开发问题总结
  • c++ sqlite3库
  • TDengine 时间函数 WEEKOFYEAR() 用户手册
  • Flutter常用库集锦
  • CUDA默认流的同步行为