蓝牙学习

使用 iOSDFULibrary 进行蓝牙 DFU升级(OTA

2019-07-08  本文已影响0人  怀可

现在公司用的蓝牙芯片是 NRF51 系列,DFU 升级(OTA 升级)可直接使用官方提供的 iOSDFULibrary。

准备

使用 cocoapods 安装

target 'YourAppTargetName' do
    use_frameworks!
    pod 'iOSDFULibrary'
end

安装后除了iOSDFULibrary 还有一个 ZIPFoundation。是iOSDFULibrary的一个依赖库,解压zip 包用的,我们不会直接使用。

使用前确认硬件同事发过来的空升包能正常使用,在 APP Store 下载 nRF Connect 操作,能升级成功,再看代码不迟。

空升步骤

  1. 确认手柄与系统已连接
  2. 向蓝牙设备发“开启升级模式”消息。此时手柄会主动断连。
  3. APP 收到蓝牙断开回调,APP 发起蓝牙连接请求,(此时连接的设备名变为会改变,需和硬件同事确认)
  4. APP 收到蓝牙连接成功回调,读本地空升包,调用 iOSDFULibrary与 dfuService 通信

空升代码

开始空升(空升步骤第3步),我这里建了一个单独的类 DFUHelper,遵守协议 DFUServiceDelegate, DFUProgressDelegate, LoggerDelegate。

func startDFU() {
    guard let filePath = Bundle.main.path(forResource: "你的空升包名字", ofType: "zip") else {
        return
    }
    
    guard let selectedFirmware = DFUFirmware(urlToZipFile: URL(fileURLWithPath: filePath)) else { return }

    let initiator = DFUServiceInitiator(centralManager: BlueToothHelper.centralManager, target: BlueToothHelper.peripheral)
    initiator.forceDfu = UserDefaults.standard.bool(forKey: "dfu_force_dfu")
    initiator.packetReceiptNotificationParameter = UInt16(UserDefaults.standard.integer(forKey: "dfu_number_of_packets"))
    initiator.logger = self
    initiator.delegate = self
    initiator.progressDelegate = self
    initiator.enableUnsafeExperimentalButtonlessServiceInSecureDfu = true
    dfuController = initiator.with(firmware: selectedFirmware).start()
}

协议回调

// 升级状态回调
func dfuStateDidChange(to state: DFUState) {
    switch state {
    case .completed:
        print("升级成功")
    default:
        break
    }
}

// 升级进度回调,范围 1-100
func dfuProgressDidChange(for part: Int, outOf totalParts: Int, to progress: Int, currentSpeedBytesPerSecond: Double, avgSpeedBytesPerSecond: Double) {
    DispatchQueue.main.async {
        // 回主线程更新 UI
    }
}

func dfuError(_ error: DFUError, didOccurWithMessage message: String) {
    print("⚠︎  dfuError: \(error), didOccurWithMessage: \(message)")
}

func logWith(_ level: LogLevel, message: String) {
    print("⚠︎  logWith   \(level), message: \(message)")
}
上一篇下一篇

猜你喜欢

热点阅读