Android STB 高效调试技巧

  在开发机顶盒ROM时,有一些高效的开发技巧,可以让开发工作效率大大提升,本篇文章基于Android4.4.2系统,简单介绍下一些常见的高效调试方法。

一、编译

  先说编译,是因为Android系统开发和Android应用开发有个明显不同的地方:完整ROM编译的时间会比较长,可能会达到一个小时以上,所以要谨慎全编版本

1.1 版本全编

  先简单说下全编译版本,此处就以Hi3798MV300为例介绍,全编ROM的过程分为3个步骤:
   1>source build/envsetup.sh
     该步骤其实是调用了build/envsetup.sh脚本,该脚本的作用是初始化编译环境,并引入一些辅助的Shell函数,如mm、mmm等。
   2>lunch Hi3798MV300H-eng
     该步骤是调用了lunch函数,这个函数后面的参数包含两部分:硬件类型和版本类型。
   3>make bigfish -j 2>&1 | tee log_Hi3798MV300H.txt
     此时开始真正编译,make bigfish是编译版本的命令;2>&1是将将标准错误重定向到标准输出;tee log_Hi3798MV300H.txt是从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。简单来说,该命令的作用是:开始编译版本,并且将编译日志保存到系统代码根目录下的log_Hi3798MV300H.txt文件。

1.2 模块单编

  说完了全编,接下来就要说单编某个模块。要单编模块,需要先执行source build/envsetup.sh和lunch Hi3798MV300H-eng命令,然后再执行单编命令。经常单编的模块如下:
   1>apk
     在packages/app/ApkName目录,执行mm -B即可。编出来的 Apk 一般在out/target/product/Hi3798MV300H/system/app目录。如在packages/app/Bluetooth目录下执行mm -B,则编出来的apk是out/target/product/Hi3798MV300H/system/app/Bluetooth.apk。
     但也有特殊情况,如在packages/app/Settings目录执行mm -B,则编出来的apk是out/target/product/Hi3798MV300H/system/priv-app目录下。
    关于system/priv-app和system/app的区别,可以简单理解为system/priv-app目录下的系统应用可以获取的权限更高一些。
   2>jar
     此处指的是修改framework代码,单编命令也是mm -B和mmm,常见的单编命令执行目录及其对应的jar如下:

目录jar
frameworks/base/servicesservices.jar
frameworks/base/policyandroid.policy.jar
frameworks/baseframework.jar

   3>so
     在调试播放器、HDMI等涉及到较底层代码时,常常会编译出so文件,如在device/hisilicon/bigfish/frameworks/hidisplaymanager/hal执行mm -B,会生成out/target/product/Hi3798MV300H/system/lib/hw/hidisplay.bigfish.so文件。
   4>bin
     在frameworks/base/cmds/bootanimation目录执行mm -B,会生成out/target/product/Hi3798MV300H/system/bin/bootanimation文件;在external/dhcpcd执行mm -B,会生成out/target/product/Hi3798MV300H/system/bin/dhcpcd文件。

1.3 芯片特有单编模块

  除了这些公共的可以单编的模块,在不同的芯片平台,还有一些特殊的可以单编的模块,如在Amlogic905上,就有以下模块可以单编:

1.3.1 Uboot

  即Amlogic的bootloader,此处以gxlx_p261.dts配置为例,编译uboot文件方式如下:
   1、配置编译环境
     export PATH=sdk路径/toolchain/gcc-arm-none-eabi-6-2017-q2-update/bin/:$PATH
    2、修改makefile脚本

diff --git a/uboot/Makefile b/uboot/Makefile
index 641b28c..551c757 100755
--- a/uboot/Makefile
+++ b/uboot/Makefile
@@ -246,7 +246,7 @@ ifeq ($(HOSTARCH),$(ARCH))
 CROSS_COMPILE ?=
 endif
 
-export CROSS_COMPILE=/opt/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-
+export CROSS_COMPILE=sdk路径/toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin/aarch64-none-elf-
 
 KCONFIG_CONFIG ?= .config

    3、在sdk/uboot目录执行: ./mk gxl_p211_v1
    生成的uboot文件为:uboot/fip/gxl目录下的u-boot.bin、u-boot.bin.sd.bin、u-boot.bin.usb.bl2和u-boot.bin.usb.tpl。

1.3.2 boot.img&dt.img

   编译的命令为:make bootimage,此命令会同时生成boot.img和dt.img。

