Android dfu升级
android实现dfu升级
dfu全称是Device Firmware Upgrade,用于设备固件升级,本文主要介绍Android平台上dfu升级功能的实现,用于电视上。
前提
dfu-util源码下载地址:https://sourceforge.net/projects/dfu-util/
下载的源码,可以直接在Linux上编译执行,可参考文章:linux系统编译dfu。
因为我们实际是用在电视上,所以需要能够在arm平台上实现dfu升级。
需要用到libusb,libusb下载地址:https://sourceforge.net/projects/libusb/
有两种方式:1.app升级。将源码封装成接口,编译成.so库,再开发一个app,通过jni调用这个库,最终实现dfu升级。这种方式我没成功。
2.可执行程序升级。直接将源码编译成arm平台上的可执行程序,然后放到电视目录下,直接实现dfu升级。这个成功了。
app升级
1.新建一个ndk项目,将libusb里的库作为第三方调用的共享库,将dfu-util源码里src目录下的文件也作为第三方调用的源码,不需要main.cpp,然后自己需要写个头文件和实现类,按照main.cpp中的main函数功能,封装好queryDevice()(-l),detachDevice()(-e),upgradeFirmware()(-d)这三个接口,写好Android.mk和Application.mk,然后通过ndk编译成so库。再写个app,通过jni调用so库。
2.将需要升级的板子提供usb连接到电视上,查找电视的ip地址,
adb connect 电视ip:5555 连接结果可以直接看到
也可以直接在android studio中看到连接的设备,不需要usb线连接电视和电脑,调试很方便
3.因为连接的usb,app里需要添加需要动态授予读写的权限。
4.连接成功后,调试。在queryDevice的时候,报错了,libusb_init初始化成功,但是libusb_open的时候报错,返回值为-3,LIBUSB_ERROR_ACCESS 最终参考:https://blog.csdn.net/Zhangshiting/article/details/53781664解决(需重新下载libusb的版本,修改后,需重新编译libusb库),能够实现查询设备。
5.在detach的时候,又出了问题,libusb_claim_interface()这个函数返回-99,LIBUSB_ERROR_OTHER,刚开始看错单词,以为是权限的问题,找了半天都不知道是什么权限,最后才发现是other,也就是别的错误,但是传递的参数就是上一步查询的结果,然后真的不知道该怎么办,就停止用这种方法了。
可执行程序升级
1.和app升级的步骤一类似,只是不需要自己增加接口,dfu-util下的源码作为编译的源码,需要main.cpp,Android.mk除了文件路径修改,还需要修改编译的最终module为可执行的,如:
LOCAL_MODULE:=dfuutil
include $(BUILD_EXECUTABLE) //编译成可执行程序,windows上看,类型是文件
2、通过adb将dfuutil和libusb.so push到电视上,通过命令提示符
一般情况下,将dfuutil放到/system/bin目录下,将libusb.so 放到/system/lib64下,先检查下该目录下是否有这个so库,我查了下,没有这个库,但是system目录是只读的,无法操作。(通过adb shell可直接进入电脑目录,进行操作)
那就将文件放到/data/目录下,别的目录好像都会因为权限问题导致程序无法运行。
在/data/目录下新建一个dfu目录,然后把dfuutil和libusb.so都放到这个目录,执行**export LD_LIBRARY_PATH=.**指定libusb的目录,要下载的固件也push到这个目录,然后到该目录下执行:
./dfuutil -l //查询设备
./dfuutil -e //detach设备,进入dfu模式
./dfuutil -d -D 固件.bin //下载固件
最终升级成功了。
PS:看到这篇文章的朋友,如果你对我第一种方法遇到的问题有解决办法,欢迎留言相告!大家一起进步!