为了让CSR867x的开发更容易,现与思度科技联合推出CSR867x学习板【淘宝链接:思度科技CSR开发板】。

技术交流QQ群号:743434463
开发板会员QQ群号:725398389(凭订单号入群,赠PPT、项目源码、视频教程)
——————————正文分割线———————————–

#1. DFU简介

  • DFU全称是Device Firmware Upgrade,是一种通过USB升级设备程序的机制,能用来升级以下软件组件:

    • 固件协议栈
    • VM应用程序
    • VM文件系统内的其它文件(语音提示音、额外语言包)
    • PS Keys
  • DFU协议被USB实施者论坛标准化为一个设备类规范。CSR兼容这个规范,且包含加密检查
    • 在制造时设备烧录的程序有RSA公钥
    • DFU文件用RSA私钥加密,确保只有为此产品定制的DFU文件能被终端用户使用

#2. DFU升级过程

  • Loader是出厂时烧录进芯片的
  • PS Keys存储了系统的配置
  • Firmware是固件协议栈
  • VM文件系统包含了VM app和语音提示音

##2.1. 详细执行过程
这个章节列出了在使用DFU机制时的选择和限制:

  • loader不能被升级

    • 这使得DFU升级过程是安全的,loader总是存在且原封不动,因此在升级失败后DFU过程仍可重复
  • 固件协议栈可以被升级(但不是必须的)
    • 固件协议栈可以不包含在DFU文件里,这种情况下固件不会被更新。
    • 如果默认boot模式没有主机接口,必须包含固件协议栈(否则产品只有协议栈,没有VM,没有主机接口,因此不能工作)
  • 任何DFU文件内的PS Keys都可以被修改
  • VM文件系统可以被升级(但不是必须的)
    • 如果VM文件系统存在于DFU文件内,VM文件系统被替换成新的
    • 不能单独升级VM文件系统内的文件,文件必须是连续的且没有间隙

##2.2. DFU升级工具
DFU升级工具有两种:

  • DFUWizard:需要用户安装CSR DFU驱动才能开始DFU过程
  • HidDfu:不需要用户安装驱动,使用USB HID接口执行DFU

##2.3. PS Keys
PS Keys的类型有很多种:

  • 未保护固件(FW)和虚拟机(VM)Keys:

    • 这些Keys不需要被签名,但签名也不会有任何问题
  • 被保护FW Keys
    • 这些Keys被保存在loader内的FW公钥认证
  • 被保护VM Keys
    • 这些Keys被保存在被保护FW Keys内的VM公钥认证
  • 虚拟Keys,有着专门用途

##2.4. DFU事件序列
DFU事件序列如下:

  • 设备正常运行在独立模式
  • USB插入,设备被枚举成USB设备
  • 一个用户USB命令或按键序列切换到DFU模式(这导致用户在mode 0内reboot,用户接口在这个模式内必须可用)
  • DFUWizard命令设备切换到Loader模式,设备reboot且loader被激活(当使用HidDfu时不需要这个步骤)
  • DFU文件被下载到设备且由loader处理
  • 设备reboot回到mode 0(当使用HidDfu时不需要)
  • 设备reboot回到独立模式
  • 设备检测到到USB连接且枚举为一个USB设备

#3. 生成DFU文件
官方手册的步骤比较详细,但每次生成代码需要手动操作。我写了一个批处理文件,实现了编译、烧录、生成DFU、生成release文件一键操作。

##3.1. 设置CSR安装路径

:: set CSR install path
set dfutoolspath="C:\ADK4.0.0\tools\bin"
set adkpath="C:\ADK4.0.0"
set debugtransport=SPITRANS=USB SPIPORT=0
set adkversion=adk4.0.0

这里的debugtransport指向USB-SPI调试器,在执行批处理文件过程中,确保PC与编程器已经连接。

##3.2. 设置全局变量

:: set project path
set ReleasePath=released
set ReleaseVersion=0.0.13
set ReleasePackageName=BT%ReleaseVersion%
set ReleaseNoteName=ReleaseNote_BT%ReleaseVersion%set projectpath=parasol_v%ReleaseVersion%
set projectmakefile=Speaker.parasol_released
set projectname=speaker
set projectpsr1=sink_system_csr8670
set projectpsr2=Speaker_with_TWS_CNS10001v4
set projectpsr3=Music5_bt_%ReleaseVersion%
set dfupsrfw=example_DFU_fw_Music5_bt_%ReleaseVersion%
set dfupsrvm=example_DFU_vm_Music5_bt_%ReleaseVersion%