二、调试

  编译简单介绍完了,就要说调试了,机顶盒ROM的调试方式比较多样,就先接着第一章节,介绍一下上面的问题怎么替换。

2.1 文件替换

2.1.1 常规文件替换

  第一章节编出来的文件有apk、so、bin、jar等,替换到out目录下对应的机顶盒路径中即可。这句话可能有点不好理解,例子如下:

源码目录机顶盒中路径
out/target/product/Hi3798MV300H/system/bin/dhcpcdsystem/bin/dhcpcd
out/target/product/Hi3798MV300H/system/framework/android.policy.jarsystem/framework/android.policy.jar
out/target/product/Hi3798MV300H/system/lib/hw/hidisplay.bigfish.sosystem/lib/hw/hidisplay.bigfish.so
out/target/product/Hi3798MV300H/system/app/BluetoothSet.apksystem/app/BluetoothSet.apk

  替换文件时,除了apk、so、jar之外,别的(还有如:20-dns.conf、bootAnimation.zip等)都要保持替换前后权限一致。查看文件权限的命令是"ll filename",文件权限为"r:4 w:2 x:1 ",常见的权限如下:

    -rw------- (600)      只有拥有者有读写权限。
    -rw-r--r-- (644)      只有拥有者有读写权限;而属组用户和其他用户只有读权限。
    -rwx------ (700)      只有拥有者有读、写、执行权限。
    -rwxr-xr-x (755)      拥有者有读、写、执行权限;而属组用户和其他用户只有读、执行权限。
    -rwx--x--x (711)      拥有者有读、写、执行权限;而属组用户和其他用户只有执行权限。
    -rw-rw-rw- (666)      所有用户都有文件读、写权限。
    -rwxrwxrwx (777)      所有用户都有读、写、执行权限。

2.1.2 特殊文件替换

  特殊的文件,可简单理解为不能直接替换到机顶盒中的文件,比如1.3章节中编出的文件,替换方式如下(usb_disk代表U盘挂载到终端后的路径):
   1>boot.img
    cat usb_disk/boot.img > /dev/block/boot
   2>uboot
    cat usb_disk/u-boot.bin.sd.bin > /dev/block/bootloader

2.2 常用调试命令

  要想让开发过程变得高效,常用的调试命令必须要能够熟练地使用。在不同的芯片平台上,U盘挂载后的路径是不同的,如下:

芯片常规U盘路径
海思mnt/sda/sda1
Amlogicstorage/external_storage/sda1
Mstarmnt/usb/sda1

  为方便表示,下文中的U盘路径均用usb_disk表示。

2.2.1 ADB命令

