关于DFU uboot 内核kernel and 开源代码配置
• DFU 实现原理
• linux 内核配置
• Uboot 相关配置
• DFU模式以及DFU-util 的使用
USB Device Firmware Update (DFU)
DFU 实现原理
dfu 功能分为两个模式: runtime 模式与 dfu 模式
runtime 模式:
正常工作状态,此时需要host设备发送detach命令使设备转换成dfu模式dfu 模式
升级状态,host设备可以读写相应分区的数据来升级设备
dfu 具体工作流程如下:
host设备给device设备发送准备升级固件命令device 在接收到命令时会卸载所有已经加载的驱动,并切换到DFU 模式host 给device发起usb resetdevice 发送DFU 模式下的描述符,进行重新枚举识别host 给设备发送需要升级的固件host 收到设备端数据处理成功的信息,给device发送转换模式的命令device 重新切换到 runtime 模式host 发起usb reset,并重新识别device设备
DFU模式与runtime模式的客制化流程:
device 正常启动到linux,配置相关的usb device驱动使设备处于runtime模式当用户需要升级firmware时,需要通过host端软件发送runtime模式detach命令(DFU-util -e)当device 接收到detach命令,会通过fw_setenv工具配置uboot环境变量enter_dfu_mode为1,并重启device 重启进入uboot过程中会读取enter_dfu_mode变量的值,当为1时,执行相应的dfu命令(例dfu 0 ram 0)
进入dfu模式并等待升级用户通过DFU-util工具发送firmware 到对应配置分区device 收到数据包并写入相应配置分区当升级完毕,用户使用DFU-util工具重启devicedevice 收到重启命令,配置环境变量enter_dfu_mode为0,并重启进入linux,配置模式为runtime
用户配置dfu流程:编译生成fw_setenv,以便支持linux下配置uboot环境变量
i. 使用uboot编译生成fw_setenv,并拷贝到linux 文件系统中的/etc目录
make env; ln -sf fw_printenv fw_setenv
ii. 配置fw_env.config,并拷贝到linux 文件系统中/etc目录linux的配置以支持usbcam以及dfuuboot的配置以支持dfu功能设置uboot环境变量
i. 分区表变量 dfu_alt_info
ii. 缓存大小配置 dfu_bufsiz
linux 内核配置
需要在配置完webcam的基础上增加配置,具体配置方法参考:usbcam 配置
在linux kernl目录执行:make menuconfig ,并找到对应的配置:
-> Device Drivers
-> USB support
-> USB Gadget Support
-> USB Gadget Drivers
-> USB Webcam Gadget
-> Include configuration with (DFU)
编译完成会在linux/modules 目录生成对应的驱动:usb_f_dfu.ko
在装载阶段需要在 g_webcam.ko 后面增加参数:insmod g_webcam.ko dfu_function_enable=1
编译完成会在linux/modules 目录生成对应的驱动:usb_f_dfu.ko
在装载阶段需要在 g_webcam.ko 后面增加参数:insmod g_webcam.ko dfu_function_enable=1
Uboot 相关配置
需要在基础配置上添加相应的配置,可以在uboot目录执行:./list_config.sh 查看相应配置
在uboot 目录执行:make menuconfig , 并找到对应配置:
首先配置出uboot cmdline下 dfu 命令:
-> Command line interface
-> USB commands
-> dfu
-> Device Drivers
-> DFU support
-> Enable USB DFU gadget
添加RAM支持:
-> Device Drivers
-> DFU support
-> RAM back end for DFU
添加SPI NorFlash支持:
-> Device Drivers
-> DFU support
-> SPI flash back end for DFU
添加NAND Flash支持:
-> Device Drivers
-> DFU support
-> NAND back end for DFU
DFU模式以及DFU-util 的使用
Uboot 配置环境变量:
dfu_bufsiz
用户缓存用户数据的buff大小, 需要32 byte对齐(cacheline)
setenv dfu_bufsiz 0x320000
dfu_alt_info
用于配置分区的变量, host仅支持已经配置的分区,可以使用DFU-util 烧写相应分区:
i. 配置Dram:dfu_alt_info=name ram offset size
例:
配置一个RAM分区:setenv dfu_alt_info "block ram 0x21000000 0x100000"
配置两个RAM分区:setenv dfu_alt_info "block ram 0x21000000 0x100000\;block2 ram 0x22000000 0x100000"
ii. 配置Nor Flash:dfu_alt_info=name raw offset size
例:
配置两个Nor分区:setenv dfu_alt_info "rootfs raw 0x00250000 0x00400000\;IPL raw 0x00000000 0x00010000"
iii. 配置Nand Flash
配置Nand普通分区:
方式一:dfu_alt_info=name raw offset len
例:setenv dfu_alt_info "IPL0 raw 0x00140000 0x000c0000;IPL_CUST0 raw 0x00200000 0x00060000"
方式二:dfu_alt_info=name part nandNum partNum
例:setenv dfu_alt_info "IPL0 part 0 1;IPL_CUST0 part 0 2"
可以通过mtdparts查找对应分区号:注意实际分区号需加1,譬如IPL0分区号为0, 实际传入参数则为1
SigmaStar # mtdparts
device nand0
#: name size offset mask_flags
0: IPL0 0x000c0000 0x00140000 0
1: IPL_CUST0 0x00060000 0x00200000 0
2: IPL_CUST1 0x00060000 0x00260000 0
3: UBOOT0 0x00060000 0x002c0000 0
4: UBOOT1 0x00060000 0x00320000 0
5: ENV0 0x00040000 0x00380000 0
6: KERNEL 0x00500000 0x003c0000 0
7: RECOVERY 0x00500000 0x008c0000 0
8: rootfs 0x00600000 0x00dc0000 0
9: UBI 0x06c40000 0x013c0000 0
配置Nand UBI分区:
方式一:dfu_alt_info=name partubi nandNum partNum
例:setenv dfu_alt_info "UBI partubi 0 10"
注意: 该方式无法区分UBI分区下的具体volume,要求烧写的firmware包含ubi分区表信息?
方式二:dfu_alt_info=name partubi-e part volume
例:setenv dfu_alt_info miservice partubi-e UBI miservice
注意:该方式为新增方式,非uboot原生:part指代mtd具体分区名,volume为ubi分区下的volume
enter_dfu_mode
device设备转换模式时自动配置,当值为1时,系统重启进入uboot dfu模式
0->1: runtime--->dfu
1->0: dfu--->runtime
注:
1. 在uboot命令行可以执行如下命令设置环境变量: setenv 变量名 变量值
在修改完环境变量需要使用命令进行保存:saveenv
2. linux 配置需要有fw_setenv工具,该工具由uboot编译获得,可以通过fw_env.config配置分区信息,
可将工具放置到以下目录"/bin", "/usr/bin", "/config", "/sbin", "/customer", "/etc"。
fw_env.config 文件默认存放到/etc目录。
Uboot执行DFU程序使用帮助:Usage:dfu
device firmware upgrade via
on device
[list] - list available alt settings
目前uboot仅支持一个interface,需要从ram,nor flash, nand flash, mmc中选择一个:
启动 ram 0 支持:
dfu 0 ram 0
启动 nor flash 0 支持:
dfu 0 sf 0:0
启动 nand flash 0 支持:
dfu 0 nand 0
dfu的执行时机:在uboot启动阶段,程序会读取enter_dfu_mode环境变量,当为1时,uboot会执行相应dfu命令:见update_dfu(common/main.c)也可以在uboot命令行执行命令进入。DFU-util DFU-util 是一个host端开源软件,可以对支持dfu功能的设备进行升级:dfu-utilDFU-Util 帮助手册:Usage: dfu-util [options] …-h --help Print this help message-V --version Print the version number-v --verbose Print verbose debug statements-l --list List the currently attached DFU capable USB devices-e --detach Detach the currently attached DFU capable USB devices-d --device vendor:product Specify Vendor/Product ID of DFU device-p --path bus-port. … .port Specify path to DFU device-c --cfg config_nr Specify the Configuration of DFU device-i --intf intf_nr Specify the DFU Interface number-a --alt alt Specify the Altsetting of the DFU Interface
by name or by number
-t --transfer-size Specify the number of bytes per USB Transfer-U --upload file Read firmware from device into -D --download file Write firmware from into device-R --reset Issue USB Reset signalling once we’re finished
-s --dfuse-address address ST DfuSe mode, specify target address for
raw file download or upload. Not applicable for
DfuSe file (.dfu) downloads
命令事例:
让设备重启到DFU模式:
DFU-Util -e
下载bin档案到对应配置分区并重启到runtime模式:
DFU-Util -R -D Image.bin --alt 0
DFU 版本号获取方法通过USB interface string 来获取版本号:device配置:insmod f_dfu.ko version_file=path (默认/customer/version_info)将版本信息放入文件host获取方法:DFU-util -l
参考: usb dfu 官方文档