projectmakefile需要与工程的编译文件对应。

##3.3. 创建release文件夹

:: create package dir
rd /s /Q %ReleasePackageName%
mkdir %ReleasePackageName%
mkdir %ReleasePackageName%\"BT_Program file"
mkdir %ReleasePackageName%\"BT_Source code"
mkdir %ReleasePackageName%\"BT_Upgrade file"
  • 首先删除同名文件夹,再分别创建各文件夹
  • 第一个文件夹存工厂烧录文件
  • 第二个文件夹存源代码(如果库文件被修改了,也要包含在内)
  • 第三个文件夹存DFU文件

##3.4. 更新调试接口

:: update debug transport in XIP files
cscript //NoLogo //B xip_set_transport.vbs %adkpath%\apps\%projectpath%\%projectname%.xip "[%debugtransport%]"cscript //NoLogo //B xip_set_transport.vbs %adkpath%\kalimba\apps\a2dp_sink\sbc_decoder.xip "[%debugtransport%]"cscript //NoLogo //B xip_set_transport.vbs %adkpath%\kalimba\apps\a2dp_sink\aptx_decoder.xip "[%debugtransport%]"cscript //NoLogo //B xip_set_transport.vbs %adkpath%\kalimba\apps\a2dp_sink\aptx_acl_sprint_decoder.xip "[%debugtransport%]"
cscript //NoLogo //B xip_set_transport.vbs %adkpath%\kalimba\apps\a2dp_sink\aac_decoder.xip "[%debugtransport%]"set origpath=%cd%

DSP工程的调试接口需要设置,否则编译时会报错找不到调试器。

##3.5. 编译DSP工程

echo. *** compile DSP app ***
cd /D %adkpath%\kalimba\apps\a2dp_sink
call %adkpath%\xide\bin\xipbuild.exe -f sbc_decoder.xipcd /D %adkpath%\kalimba\apps\a2dp_sink
call %adkpath%\xide\bin\xipbuild.exe -f aptx_decoder.xipcd /D %adkpath%\kalimba\apps\a2dp_sink
call %adkpath%\xide\bin\xipbuild.exe -f aptx_acl_sprint_decoder.xipcd /D %adkpath%\kalimba\apps\a2dp_sink
call %adkpath%\xide\bin\xipbuild.exe -f aac_decoder.xip

每个VM工程包含一个主工程和多个DSP子工程。

##3.6. 复制psr文件

cd /D %origpath%
call %adkpath%\tools\bin\copyfile %adkpath%\apps\%projectpath%\configurations\%projectpsr3%.psr %ReleasePackageName%\BT_Upgrade file\%projectpsr3%.psr"

这里的psr3其实包含了三个部分:psr1、psr2、与项目有关的配置改动。

psr1和psr2是CSR默认的配置。

##3.7. 生成未加密的工厂烧录文件

cd /D %adkpath%\apps\%projectpath%
call %adkpath%\xide\bin\xipbuild.exe -f %projectname%.xipecho. *** erase board ***
call %adkpath%\tools\bin\BlueFlashCmd.exe -TRANS "%debugtransport%" eraseecho. *** delete the image directory before copying files into it ***
echo. *** this will also flash the unsigned image onto the board
echo. *** prevent voice file from delect ***call rmdir /S /Q headers_temp
call rmdir /S /Q prompts_temp
call rmdir /S /Q refname_temp
del /f /s /Q audio_prompt_config_temp.csrmkdir headers_temp
mkdir prompts_temp
mkdir refname_temp
xcopy /E image\headers headers_temp
xcopy /E image\prompts prompts_temp
xcopy /E image\refname refname_temp
copy /b image\audio_prompt_config.csr audio_prompt_config_temp.csrcall rmdir /S /Q image
mkdir imagexcopy /E headers_temp "image\headers\"
xcopy /E prompts_temp "image\prompts\"
xcopy /E refname_temp "image\refname\"
copy /b audio_prompt_config_temp.csr "image\audio_prompt_config.csr"
call rmdir /S /Q headers_temp
call rmdir /S /Q prompts_temp
call rmdir /S /Q refname_temp
del /f /s /Q audio_prompt_config_temp.csr%adkpath%\tools\bin\make -R BLUELAB=%adkpath%\tools -f %projectmakefile%.mak flashcd /D %origpath%echo. *** merge psr file to board ***
call %adkpath%\tools\bin\pscli.exe -TRANS "%debugtransport%" merge "%ReleasePackageName%\BT_Upgrade file\%projectpsr3%.psr"

