# GoodixBleDFU.Windows **Repository Path**: goodix-ble/GoodixBleDFU.Windows ## Basic Information - **Project Name**: GoodixBleDFU.Windows - **Description**: BLE DFU SDK for Windows, Supporting full series of GR5xxx SoC - **Primary Language**: C/C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-25 - **Last Updated**: 2025-07-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GR5xx DFU(Windows)集成方法说明 ## 简介 GRDFU固件升级工具、动态链接库文件GRDFU.dll以及导入库文件GRDFU.lib是由汇顶科技自主研发并提供,用于实现Windows平台下对GR5xx低功耗蓝牙芯片进行固件升级和资源文件写入,本文旨在帮助用户快速了解库文件集成步骤以及工具使用方法。 ## 库文件说明 ### 编译环境 - Windows SDK 版本: 10.0 - 平台工具集: Visual Studio 2019 (V142) - C++语言版本:ISO C++ 17标准 (std: c++ 17) - 系统架构 : X86(32位)、X64(64位) ### 文件结构 ``` GRDFU |-- include | |-- GRDataTypes.h //数据结构定义的头文件,如:错误码GRErrorCode、DFU进度监听接口GRDfuProgressListener等。 | |-- GRBluetoothScanner.h //蓝牙扫描的头文件,定义蓝牙扫描、停止扫描功能。 | |-- GREasyDfu.h //固件升级头文件,定义基于App bootloader方案的固件升级、资源写入等DFU功能。 |-- lib/x86/ | |-- debug | | |-- GRDFU.dll //32位Debug版DFU动态链接库文件。 | | |-- GRDFU.lib //链接32位Debug版GRDFU.dll的导入库,包含DLL中导出的函数和数据的引用信息。 | |-- release | | |-- GRDFU.dll //32位Release版DFU动态链接库文件 | | |-- GRDFU.lib //链接32位Release版GRDFU.dll的导入库,包含DLL中导出的函数和数据的引用信息。 |-- lib/x64/ | |-- debug | | |-- GRDFU.dll //64位Debug版DFU动态链接库文件。 | | |-- GRDFU.lib //链接64位Debug版GRDFU.dll的导入库,包含DLL中导出的函数和数据的引用信息。 | |-- release | | |-- GRDFU.dll //64位Release版DFU动态链接库文件 | | |-- GRDFU.lib //链接64位Release版GRDFU.dll的导入库,包含DLL中导出的函数和数据的引用信息。 |-- tool | |-- GRDFU_Vx.x.x.zip //基于GRDFU.dll开发的固件升级工具,解压后双击GRDFU.exe即可启动,使用方法参见“GRDFU工具使用” 章节。 |-- app | |-- qt //基于GRDFU.dll开发的QT版本固件升级工具GRDFU源码工程。 ``` ## 集成步骤 ### 环境要求 目标项目编译环境需在Windows SDK 8.1 及以上。 ### 库文件导入 用户需根据使用的开发环境和工具,自行导入GRDFU 库文件(位于GRDFU/lib下)和 头文件(位于GRDFU/include下)。 ### 代码集成 1. **导入头文件到源码文件中** ``` /* DFU Header files */ #include "GRBluetoothScanner.h" // 蓝牙扫描 #include "GREasyDfu.h" // DFU升级 ``` 2. **启动/停止扫描设备、监听扫描结果** ``` // 通过GRBluetoothScanner startScan()方法启动扫描。 // 参数1 this:完成DFU升级功能的主要实现类对象(本文中为MainWindow),该类需要实现GRScannerListener接口。 // 参数2 onlyScanUpgradable:指定是否只扫描可进行DFU升级的设备。当扫描到设备后,将通过onAdvertisementReceived()回调上报。 GRBluetoothScanner::getInstance().startScan(this, onlyScanUpgradable); // 停止扫描。 停止扫描后,将通过 onScanningStopped回调上报。 GRBluetoothScanner::getInstance().stopScan(); // 实现监听扫描 GRScannerListener void MainWindow::onAdvertisementReceived(GRScannedItem scannedItem) { // 当扫描到设备广播时,将触发调用该方法。注意此回调是在扫描线程中调用的,而非在发起扫描线程中。 } void MainWindow::onScanningStopped() { // 调用stopScan停止扫描后,将回调此方法。注意此回调是在扫描线程中调用的,而非在发起扫描线程中。 } ``` 3. **固件单区升级(Single-Bank)** ``` GREasyDfu *easyDfu = new GREasyDfu(); easyDfu->setListener(this); // this类需要实现GRDfuProgressListener easyDfu->setFastMode(isFastMode); easyDfu->setDfuRetryTimes(3); // 升级失败时,重试次数,若不设置,默认为3次。 if (isFastMode) { // 在快速升级速率模式下,若数据发送速度过快,导致设备端无法及时处理大批量数据而导致升级失败时,可以调用此方法控制数据包的发送频率。 // 参数 transIntervalMs:表示发送2个数据包之间的延时间隔,若不设置,默认为20 ms。 easyDfu->setFastModeTransmissionInterval(transIntervalMs); } // 启动DFU单区模式升级。启动后,将从GRDfuProgressListener的实现接口中收到升级状态信息。 // 参数1 bluetoothAddress:uint64_t整型值,而非字符串地址,可以直接从扫描对象GRScannedItem中获取。 // 参数2 firmwareFilePath:待升级固件的文件路径 easyDfu->startDfuWithSingleBankMode(scannedItem.bluetoothAddress, firmwareFilePath); ``` 4. **固件双区升级(Dual-Bank)** ``` GREasyDfu *easyDfu = new GREasyDfu(); easyDfu->setListener(this); // this类需要实现GRDfuProgressListener easyDfu->setFastMode(isFastMode); easyDfu->setDfuRetryTimes(3); // 升级失败时,重试次数,若不设置,默认为3次。 if (isFastMode) { // 在快速升级速率模式下,若数据发送速度过快,导致设备端无法及时处理大批量数据而导致升级失败时,可以调用此方法控制数据包的发送频率。 // 参数 transIntervalMs:表示发送2个数据包之间的延时间隔,若不设置,默认为20 ms。 easyDfu->setFastModeTransmissionInterval(transIntervalMs); } // 启动DFU双区模式升级。启动后,将从GRDfuProgressListener的实现接口中收到升级状态信息。 // 参数1 bluetoothAddress:uint64_t整型值,而非字符串地址,可以直接从扫描对象GRScannedItem中获取。 // 参数2 firmwareFilePath:待升级固件的文件路径 // 参数3 targetAddress:双区升级时的拷贝地址 easyDfu->startDfuWithDualBankMode(scannedItem.bluetoothAddress, firmwareFilePath, targetAddress); ``` 5. **资源文件升级** ``` GREasyDfu *easyDfu = new GREasyDfu(); easyDfu->setListener(this); // this类需要实现GRDfuProgressListener easyDfu->setFastMode(isFastMode); easyDfu->setDfuRetryTimes(3); // 升级失败时,重试次数,若不设置,默认为3次。 if (isFastMode) { // 在快速升级速率模式下,若数据发送速度过快,导致设备端无法及时处理大批量数据而导致升级失败时,可以调用此方法控制数据包的发送频率。 // 参数 transIntervalMs:表示发送2个数据包之间的延时间隔,若不设置,默认为20 ms。 easyDfu->setFastModeTransmissionInterval(transIntervalMs); } // 启动DFU资源升级。启动后,将从GRDfuProgressListener的实现接口中收到升级状态信息。 // 参数1 bluetoothAddress:uint64_t整型值,而非字符串地址,可以直接从扫描对象GRScannedItem中获取。 // 参数2 resourceFilePath:待升级资源文件的完整路径 // 参数3 targetAddress:资源升级的目标地址 // 参数4 isExternalFlash:指定是否升级到外部Flash。 easyDfu->startDfuResource(scannedItem.bluetoothAddress, resourceFilePath, targetAddress, isExternalFlash); ``` 4. **DFU 升级状态监听接口实现** ``` void MainWindow::onDfuStatusMessage(const std::string& message) { // 当DFU升级过程中的子步骤开始、结束或状态变化时,将回调此方法。注意此回调是在DFU线程中调用的,而非在发起升级的线程中。 // 参数message记录升级信息。 } void MainWindow::onDfuStarted(int32_t targetAddress) { // 当成功启动DFU升级时,将回调此方法。注意此回调是在DFU线程中调用的,而非在发起升级的线程中。 } void MainWindow::onDfuProgress(float progress, float speedInKBytes, const std::string &message) { // 当传输升级数据至设备时,将回调此方法。注意此回调是在DFU线程中调用的,而非在发起升级的线程中。 // 参数progress:记录当前已传输数据的进度百分比(0~100)。 // 参数speedInKBytes:记录传输速率,单位为KBytes。 // 参数message:记录升级信息。 } void MainWindow::onDfuCompleted(bool success) { // 当升级流程完成,将回调此方法。注意此回调是在DFU线程中调用的,而非在发起升级的线程中。 // 参数 success 为true时,表示升级成功,当为false时表示升级失败。 } void MainWindow::onDfuError(const std::string &message, GRErrorCode error) { // 当在DFU升级过程中出现错误时,将回调此方法,注意此回调是在DFU线程中调用的,而非在发起升级的线程中。 // 参数message:记录错误信息。 // 参数error:记录错误码。 // 注意出现错误时并不表示升级流程即将结束,程序会进行重试,直至重试次数达到上限或升级成功。 } ``` ## GRDFU工具使用 GRDFU是基于GRDFU.dll开发的固件升级工具(位于GRDFU/tool/GRDFU_Vx.x.x.zip),下面将简单介绍GRDFU工具的功能和操作使用。 ### 功能介绍 1. 基于GRDFU.dll 实现固件升级功能。 2. 支持固件单区/双区升级以及资源升级。 3. 升级速率模式支持普通模式和快速模式。 ### 使用说明 1. **扫描设备**:点击“Scan”启动设备扫描,默认扫描30秒后自动停止,用户也可以点击“Stop” 手动停止。默认只扫描可升级的设备, 如果用户需要扫描所有设备,需勾选 “All”后重新扫描。 2. **查询设备**:当列表中展示的设备太多时,可在“Search”左边的文本框中输入设备名称或蓝牙地址进行过滤查询。 3. **排序设备**:点击设备列表中每列的表头,可进行排序显示。例如,点击第3列的RSSI,即可按RSSI值从大到小排序,再次点击时,则反向排序。 4. **选择设备**:点击设备列表中的行,即可选中待升级设备。选中设备后,界面左下方“Upgrade”按钮的右边将显示设备名称。 5. **查看设备固件版本**:选中设备后,点击下方的“Read FW info”按钮,获取设备当前固件版本。(注:设备端需实现GATT服务为0X180A,特征为0X2A26的读操作。) 6. **选择升级模式**:点击“DFU Mode”下拉框,选择升级模式,包括:固件单区升级(Firmware(Single-Bank)、固件双区升级(Firmware(Dual-Bank)、资源升级(Resource)。 7. **选择文件**: 在“File”栏,点击“Select”选择待升级固件/资源文件。当升级模式为固件升级时,只能选择bin文件。 8. **配置地址**:当升级模式为“Firmware (Dual-Bank) ”时,需设置双区升级时固件临时存放地址(Dual Addreess),若未填写则从设备获取;当升级模式为“Resource”时,需设置资源待写入的目标地址(Resource Address)。 9. **选择外部Flash**:当升级模式为“Resource”时,若勾选“Ext Flash”,则表示将资源升级到外部Flash。 10. **选择升级速率模式**: 若勾选“Fast Mode”,则使用快速模式进行升级,否则使用普通模式。 11. **设置发送间隔**: 若已勾选“Fast Mode”,则需输入“Trans Tnterval(ms)”值以设置快速模式下数据包之间的发送间隔,从而控制数据包的发送速率。该参数值越大,发送间隔越长,发送速率越慢。当设备端无法及时处理GRDFU工具快速发送的升级数据时,可通过增大“Trans-Interval”值来减慢发送速率,从而确保升级成功。 12. **启动升级**: 升级配置完成后,可点击“Upgrade”启动升级流程。 ![GRDFU界面](./images/grdfu.png "GRDFU界面") ## 注意事项 1. 升级前,请确保待升级固件是有效的,并与待升级设备相匹配,否则将导致升级失败或设备无法运行。 2. 升级前,请确保设备端支持APP Bootloader DFU方案,否则将无法升级。 3. 升级时,请勿同时广播2个及以上相同蓝牙地址设备,否则可能出现连接或升级失败。 4. 进行双区升级或资源升级时,请确保输入的目标地址和所需的空间大小有效且可用,否则将导致升级失败或设备无法运行。 ## 常见问题 1. 在固件双区(Dual-Bank)升级模式下,GRDFU工具显示升级成功,但固件端并未升级成功并提示Error,是什么原因? 此问题通常是由于在双区升级时设置了错误的固件临时存放地址而引起的。请重新设置有效的地址,并确保预留的地址和空间大小均有效,否则仍可能出现写入失败、擦除失败等Flash操作问题。 2. 如何请求交换MTU? GRDFU工具和库文件GRDFU.dll均不支持请求交换MTU,需由固件端发起。 3. GRDFU工具 在FastMode升级时,在进度99%时等待很久后,出现 “ProgrammingDfu status: EndButFail, error: DataReceiveTimeout” 错误,是什么原因? 在快速升级速率模式下,由于数据发送太快,而设备端还未完成数据处理时,工具端会因超时(2分钟)而断开连接。为解决此问题,可通过以下方式降低发送速率: - 若使用GRDFU工具,则增大“Trans-Interval”值。 - 若使用GRDFU.dll,则调用GREasyDfu中的setFastModeTransmissionInterval方法以增大传输间隔值。 4. 扫描不到广播设备或总是连接不成功。 检查系统蓝牙功能是否正常,可进入Windows系统设置的“蓝牙和其它设备”页面,重新打开蓝牙后再试。 5. DFU 升级方案是如何设计的? 请参考[GR5xx固件升级开发指南](https://docs.goodix.com/zh/online/firmware_upgrade_bl)。