ADB命令串口命令意义
adb connect IP:port-连接 Android 设备
adb disconnect-断开 ADB 连接
adb kill-server-关闭 PC ADB 调试,效果等同断开连接
adb shell-进入 shell 模式,效果等同于串口连接
adb remountmount -o remount,rw /system将 ‘/system’ 部分置于可写入的模式
ll file(adb shell后)ll file查看该目录下文件的详细信息,如最后修改时间、权限等
chmod 755 file(adb shell后)chmod 755 file赋予文件755权限
adb rebootreboot重启
reboot recovery(adb shell后)reboot recovery重启后进入recovery
adb install -r **.apkpm install -r **.apk覆盖安装某个应用
adb uninstall com.exp.testpm uninstall com.exp.test卸载某个应用(com.exp.test为应用的包名)
pm list packages(adb shell后)pm list packages查看已安装的应用及其对应的包名
adb logcat –clogcat -c清除log缓存
logcat(adb shell后)logcat直接查看运行log
adb logcat –v threadtime >E:\1.loglogcat -v threadtime -f /sdcard/.log抓取1.log
dmesg(adb shell后)dmesg直接查看运行内核log
tcpdump -s 0 -i eth0 -w /data/dhcp.pcap(adb shell后)tcpdump -s 0 -i eth0 -w /data/dhcp.pcap抓取网络包
adb pull system/media/bootanimation.zip E:\cp -r system/media/bootanimation.zip usb_disk从终端中拷贝文件出来
adb push E:\Provision.apk system/app/Provision.apkcp -r usb_disk/Provision.apk system/app/Provision.apk替换文件到终端中
adb shell syncsync将内存缓冲区中的数据 写入到磁盘
am start -n 包名/完整Activity路径(adb shell后)am start -n 包名/完整Activity路径启动Activity
am broadcast -a “broadcastactionfilter”(adb shell后)am broadcast -a “broadcastactionfilter”发送Broadcast
am startservice “com.exm.test/.TestService”(adb shell后)am startservice “com.exm.test/.TestService”启动Service
content query --uri content://stbconfig/authentication(adb shell后)content query --uri content://stbconfig/authentication查询ContentProvider内容
am force-stop com.exp.test(adb shell后)am force-stop com.exp.test强制关闭应用
screencap /sdcard/screen.png(adb shell后)screencap /sdcard/test.png截屏
screenrecord /sdcard/demo.mp4(adb shell后)screenrecord /sdcard/demo.mp4录制视频
input text “123”(adb shell后)input text “123”输入一段字符串
input keyevent 23(adb shell后)input keyevent 23模拟按键
dumpsys -l/service list(adb shell后)dumpsys -l/service list查看当前运行的Service
dumpsys package(adb shell后)dumpsys package查看应用的四大组件信息
dumpsys activity (adb shell后)dumpsys activity查询AMS服务相关信息
dumpsys window(adb shell后)dumpsys window查询WMS服务相关信息
dumpsys cpuinfo(adb shell后)dumpsys cpuinfo查询CPU情况
dumpsys meminfo(adb shell后)dumpsys meminfo查询内存情况
top(adb shell后)top查询试试内存情况
ps(adb shell后)ps查看进程
start adbd(adb shell后)start adbd启用adbd,可以使用adb连接功能
stop adbd(adb shell后)stop adbd禁用adbd
start console(adb shell后)start console启用串口调试功能
stop console(adb shell后)stop console禁用串口调试功能
getprop(adb shell后)getprop查看属性
setprop prop_name prop_val(adb shell后)setprop prop_name prop_val设置属性值
cat node_path(adb shell后)cat node_path查看节点值
remotecfg(adb shell后,Amlogic上使用)
stop ir_user(adb shell后,海思上使用)
busybox devmem 0x1f007b00 16 0x0000 (adb shell后,Mstar9380上使用)
remotecfg(Amlogic上使用)
stop ir_user(海思上使用)
busybox devmem 0x1f007b00 16 0x0000 (Mstar9380上使用)
禁用红外遥控器使用功能
./system/bin/remotecfg.sh(adb shell后,Amlogic上使用)
start ir_user(adb shell后,海思上使用)
busybox devmem 0x1f007b00 16 0x01bf(adb shell后,Mstar9380上使用)
./system/bin/remotecfg.sh(Amlogic上使用)
start ir_user(海思上使用)
busybox devmem 0x1f007b00 16 0x01bf (Mstar9380上使用)
启用红外遥控器使用功能
settings get secure ntp_server (adb shell后)settings get secure ntp_server查看系统数据库中值
settings put secure ntp_server cn.pool.ntp.org(adb shell后)settings put secure ntp_server cn.pool.ntp.org设置系统数据库中值
wm size(adb shell后)wm size查看UI分辨率
wm size 1920x1080(adb shell后)wm size 1920x1080修改UI分辨率
wm density(adb shell后)wm density查看屏幕密度
wm density 240(adb shell后)wm density 240修改屏幕密度
cat /proc/cpuinfo(adb shell后)cat /proc/cpuinfo查看CPU信息

2.2.2 LINUX命令