这里完成了4件事:

  • 编译VM工程
  • 擦除目标板
  • 烧录VM文件系统到目标板
  • 烧录psr文件到目标板

在执行第3部之前,需要首先删除image文件夹。image文件夹的截图如下:

image文件夹由如下部分组成:

  • VM应用(vm.app)
  • 各个DSP工程的映像(aac_decoder等几个decoder)
  • 语音提示音(headers、prompts、refname)

headers文件夹内的文件数量与pskey中设定的语音提示音数量是对应的。

语音提示音文件夹是通过sink configuration tool生成的,然后通过编译工程来添加到最终生成的image.fs文件里。所以在删除image文件夹之前需要把相关内容缓存一下,并在生成image之前再次放回到image文件夹。

把image和psr一起烧录进目标板后,就可以读出完整的工厂烧录文件。

echo. *** cold reset ***
call %adkpath%\tools\bin\pscli.exe -TRANS "%debugtransport%" cold_resetecho. *** dump file from board ***
cd /D %origpath%\%ReleasePackageName%\"BT_Program file"
call %adkpath%\tools\bin\BlueFlashCmd.exe -TRANS "%debugtransport%" dump %projectpsr3%

##3.10. 压缩源码

echo. *** copy library file to BT_Source code ***
cd /D %origpath%
xcopy /E %adkversion% "%ReleasePackageName%\BT_Source code\BT_Source code\"echo. *** copy source file to BT_Source code ***
xcopy /E %adkpath%\apps\%projectpath% "%ReleasePackageName%\BT_Source code\BT_Source code\Parasol_TWS_Code\"echo. *** compress code ***
call "C:\Program Files\WinRAR\rar.exe" a -ep1 -o+ -ibck %ReleasePackageName%\"BT_Source code"\BT_SourceCode.rar "%ReleasePackageName%
\BT_Source code\BT_Source code"
rd /s /Q "%ReleasePackageName%\BT_Source code\BT_Source code\"

这里首先把有修改的库文件和源码一起拷贝到目标文件夹下,然后调用了WinRAR提供的压缩程序用来生成压缩文件。

##3.11. 生成已加密的image文件

echo. *** generate keys ***
cd /D %origpath%\dfu_key
copy /b keys.private.key %origpath%\%ReleasePackageName%\"BT_Upgrade file"\keys.private.key
copy /b keys.public.key %origpath%\%ReleasePackageName%\"BT_Upgrade file"\keys.public.keycd /D %origpath%\%ReleasePackageName%\"BT_Upgrade file"
:: call %dfutoolspath%\dfukeygenerate.exe -o keysecho. *** sign firmware ***
copy /b %adkpath%\firmware\assisted\unified\gordon\loader_unsigned.xdv loader_unsigned.xdvcopy /b %adkpath%\firmware\assisted\unified\gordon\loader_unsigned.xpv loader_unsigned.xpvcopy /b %adkpath%\firmware\assisted\unified\gordon\stack_unsigned.xdv stack_unsigned.xdvcopy /b %adkpath%\firmware\assisted\unified\gordon\stack_unsigned.xpv stack_unsigned.xpvcall %dfutoolspath%\dfukeyinsert -v -o loader_signed -l loader_unsigned.xdv -ks keys.public.keycall %dfutoolspath%\dfusign -v -o stack_signed -s stack_unsigned.xpv -ks keys.private.keyecho. *** copy image.fs to BT_Upgrade file ***
call %adkpath%\tools\bin\copyfile %adkpath%\apps\%projectpath%\image.fs app.fsecho. *** sign app ***
call %dfutoolspath%\dfukeyinsert -v -o image_signed -ps %projectpsr3%.psr -ka keys.public.keycall %dfutoolspath%\dfusign -v -o image_signed -h app.fs -ka keys.private.keyecho. *** build binary ***
call %adkpath%\tools\bin\vmbuilder -size 16064 merge.xpv stack_signed.xpv image_signed.fs

上述代码完成了如下几件事:

  • 生成密钥,这个密钥需要保存好,后续release DFU文件时需要用到
  • 加密固件,包括loader和stack
  • 加密VM app和psr,生成加密后的image文件

##3.12. 生成已加密的工厂烧录文件

echo. *** merge signed xpv file to board ***
call %adkpath%\tools\bin\BlueFlashCmd.exe -TRANS "%debugtransport%" erase
call %adkpath%\tools\bin\BlueFlashCmd.exe -TRANS "%debugtransport%" mergeecho. *** merge signed psr file to board ***
call %adkpath%\tools\bin\pscli.exe -TRANS "%debugtransport%" merge image_signed.psrecho. *** cold reset ***
call %adkpath%\tools\bin\pscli.exe -TRANS "%debugtransport%" cold_resetecho. *** dump signed file from board ***
cd /D %origpath%\%ReleasePackageName%\"BT_Program file"
call %adkpath%\tools\bin\BlueFlashCmd.exe -TRANS "%debugtransport%" dump %projectpsr3%_signed
  • 首先把已加密的image文件merge到目标板
  • 然后merge已加密的psr文件
  • 最后dump出已加密的工厂烧录文件

如果设备出厂时烧录的是已加密的烧录文件,后续DFU升级就可以更改被保护的PS Keys,否则只能更改未被保护的PS Keys。

##3.13. 生成DFU文件

echo. *** sign PSKEYs to be included in the DFU image ***
cd /D %origpath%\%ReleasePackageName%\"BT_Upgrade file"
copy %origpath%\%dfupsrvm%.psr app_vm.psr
copy %origpath%\%dfupsrfw%.psr app_fw.psr
call %dfutoolspath%\dfusign -v -o dfu_vm_signed -pa app_vm.psr -ka keys.private.keycall %dfutoolspath%\dfusign -v -o dfu_fw_signed -ps app_fw.psr -ks keys.private.keyecho. *** generate the DFU file ***
call %dfutoolspath%\dfubuild -v -pedantic -f %projectpsr3%.dfu -uv 0x0a12 -up 0x0001 -ui "ADK DFU" -s stack_signed.xpv -d stack_signed.xdv -h image_signed.fs -p3 . dfu_fw_signed.stack.psr dfu_vm_signed.app.psrecho. *** delete middle files ***
cd /D %origpath%\%ReleasePackageName%\"BT_Upgrade file"
del /f /s /Q dfu_fw_signed.stack.psr
del /f /s /Q dfu_vm_signed.app.psr
del /f /s /Q image_signed.fs
del /f /s /Q image_signed.psr
del /f /s /Q loader_signed.xdv
del /f /s /Q loader_unsigned.xdv
del /f /s /Q merge.xdv
del /f /s /Q stack_signed.xdv
del /f /s /Q stack_unsigned.xdv
del /f /s /Q loader_signed.xpv
del /f /s /Q loader_unsigned.xpv
del /f /s /Q merge.xpv
del /f /s /Q stack_signed.xpv
del /f /s /Q stack_unsigned.xpv

DFU文件由以下部分组成:

  • 已加密的stack
  • 已加密的image
  • 已加密的psr,包括vm和fw两部分

DFU文件中的psr会覆盖掉设备原有的psr。

##3.14. 打包release文件

echo. *** copy release note ***
copy %origpath%\%ReleaseNoteName%.xlsx %ReleaseNoteName%.xlsxecho. *** package all files ***
cd /D %origpath%
call "C:\Program Files\WinRAR\rar.exe" a -ep1 -o+ -ibck %ReleasePackageName%.rar %ReleasePackageName%

#4. 总结

  • DFUWizard只支持windows平台,别的平台需要另行开发。
  • loader最好要加密,且生成的密钥需要妥善保存。如果密钥丢失会导致后续DFU升级都不能成功,只能重新生成密钥并重新烧录loader。
  • 如果设备中的loader是未加密的,在跨ADK版本升级时(4.0.0升级到4.0.1),即使DFU升级过程完成了,新的程序也无法正常运行,原因就是被保护PS Keys没有升级成功,导致程序崩溃。
  • 如果启用了UART口,进入DFU模式时芯片会reboot失败,因为UART和USB口功能冲突。这种情况下,DFU模式需要从reboot mode 1启动,且确保在reboot mode 1内把host interface设成USB。
// --------MODE0--------------------------------------------------------
// BOOTMODE_KEY_LIST_0: Overwrite :
//                                HOST_INTRFACE  (1F9)
//                                USB PRODUCT ID (2bf)&04B0 = 01F9 02BF// BOOTMODE_KEY_TABLE_0+0: PSKEY_HOST_INTERFACE = USB
&04B8 = 0002
//  BOOTMODE_KEY_TABLE_0+1: USB PID = 0xffff (DFU)
&04B9 = ffff// PSKEY_INITIAL_BOOTMODE
&03cd = 0001
  • 如果PC识别不到设备,需要检查PS Keys是否符合以下设置:

    • PSKEY_USB_PIO_VBUS:开发板需要设置成VDD_CHG
    • PSKEY_USB_DFU_PRODUCT_ID=0xffff