LINUX命令意义
cd /
cd -
cd dirA
切换到根目录
切换到上次操作目录
切换到dirA目录
pwd查看当前目录
su userName切换用户
df查看磁盘使用情况
mkdir创建目录
rm –f fileName强制删除文件
rm –rf folderName强制删除文件夹(慎用)
mv aName bName文件(夹)重命名
cp –rf dirA dirB拷贝文件夹 A 内容到文件夹 B
find . –name fileName在当前目录搜索某文件
grep –rin “str” ./*在当前目录检索字符串
tar –cvf test.tar ./fName压缩 fName 目录文件为 test.tar
tar –xvf a.tar解压 test.tar
make clean清除编译内容
busybox md5sum fileName查看文件 md5
echo 7 > /proc/sys/kernel/printk修改内核log等级
cat /proc/sys/kernel/printk查看内核log等级
java -Xmx2048m -jar signapk.jar -w platform.x509.pem platform.pk8 test.apk test_sign.apkapk签名
java -Xmx2048m -jar signapk.jar -w testkey.x509.pem testkey.pk8 update.zip update_signed.zipupdate.zip签名

  此外,还有一些不那么常用、却很有用的命令,可以尽量掌握下:
   1>lsmod
    查看已加载的模块,输出结果和"cat /proc/modules"一致,示例内容如下:

dwc_otg 282708 0 - Live 0x0000000000000000
dwc3 18053 0 - Live 0x0000000000000000
bt_usb 14905 0 - Live 0x0000000000000000 (O)
mac80211 412290 0 - Live 0x0000000000000000
cfg80211 401371 1 mac80211, Live 0x0000000000000000
aml_thermal 18902 0 - Live 0x0000000000000000 (O)
tb_detect 5521 0 - Live 0x0000000000000000 (O)
mali 191194 26 - Live 0x0000000000000000 (O)
aml_nftl_dev 81488 0 - Live 0x0000000000000000 (PO)

    第1列表示模块的名称,第2列表示模块的大小,第3列表示依赖模块的个数,第4列表示依赖模块的内容。
   2>cat /proc/meminfo
    查看内存信息。

2.2.3 VIM命令

VIM命令意义
vi fileName打开文件
:set nu显示行数
/检索
:w保存修改
:q退出
i进入编辑模式
Esc退出编辑模式
dd删除一行

2.2.4 GIT命令

VIM命令意义
git branch查看本地分支
git status .查看当前目录哪些文件修改过还未提交
git diff filename/folderName查看某个文件/文件夹具体修改内容
git log查看本地所以修改记录
git log filename/folderName查看某个文件/文件夹修改记录
git checkout fileName回退某个文件未提交的修改
git pull更新本地代码,与服务器同步
git show commitId查看某次 commit 内容
git show –-stat commitId查看某次提交修改的文件
git clone + gitUrl拉取远程代码到本地
git checkout A B从分支 A 切换到分支 B
git add/rm添加到暂存区/删除文件
git commit –m “”将修改提交到本地
git push origin branchRemoteName将本地分支修改提交到远程分支

2.2.5 命令使用小技巧

  首先,要尽量将上述ADB命令与" |grep "结合使用,如"ll/ls"与" |grep"使用,可过滤特定名称的文件/文件夹;“getprop"与” |grep "使用,可过滤特定名称的属性;“dumpsys meminfo"与” |grep"使用,可过滤特定名称
应用的内存使用情况;“logcat"与” |grep "使用,可过滤某些特定日志。
  其次,多使用模糊搜索/特定目录搜索,如:"find frameworks/base –name Window.java"可搜索 frameworks/base 目录下名称中带 Window 的java文件。
  再者,在 shell 界面使用 linux 命令时,命令前都要加上"busybox"
  最后,在向机顶盒中 push 文件或从机顶盒向外 pull 文件后,尽量使用一下"adb shell sync",来确保文件传输完整。

三、积累关键功能调试经验

  在以上两个章节中,涵盖了较多的日常机顶盒ROM调试命令。除此之外,还有些命令之外的技巧需要积累,如下:

3.1 功能开关

  某些功能,在源码中是已经实现好了的,在检测ROM中是否包含该功能时,只需要检查特定的属性或文件即可。如:
  1>海思上的CEC开关
   persist.sys.hdmi.cec为true,代表打开该功能;为false,代表关闭该功能。
  2>海思上的HDMI待机开关
   persist.hdmi.suspend.enable为1,代表打开该功能;为0,代表关闭该功能;
   persist.hdmi.suspend.time为具体的待机时间,一般为5。
  3>Amlogic静帧功能
   system/etc目录下的blackout_whitelist.txt文件,文件内逐行写入要实现静帧功能的应用的包名、类名。
  3>Amlogic DHCP重连功能
   net.dhcp.repeat为enabled,代表打开DHCP重连功能;
   net.dhcp.repeat.count为重试次数。

3.2 调试思路

  当某一功能实现出现问题,要遵循"先硬件/环境,再软件"和"先底层,再上层"的排查思路,如下:
   1>先硬件/环境,再软件
    遇到一个问题时,要先了解问题出现的具体情况,是否与环境、复现问题方式、机顶盒硬件有关,先做对比验证。确定是软件问题后,再从软件侧进行排查。
   2>先底层,再上层
    遇到一个问题时,可以先用命令从底层了解功能是否OK。如果底层OK,那就是上层调用逻辑出现了问题,再层层向上、逐步缩小debug范围。
  至此,常用的调试技巧已介绍完毕。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页