CSR8670的DFU功能相关推荐

  1. NRF52832学习笔记(2)—— 添加DFU功能(基于SDK15.3)

    前言 SDK版本15.3 评估板:pca10040 在 uart 的例程中添加 DFU 功能,使用 s132 的协议栈,因为官方的 BootLoader 工程用的是s132的协议栈. 一.准备工作 在 ...

  2. STM32F4XX的DFU功能

    相当部分的 STM32芯片都带USB模块,有时我们会考虑利用STM32芯片的USB模块进行程序代码的下载或升级.USB协议中有专门针对设备固件升级的类协议,即可以通过DFU类协议进行产品固件的加载或更 ...

  3. CSR8670的UART功能的应用笔记

    为了让CSR867x的开发更容易,现与思度科技联合推出CSR867x学习板[淘宝链接:思度科技CSR开发板]. 技术交流QQ群号:743434463 开发板会员QQ群号:725398389(凭订单号入 ...

  4. SDK_17.1.0 nrf52832 串口透传(NUS)增加DFU功能OTA

    1.环境搭建以及需要的软件见这篇文章:Secure DFU环境搭建_Zoolybo的博客-CSDN博客 2.密钥以及加密算法的方法详见这篇文章:详解蓝牙空中升级(BLE OTA)原理与步骤_Zooly ...

  5. CSR8670 /CSR8675 升级文件DFU制作

    本文主要讲解在ADK_CSR867x.WIN4.4.0.17下, 验证CSR8670 sink程序的HID DFU功能, 用的工具为ADK_CSR867x.WIN.4.4.0.17\tools\bin ...

  6. QCC512x QCC302x GAIA OTA DFU 升级(earbud)

    QCC512x QCC302x GAIA OTA DFU 升级(earbud) 1.不能 DFU 升级的 filesystems: Read-Write (RW) FileSystem Device ...

  7. CSR8670项目实战:BlueCar蓝牙音频网关

    为了让CSR867x的开发更容易,现与思度科技联合推出CSR867x学习板[淘宝链接:思度科技CSR开发板]. 技术交流QQ群号:743434463 开发板会员QQ群号:725398389(凭订单号入 ...

  8. nRF52-Note(09)-添加DFU服务

    一.开发环境及工具 nRF5 SDK v15.3.0 IAR For ARM V7.80.4 / Keil uVision5(MDK-ARM) V5.33 此工程源码下载路径 : https://gi ...

  9. [NRF52] mesh DFU

    mesh DFU 升级过程: 完整流程: 以前nRF SDK DFU的实现是通过nRF51 Dongle配合主机nRF connect工具,且借助Secure DFU的后台式更新速率较快(见另一篇笔记 ...

最新文章

  1. mysql8 mac 忘记密码_mac下 MySql 8.0.15忘记密码重置密码
  2. Wintel物联网平台-Windows IoT新手入门指南
  3. 用 Python 控制你的鼠标和键盘,然后爱怎么玩怎么玩
  4. 图像坐标球面投影_坐标系统及投影概述
  5. python pysnmp使用
  6. (原创)C++11改进我们的程序之右值引用
  7. 蓝色起源起诉NASA,不服其将月球着陆器合同授予SpaceX
  8. java将数据写入csv文件,从csv文件中读取数据
  9. 网络工程师HCIE-RS-路由回馈问题(通俗易懂!)
  10. Python坦克大战(一):素材准备
  11. FFMPEG 常用命令一览
  12. 转:教人找电影的攻略
  13. 2023 年大淘宝 Web 端技术概览
  14. ue4子弹追踪与魔法子弹 逆向教程
  15. Spring Cloud Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)
  16. Generating Summaries with Topic Templates and Structured Convolutional Decoders笔记
  17. 基于Python技术的营养信息管理系统
  18. 如何解决数据关联查询
  19. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之四Git搭建下载实例!
  20. 219年北京移动校园卡200打一年究竟是不是骗局?到底有没有坑?

热门文章

  1. Qt/C++ 定时关机-给女票用的
  2. 《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》课后习题答案(带解析)(一)
  3. 尹成老师,关于链表的一些操作(C)
  4. 7-4 美女排名 (15分)
  5. echarts实现离线世界地图(国内)展示
  6. VR设计人体工程学建议
  7. php实现mkv视频播放,mkv文件用什么软件打开
  8. 2021实训笔记-day1
  9. 赛门铁克linux安装教程,SEP14在linux下安装失败……
  10. SSDT HOOK技术轻松让最新版冰刃、XueTr失效