马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
MSM8909W watch项目编译问题:
Checking build tools versions...
************************************************************
You asked for an OpenJDK based build but your version is
java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode).
************************************************************
build/core/main.mk:231: *** stop.
make: *** [out/build-msm8909w.ninja] 错误 1
安装openjdk 1.8,留意要求的是openJDK,不是甲骨文公司的jdk
sudo add-apt-repository ppa penjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
默认安装目次是:/usr/lib/jvm/java-1.8.0-openjdk-amd64/
用如下命令修改默认jdk,配置默认JDK版本
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java 300
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/javac 300
sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/jar 300
查抄:
whl@whl-Dell:~/work/law_msm8909w_android$ sudo update-alternatives --config java
有 3 个候选项可用于替换 java (提供 /usr/bin/java)。
选择 路径 优先级 状态
------------------------------------------------------------
0 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 1071 主动模式
* 1 /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java 300 手动模式
2 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 1071 手动模式
3 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1069 手动模式
sudo update-alternatives --config javac
要维持当前值
请按回车键,或者键入选择的编号:
java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-3~14.04.1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
make -j8开始编译
Communication error with Jack server (52). Try 'jack-diagnose'
/bin/bash: out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/jack-rsc.tmp: 是一个目次
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1
使用命令启动jack:jack-admin start-server
---------------------------------------
Try increasing heap size with java option '-Xmx<size>'.
Warning: This may have produced partial or corrupted output.
[ 0% 36/27253] build out/target/common/obj/JAVA_LIBRARIES/sdk_v19_intermediates/classes.jack
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1
从上面的错误提示中可以看到如下一句:
Try increasing heap size with java option '-Xmx<size>'.
按照上述发现的提示语句,我们对prebuilts/sdk/tools/jack-admin文件进行如下修改:
1.找到如下语句:
JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"
2.将上述语句修改为:
JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"
Android N上的代码编译使用了jack服务,对体系内存有很高的要求,在编译过程中,通常会由于哀求不到可用内存而失败,重要是添加了-Xmx4096m参数,接下来在源码目次下实行如下命令重启jack-admin服务:
./prebuilts/sdk/tools/jack-admin stop-server
./prebuilts/sdk/tools/jack-admin start-server
----------------------------------------
4 warnings generated.
[ 10% 2456/22820] build out/target/product/msm8909w/gen/EXECUTABLES/iw_intermediates/version.c
FAILED: /bin/bash -c "external/iw/version.sh out/target/product/msm8909w/gen/EXECUTABLES/iw_intermediates/version.c"
fatal: 没有发现名称,无法描述任何东西。
[ 10% 2456/22820] target thumb C++: logd <= system/core/logd/LogBuffer.cpp
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1
办理:
vi external/iw/version.sh
可以看到如下:
if [ -d .Git ] && head=`git rev-parse --verify HEAD 2>/dev/null`; then
为了让这个脚本不走[ -d .git ]分支改成如下:
#if [ -d .git ] && head=`git rev-parse --verify HEAD 2>/dev/null`; then
if [ -d .git ] && head=`git rev-parse --verify HEAD 2>/dev/null` && [$VERSION != "4.1"]; then
------------------------
[ 96% 19601/20376] host Java: ahat-tests (out/host/common/obj/JAVA_LIBRARIES/ahat-tests_intermediates/classes)
注: art/tools/ahat/test/SortTest.java使用了未经查抄或不安全的操纵。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[ 96% 19704/20376] host Java: android-icu4j-host (out/host/common/obj/JAVA_LIBRARIES/android-icu4j-host_intermediates/classes)
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: external/icu/android_icu4j/src/main/java/android/icu/impl/Relation.java使用了未经查抄或不安全的操纵。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[ 96% 19749/20376] host Java: android-icu4j-tests-host (out/host/common/obj/JAVA_LIBRARIES/android-icu4j-tests-host_intermediates/classes)
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: 某些输入文件使用了未经查抄或不安全的操纵。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[100% 20376/20376] host Executable: primitives_tests_32 (out/host/linu...6/obj32/EXECUTABLES/primitives_tests_intermediates/primitives_tests32)
办理方法:
make update-api
---------------------
make -j4
Creating filesystem with parameters:
Size: 1860648960
Block size: 4096
Blocks per group: 32768
Inodes per group: 8112
Inode size: 256
Journal blocks: 7097
Label: data
Blocks: 454260
Block groups: 14
Reserved block group size: 111
Created filesystem with 209/113568 inodes and 17124/454260 blocks
Running ['mkuserimg.sh', '-s', 'out/target/product/msm8909w/data', 'out/target/product/msm8909w/userdata.img', 'ext4', 'data', '1860648960', '-D', 'out/target/product/msm8909w/system', '-L', 'data', 'out/target/product/msm8909w/root/file_contexts.bin'] command, exit code = 0
out/target/product/msm8909w/userdata.img maxsize=1899600384 blocksize=135168 total=40875316 reserve=19193856
#### make completed successfully (11:06 (mm:ss)) ####
编译乐成
====================
msm8909w编译user版本问题:
make[1]:正在脱离目次 `/home/whl/work/law_msm8909w_android/out/target/product/msm8909w/obj/KERNEL_OBJ'
make: *** [sub-make] 错误 2
make:脱离目次“/home/whl/work/law_msm8909w_android/kernel”
[ 86% 30130/35026] target Package: SettingsProvider (out/target/product/msm8909w/obj/APPS/SettingsProvider_intermediates/package.apk)
warning: ignoring flag -c hdpi-v4. Use --preferred-density instead.
warning: ignoring flag -c mdpi-v4. Use --preferred-density instead.
warning: ignoring flag -c hdpi-v4. Use --preferred-density instead.
warning: ignoring flag -c mdpi-v4. Use --preferred-density instead.
[ 86% 30130/35026] target R.java/Manifest.java: Settings (out/target/common/obj/APPS/Settings_intermediates/src/R.stamp)
nothing matches overlay file suw_navbar_ic_back.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_more.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_next.xml, for flavor anydpi-v21
nothing matches overlay file suw_progress_bar.xml, for flavor v21
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1
---------------------------
user版本和userdebug版本编译tp驱动的时候都会出现以下问题:
CC drivers/input/touchscreen/it7259_ts_i2c.o
/home/whl/work/law_msm8909w_android/kernel/drivers/input/touchscreen/it7259_ts_i2c.c: In function 'i2cDirectWriteToIT7259':
/home/whl/work/law_msm8909w_android/kernel/drivers/input/touchscreen/it7259_ts_i2c.c:449:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
error, forbidden warning: it7259_ts_i2c.c:449
make[4]: *** [drivers/input/touchscreen/it7259_ts_i2c.o] 错误 1
make[3]: *** [drivers/input/touchscreen] 错误 2
make[2]: *** [drivers/input] 错误 2
make[1]: *** [drivers] 错误 2
make[1]: *** 正在等候未完成的任务....
make[1]:正在脱离目次 `/home/whl/work/law_msm8909w_android/out/target/product/msm8909w/obj/KERNEL_OBJ'
make: *** [sub-make] 错误 2
重新配置frame size
----------------------
user编译:
make[1]:正在脱离目次 `/home/whl/work/law_msm8909w_android/out/target/product/MSM8909W/obj/KERNEL_OBJ'
make: *** [sub-make] 错误 2
make:脱离目次“/home/whl/work/law_msm8909w_android/kernel”
[ 86% 30132/35026] target R.java/Manifest.java: Settings (out/target/common/obj/APPS/Settings_intermediates/src/R.stamp)
nothing matches overlay file suw_navbar_ic_back.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_more.xml, for flavor anydpi-v21
nothing matches overlay file suw_navbar_ic_next.xml, for flavor anydpi-v21
nothing matches overlay file suw_progress_bar.xml, for flavor v21
ninja: build stopped: subcommand failed.
make: *** [ninja_wrapper] 错误 1
重新编译就没有了
=======================================
user版本打印:
Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset), D - Delta, S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.BF.3.1.2.C3-00012
S - IMAGE_VARIANT_STRING=WAASANAZA
S - OEM_IMAGE_VERSION_STRING=Alan-PC
S - Boot Config, 0x000000e1
B - 1567 - PBL, Start
B - 4543 - bootable_media_detect_entry, Start
B - 64819 - bootable_media_detect_success, Start
B - 64823 - elf_loader_entry, Start
B - 65584 - auth_hash_seg_entry, Start
B - 65843 - auth_hash_seg_exit, Start
B - 80179 - elf_segs_hash_verify_entry, Start
B - 139018 - PBL, End
B - 152286 - SBL1, Start
B - 210175 - boot_flash_init, Start
D - 30 - boot_flash_init, Delta
B - 216763 - boot_config_data_table_init, Start
D - 7869 - boot_config_data_table_init, Delta - (0 Bytes)
B - 229299 - CDT version:3,Platform ID:8,Major ID:1,Minor ID:0,Subtype:9
B - 235490 - pm_device_init, Start
B - 238845 - pm_device_init, TEST - MSM8909 detected
B - 244244 - pm_device_init, INFO - PM8916 is selected
B - 258884 - PM_SET_VAL:Skip
D - 21716 - pm_device_init, Delta
B - 260256 - sbl1_ddr_set_params, Start
B - 262757 - cpr_init, Start
D - 0 - cpr_init, Delta
B - 268308 - Pre_DDR_clock_init, Start
D - 213 - Pre_DDR_clock_init, Delta
D - 0 - sbl1_ddr_set_params, Delta
B - 281271 - pm_driver_init, Start
B - 288194 - --> Charge init
B - 4186 - battery voltage
B - 291671 - boot up
B - 10 - Current status
D - 10736 - pm_driver_init, Delta
B - 303658 - clock_init, Start
D - 152 - clock_init, Delta
B - 354623 - Image Load, Start
D - 21106 - QSEE Image Loaded, Delta - (489660 Bytes)
B - 375760 - Image Load, Start
D - 274 - SEC Image Loaded, Delta - (2048 Bytes)
B - 384025 - sbl1_efs_handle_cookies, Start
D - 610 - sbl1_efs_handle_cookies, Delta
B - 390766 - Image Load, Start
D - 13969 - RPM Image Loaded, Delta - (157664 Bytes)
B - 404796 - Image Load, Start
D - 19581 - APPSBL Image Loaded, Delta - (482464 Bytes)
B - 424438 - QSEE Execution, Start
D - 366 - QSEE Execution, Delta
B - 430172 - SBL1, End
D - 280173 - SBL1, Delta
S - Throughput, 34000 KB/s (1131836 Bytes, 33117 us)
S - DDR Frequency, 384 MHz
Android Bootloader - UART_DM Initialized!!!
[50] [50] Qseecom Init Done in Appsbl version is 0x405000
[60] [60] secure app region addr=0x87b00000 size=0x100000[60] [60] TZ App region notif returned with status:0 addr:87b00000 size:1048576
[70] [70] TZ App log region register returned with status:0 addr:8f692000 size:4096
[80] [80] Qseecom TZ Init Done in Appsbl
[140] [140] Not able to search the panel:
[640] [640] ERROR: Splash image header invalid
[770] [770] Device is unlocked! Skipping verification...
[5910] [5910] ERROR: Splash image header invalid
[5930] [5930] Authentication Key not yet programmed
[5970] [5970] Qseecom De-Init Done in Appsbl
[5970] [5970] Channel alloc freed
-------------------------------------------
心电厂商给我们的标准是57600波特率,心电的sensor会按照每秒22+8*512=4118字节的速率实时的上报数据,22个字节的固定帧头数据和512帧有效数据,每帧是8个字节,此中8个字节里有2个字节是心电的有效数据,所以标准是每秒我应该获取到512*2=1024字节的有效数据,但是我在串口加了打印,抓了一下log,
diff --git a/kernel/drivers/tty/serial/msm_serial_hs_lite.c b/kernel/drivers/tty/serial/msm_serial_hs_lite.c
index 15d8fb4..8a69360 100755
--- a/kernel/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/kernel/drivers/tty/serial/msm_serial_hs_lite.c
/* and now the main RX loop */
while (count > 0) {
+ //printk("===count = %d===\n",count);
unsigned int c;
char flag = TTY_NORMAL;
sr = msm_hsl_read(port, regmap[vid][UARTDM_SR]);
if ((sr & UARTDM_SR_RXRDY_BMSK) == 0) {
+ printk("===rx 1===\n");
msm_hsl_port->old_snap_state -= count;
break;
}
c = msm_hsl_read(port, regmap[vid][UARTDM_RF]);
+ printk("==c = 0x%8x==\n",c);
if (sr & UARTDM_SR_RX_BREAK_BMSK) {
port->icount.brk++;
+ printk("===rx 2===\n");
if (uart_handle_break(port))
continue;
} else if (sr & UARTDM_SR_PAR_FRAME_BMSK) {
+ printk("===rx 3===\n");
port->icount.frame++;
} else {
+ //printk("===rx 4===\n");
port->icount.rx++;
发现每次根本只能获取到926-999字节的数据,厂商怀疑是不是我们的DMA没有优化好,但是我通过以下方式验证:
a:高通平台查看DMA传输:
echo 1 > /sys/kernel/debug/msm_serial_hsl/loopback.1 //打开回环开关
adb shell cat /dev/ttyHSL1
另起窗口
# adb shell
# echo 11111111 > /dev/ttyHSL1
若DMA通道ok,控制台会循环显示;
控制台并没有循环显示,而是echo一次,显示一次
--------------------------------------------------------------
修改震惊强度:
(1)体系马达震惊设置,比如长按屏幕震惊:
frameworks/base/core/res/res/values/config.xml
关键字:config_longPressVibePattern
(2)来电震惊
设置开关:
packages/apps/Settings/res/values/strings.xml
关键字:vibrate_when_ringing_title
上层调用接口:虽然APK在data下,但是要全编才有效果,make -j4
packages/services/Telecomm/src/com/android/server/telecom/Ringer.java
关键字:
mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
VIBRATION_ATTRIBUTES);
mIsVibrating = true;
震惊设置:
private static final long[] VIBRATION_PATTERN = new long[] {
0, // No delay before starting
1000, // How long to vibrates
1000, // How long to wait before vibrating agai
};
重复设置:
private static final int VIBRATION_PATTERN_REPEAT = 1;
(3)马达(触觉)驱动:
kernel/drivers/platform/msm/qpnp-haptic.c
设备树文件:
kernel/arch/arm/boot/dts/qcom/msm-pmi8950-oem.dtsi
额定电压: qcom,vmax-mv = <3000>;
马达规格书,额定电压3V
(4)手动测试马达:
echo "1000" > /sys/class/timed_output/vibrator/enable
震惊1S
cat /sys/class/timed_output/vibrator/dump_regs
qpnp_haptics: REG_0xc00b = 0x0
寄存器对应到qpnp-haptic.c驱动
-------------------------------------------------------------------------------------------
SSR子体系重启:
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys0/name
a506_zap
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys1/name
venus
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys2/name
adsp
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys3/name
wcnss
root@msm8953_64:/sys/bus/msm_subsys/devices # cat subsys4/name
modem
dump模式开关的控制节点是
shell@msm8953_64:/ $ cat sys/module/msm_poweroff/parameters/download_mode
0 表现关 1表现开
-------------------------------------------------------------------------------
persist.sys.usb.config被修改和设置的地方和流程:
1.build/tools/post_process_props.py脚本对android体系下/default.prop文件做去重处置惩罚
# Put the modifications that you need to make into the /default.prop into this
# function. The prop object has get(name) and put(name,value) methods.
def mangle_default_prop(prop):
# If ro.debuggable is 1, then enable adb on USB by default
# (this is for userdebug builds)
if prop.get("ro.debuggable") == "1":
val = prop.get("persist.sys.usb.config")
if val == "":
val = "adb"
else:
val = val + ",adb"
prop.put("persist.sys.usb.config", val)
# UsbDeviceManager expects a value here. If it doesn't get it, it will
# default to "adb". That might not the right policy there, but it's better
# to be explicit.
if not prop.get("persist.sys.usb.config"):
#prop.put("persist.sys.usb.config", "none"); set user software build usb default support debug PC port like Diag and so on. lu.xingxian@pubtron.com.cn 20170502
prop.put("persist.sys.usb.config", "adb");
假如是debug版本,由于persist.sys.usb.config一开始为空,就设置persist.sys.usb.config为adb,所以一开始persist.sys.usb.config设置为adb,假如不为空就在原来基础上加上,adb字段。假如是user版本,persist.sys.usb.config获取不到,我们就把persist.sys.usb.config设置成adb,为了生产测试方便。
留意:
修改该文件def mangle_default_prop(prop):的字段
终极生成的out/target/product/msm8953_64/root/default.prop
所以假如有修改,应该先删除
out/target/product/msm8953_64/root/default.prop,否则make会编译不到。
比如修改val = "wanghl,adb",make -j4之后,out/target/product/msm8953_64/root/default.prop就会变为以下内容:
#
# ADDITIONAL_DEFAULT_PROPERTIES
#
ro.secure=1
security.perf_harden=1
ro.allow.mock.location=0
ro.debuggable=1
ro.zygote=zygote64_32
dalvik.vm.image-dex2oat-Xms=64m
dalvik.vm.image-dex2oat-Xmx=64m
dalvik.vm.dex2oat-Xms=64m
dalvik.vm.dex2oat-Xmx=512m
ro.dalvik.vm.native.bridge=0
debug.atrace.tags.enableflags=0
#
# BOOTIMAGE_BUILD_PROPERTIES
#
ro.bootimage.build.date=2017年 09月 01日 星期五 10:40:10 CST
ro.bootimage.build.date.utc=1504233610
ro.bootimage.build.fingerprint=Android/msm8953_64/msm8953_64:6.0.1/MMB29M/whl09011040:userdebug/test-keys
persist.sys.usb.config=wanghl,adb(规复出厂的时候酿成该值)
可以看到persist.sys.usb.config被改掉了,到时候软件烧录到机子上也可以看到同样的/default.prop被改掉。
这是第一个设置persist.sys.usb.config属性的地方,默认值。
后续有被改动的地方,必要终端下查看:getprop persist.sys.usb.config
wanghl.adb
2.device/qcom/common/rootdir/etc/init.qcom.usb.sh
usb_config=`getprop persist.sys.usb.config`
case "$usb_config" in
"" | "adb") #USB persist config not set, select default configuration
case "$esoc_link" in
" CIe")
setprop persist.sys.usb.config diag,diag_mdm,serial_cdev,rmnet_qti_ether,mass_storage,adb
;;
*)
case "$soc_hwplatform" in
"Dragon")
setprop persist.sys.usb.config diag,adb
;;
*)
case "$target" in
......
"msm8952" | "msm8953")
setprop persist.sys.usb.config diag,serial_smd,rmnet_ipa,adb
;;
*)
setprop persist.sys.usb.config diag,adb
;;
esac
;;
esac
;;
esac
;;
* ) ;; #USB persist config exists, do nothing
esac
假如getprop persist.sys.usb.config为空或者为adb(默认为adb)且是8953平台,就将他设置成:diag,serial_smd,rmnet_ipa,adb。这也是为什么user版本,在persisi.sys.usb.config里面persist.sys.usb.config设置成adb之后就能打开调试口diag口,modem口,网络口,adb口的缘故原由。
假如getprop persist.sys.usb.config存在其他属性值,则什么也不做。保留原来的属性值。
至此,persist.sys.usb.config的属性值就确定下来了
----------------------------------------------------------------------------------------
sys.usb.config属性值被改写的地方和流程:
1.system/core/rootdir/init.usb.rc
# Used to set USB configuration at boot and to switch the configuration
# when changing the default configuration
on property:persist.sys.usb.config=*
setprop sys.usb.config ${persist.sys.usb.config}
没错,就是它, 这个注册了一个触发器, 意思是当体系使用property更新persist.sys.usb.config的值的话,就同时更新sys.usb.config为同样的值
可以看到:sys.usb.config属性是根据persist.sys.usb.config来设置的。默认就是diag,serial_smd,rmnet_ipa,adb,所以插上USB线之后下来菜单什么也没选中,由于下来菜单的四种状态:Charging,MTP,PTP,MIDI分别对应sys.usb.config的属性值为:
(1)charging
(2)mtp,adb
(3)ptp,adb
(4)midi,adb
所以啥也不会选中。
当sys.usb.config设置成diag,serial_smd,rmnet_ipa,adb属性之后就会在文件:
device/qcom/common/rootdir/etc/init.qcom.usb.pubtron.rc(源文件是init.qcom.usb.rc)匹配上对应的操纵。
on property:sys.usb.config=diag,serial_smd,rmnet_ipa,adb && property:sys.usb.configfs=0
write /sys/class/android_usb/android0/enable 0
write /sys/class/android_usb/android0/idVendor 05C6 设置VID
write /sys/class/android_usb/android0/idProduct 9091 设置PID
write /sys/class/android_usb/android0/f_diag/clients diag
write /sys/class/android_usb/android0/f_serial/transports smd
write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa
write /sys/class/android_usb/android0/functions diag,serial,rmnet,adb
write /sys/class/android_usb/android0/enable 1
start adbd 启动adb服务器
setprop sys.usb.state ${sys.usb.config} 设置sys.usb.state的属性为sys.usb.config
原本的user版本,persist.sys.usb.config被设置为none,这时候sys.usb.config为mtp,所以默认就是mtp模式。但是尚未找到sys.usb.config在哪里被设置成mtp
============================================================================================================================================
SNS_DDF_SENSOR_PROXIMITY, // 5
SNS_DDF_SENSOR_AMBIENT, // 6
手挡住灭屏幕:传感器值是0
手拿开亮屏幕:传感器值是5
现在问题是Prox的值一开始是5,然后挡住的时候不会更新值,不会变为0
5脚的LEDA电压正常(规格书要求0.3-4.7V),有问题机器4.3V,没问题机器4.29V,VDD都是2.8V,INT有硬件上拉
SN:902707293815机器是虚焊导致的PROX sensor没反应,重新吹下来再焊接上去就好了。
------------------------------------------------------------------------------
MSM8953手机 NV项目2499这一项用到了
0:RF校准标志
1:酒精校准标志
2:酒精校准标志
------------------------------
IIC
SLA+R/W 共八位
SLA:前七位,表现从机地址(所以最多支持128个从设备),高位在前,职位在后
R/W:末了一位,为READ/WRITE控制位;假如READ/WRITE 为1,则实行读操纵;否则实行写操纵。
用于定制上层ROM的工程提交留意事项:
ADSP的修改,将编译后的NON—HLOS.bin拷贝到工程目次下的msm8953_android_oem/device/qcom/msm8953_64/radio
用于OTA升级。
修改hardware/libhardware/modules/health/health.c是将编译生成的out/target/product/msm8953_64/system/lib64/hw/health.default.so
拷贝到msm8953_android_oem/frameworks/base/healthmonitor/lib下
------------------------------------------------------------------------
高通panel初始化代码示例
39 01 00 00 00 00 12 F2 00 77 03 0A 76 03 01 01 82 01 BA 57 00 00 77 0A 76
39 01 00 00 00 00 0F F4 0B 00 00 00 21 4F 01 02 2A 7F 03 2A 00 03
39 01 00 00 00 00 0B F5 00 00 00 00 00 11 00 00 04 04
39 01 00 00 00 00 0A F6 02 01 06 00 06 04 06 74 06
15 01 00 00 00 00 02 F7 02
39 01 00 00 00 00 03 F8 33 00
15 01 00 00 00 00 02 F9 00
39 01 00 00 00 00 04 E3 84 06 64
39 01 00 00 00 00 55 FA 1F 06 01 0D 17 1C 21 2B 32 30 32 3F 35 00 06 1F 0A 28 31 35 35 40 4C 51 56 5E 3E 00 19 06 01 11 1D 23 27 2F 35 34 37 56 35 00 06 19 0A 11 2C 32 32 3C 46 4A 50 5A 3E 00 05 05 01 0C 20 29 31 38 3B 36 34 3C 35 00 05 05 0A 2B 2F 2F 2C 33 3C 44 4D 5F 3E 00
05 01 00 00 A0 00 02 11 00
05 01 00 00 00 00 02 29 00
-------------------------------------------------------------
msm8909w的TZ部门配置信息:
core/securemsm/trustzone/qsee/include/tzbsp_blsp.h
typedef struct tzbsp_blsp_peripheral_info_s
{
TzBspBlspProtocol protocol; /* Whether this Peripheral is used for SPI/I2C/UART */
TzBspBlspIsPersistent isPersistent; /* Whether the protection should remain for ever starting from TZ Cold Boot and
* no dynamic switching of BLSP Peripheral b/w TZ and other sub-system. To achieve dynamic
* owner switching this field should be set to FALSE irrespective of whether cold
* boot protection is enabled or not */
TzBspBlspGpioProtType protectionType; /* Whether the MPU/RPU protection is used of GPIO's. For Bear it is MPU and for Badger it is */
TzBspBlspPeripheralId peripheralId; /* Peripheral ID starting from 1 */
uint32 uPeripheralRgIndex; /* Peripheral (QUP/UART) RG Index */
uint32 uBlspXpuId; /* XPU Index used for QUP/UART protection */
uint32 uGpios[TZBSP_BLSP_GPIOS_SUPPORTED]; /* GPIO numbers used for protection and configuring functionality */
uint32 uNumGpios; /* Total number of GPIO's used */
uint32 uGpioIndex[TZBSP_BLSP_INDICES_SUPPORTED]; /* Index used for GPIO Protection in Bear targets.
* NOTE:: Must contact Qualcomm for index numbers.
* Must set unused entries to 0xFFFFFFFF. */
uint32 uSubSystemId; /* Subsystem ID, tells to which subsystem the QUP/UART and its resources has to be assigned */
boolean bIsPeripheralTzUsed; /* TRUE, the QUP/UART is assigned to only TZ or shared between TZ and any other subsystem.
* FALSE, not assigned to TZ (even in Dual EE) */
} TzBsp_Blsp_Peripheral_Info;
core/securemsm/trustzone/qsee/arch/msm8909/src/tzbsp_blsp_config_8909w.c
/* This structure contains QUP/UART information to be assigned to a subsystem
* at cold boot stage, according to the use case.
*
* Note: For GPIO index value, the customer must contact Buses team before
* using. The unused indices must be to 0xFFFFFFFF.
*/
/*
Information Format::
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL, PERSISTENCE, GPIO_PROTECTION_TYPE,
PERIPHERAL_ID, PERIPHERAL_RG_INDEX, BLSP_XPU_ID,
GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, GPIO_6, NUM_GPIOS,
GPIO_INDEX_1, GPIO_INDEX_2, GPIO_INDEX_3, SUBSYSTEM_ID, IS_PERIPHERAL_TZ_USED)
*/
TzBsp_Blsp_Peripheral_Info TzBspBlspPeripheralInfo[] =
{
/* QUP 1 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_QUP_1, TZBSP_BAM_BLSP1_RG_QUP0, HAL_XPU2_BAM_BLSP1_DMA,
6,7,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_NONE_ID,FALSE),
/* QUP 2 */ /* NFC */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_QUP_2, TZBSP_BAM_BLSP1_RG_QUP1, HAL_XPU2_BAM_BLSP1_DMA,
111,112,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
/* QUP 3 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_SPI, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_QUP_3, TZBSP_BAM_BLSP1_RG_QUP2, HAL_XPU2_BAM_BLSP1_DMA,
0,1,2,3,0xFFFFFFFF,0xFFFFFFFF,4,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_NONE_ID,FALSE),
/* QUP 4 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_QUP_4, TZBSP_BAM_BLSP1_RG_QUP3, HAL_XPU2_BAM_BLSP1_DMA,
14,15,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
/* QUP 5 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_I2C, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_QUP_5, TZBSP_BAM_BLSP1_RG_QUP4, HAL_XPU2_BAM_BLSP1_DMA,
18,19,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
/* QUP 6 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_SPI, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_QUP_6, TZBSP_BAM_BLSP1_RG_QUP5, HAL_XPU2_BAM_BLSP1_DMA,
8,9,10,11,0xFFFFFFFF,0xFFFFFFFF,4,
15,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
/* UART 1 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_UART_2_LINE, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_UART_1, TZBSP_BAM_BLSP1_RG_UART0, HAL_XPU2_BAM_BLSP1_DMA,
4,5,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
/* UART 2 */
TZBSP_BLSP_PERIPHERAL_INFO(PROTOCOL_UART_2_LINE, NON_PERSISTENT, PROTECTION_TYPE_MPU,
BLSP_UART_2, TZBSP_BAM_BLSP1_RG_UART1, HAL_XPU2_BAM_BLSP1_DMA,
20,21,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,2,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,TZBSP_APSS_ID,FALSE),
};
---------------------------------------------------------------------------
MDSS:Multimedia Display Sub-system
Display driver包罗:
SurfaceFlinger,Hardware Composer(HWC),以及overlay
Framebuffer
MIPI DSI驱动
DSI全称是 Display Serial Interface,是mipi协议的一个规范。它定义了一个在平台端和panel之间的串行总线和通讯协议,总线包罗一条 Clock lane和 1~4条 Date lane。每条 lane有两条 line(lane+和lane-),差分信号。在高通的 display框架里是 mdp的一部门,用来手机平台端和LCD传送 command和 data。HS mode lanes最大能支持到 1.5Gbps。
DSI只有两种操纵模式 command和 video。
(1)command mode从 host端获取 command和 data。但是这个使用 command mode
的 LCD有本身的 RAM和 LCD controller,它会自革新静态图片。MSM能直接进入休眠,
节流电量。可会多出来 RAM和 Controller的成本。
Command mode的信息是双向的,host能从 panel上读和写数据。Host能同步数据
通过从 panel中读取 Tearing Effect(TE)信号(Vsync)去避免TE。
(2)video mode获取实时的 pixel stream。DSI Controller必须不绝的革新 image data,
这个模式一样平常用于没有 RAM的panel。Host提供 video data和同步信息。同步信息有Vsync、
Hsync、data enable和 pixel clock。Video mode操纵与 RGB接口很类似,但是使用的 pin
脚更少,所以 EMI和无线电干扰更小。
但是目前来说,video模式使用的比较广泛。使用 Command模式的项目还是比较少的。
Mobile display processor MDP 3.05
---------------------------------------------------------------------------------------------------------------------------------------------
vi 删除每一行的第一个字:
:% s/^.\{1\}//g
---------------------
依赖 depends on
这个关键字表现了在某些配置选中后,本配置项才会显示。
反向依赖 select
这个关键字表现了当本配置项选中后,其他的配置项也必要选中。
-----------------------------------------------------------------------
linux用一套键值,android本身用一套键值,两者通过keylayout(kl)文件映射
源文件
frameworks/base/data/keyboards/Generic.kl:407:key 580 APP_SWITCH
frameworks/base/core/java/android/view/KeyEvent.java:547: public static final int KEYCODE_APP_SWITCH = 187;
linux 驱动键值是580,andorid APP_SWITCH是187
体系跑起来后,所有*.kl文件在:/system/usr/keylayout
frameworks/base/data/keyboards/qwerty.kl已经不用了,Generic.kl里有说到
getevent可以查看linux键值
--------------------------------
SPI panel移植调试笔记
一、lk部门
int target_cont_splash_screen()
{
uint8_t splash_screen = 0;
if (!splash_override) {
switch (board_hardware_id()) {
case HW_PLATFORM_SURF:
case HW_PLATFORM_MTP:
case HW_PLATFORM_QRD:
case HW_PLATFORM_RCM:
splash_screen = 1;
break;
default:
splash_screen = 0;
break;
}
dprintf(SPEW, "Target_cont_splash=%d\n", splash_screen);
}
return splash_screen;
}
splash_screen = 1,LK打开一连LOGO显示,splash_screen = 0,LK关闭一连LOGO显示.默认打开。
K8项目默认使用SPI屏幕:
1.
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += PANEL_LH154Q01_CMD=0
DEFINES += PANEL_ST7789V_SPI_CMD=1
endif
2.
#add support for 16bpp(RGB565) format imageBuffer LOGO of K8 SPI panel
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += DISPLAY_TYPE_MIPI=0
else
DEFINES += DISPLAY_TYPE_MIPI=1
endif
假如K8项目想使用MIPI屏幕:
1.
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += PANEL_LH154Q01_CMD=1
DEFINES += PANEL_ST7789V_SPI_CMD=0
endif
2.
#add support for 16bpp(RGB565) format imageBuffer LOGO of K8 SPI panel
ifeq ($(TARGET_PRODUCT),K8)
DEFINES += DISPLAY_TYPE_MIPI=1
else
DEFINES += DISPLAY_TYPE_MIPI=1
endif
开机显示流程:
1.初始化显示小企鹅logo:msm_display_init -> display_image_on_screen,mipi会先fetch_image_from_partition();从分区中获取LOGO,获取不到才显示的imageBuffer_rgb888格式的图片数组,spi是直接显示imageBuffer(SPI只能配置成16bpp,否则判断失败不显示logo)
2.产生DEV_UNLOCK事件,进入ORANGE启动状态,boot_verifier: Device is in ORANGE boot state.
display_bootverify_menu_thread(DISPLAY_MENU_ORANGE);显示启动菜单:
Start > Continue boot ...那个界面
fbcon_setup函数设置颜色格式
display_fbcon_menu_message("press VOLUME keys\n\n",
FBCON_SUBTITLE_MSG, common_factor);用来显示菜单内容,和显示logo一样,末了也是用fbcon_flush来革新缓存内容
display_menu_thread_start(bootverify_menu_msg_info);创建一个按键检测任务,假如有音量按键按下会弹出display_bootverify_menu_thread(DISPLAY_MENU_RED);或display_bootverify_menu_thread(DISPLAY_MENU_YELLOW);等其他菜单
3.wait_for_users_action();->display_image_on_screen();超时或POWER按键按下之后再次革新LOGO
在gcdb_display_cmdline_arg会传递屏幕类型信息到cmdline
#if PANEL_ST7789V_SPI_CMD
else if (target_is_spi())
default_str = "0:spi:0";
#endif
就像PANEL_ST7789V_SPI_CMD,假如有添加其他SPI屏幕,应该把宏开关添加到这里#if (PANEL_ST7789V_SPI_CMD || PANEL_*_SPI_CMD)
------------
LK的屏幕的头文件的和Kernel的dtsi文件通过qcom,mdss_spi_st7789v_cmd对应接洽起来
lk: bootable/bootloader/lk/dev/gcdb/display/include/panel_st7789v_spi_cmd.h
static struct panel_config st7789v_spi_cmd_panel_data = {
"qcom,mdss_spi_st7789v_cmd", "spi:0:", "qcom,mdss-spi-panel",
10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
kernel: kernel/arch/arm/boot/dts/qcom/spi-panel-gc9305-qvga-cmd.dtsi
&mdss_mdp {
spi_st7789v_cmd: qcom,mdss_spi_st7789v_cmd {
qcom,mdss-spi-panel-name = "st7789v command mode spi panel";
qcom,mdss-spi-panel-destination = "display_1";
qcom,mdss-spi-panel-controller = <&mdss_spi>;
-----------------------------------------------------------------
+config FB_MSM_MDSS_SPI_PANEL
+ depends on FB_MSM_MDSS
+ bool "Support SPI panel feature"
+ default n
+ ---help---
+ The MDSS SPI Panel provides support for transmitting SPI signals of
+ MDSS frame buffer data to connected panel. Limited by SPI rate, the
+ current max fps only reach to 27fps, and limited by MDP hardware
+ architecture only supply on MDP3.
受限于SPI的速率(15.15152M):
240*240*16(bpp)*16帧 = 14745600 < 15151520
240*240*16(bpp)*17帧 = 15667200 > 15151520
所以设置
spi-max-frequency = <15151520>;
qcom,mdss-spi-panel-framerate = <16>;
假如spi-max-frequency设置的太高会出现画面跑到开机动画之后就不革新了,就卡在开机动画界面
--------------------------------------------
/system/bin/mm-pp-daemon
是一个根据显示内容主动调节亮度的一个服务
SPI屏幕调试的时候不绝报错,
<13>[ 119.018869] init: Starting service 'ppd'...
<13>[ 119.135770] init: Service 'ppd' (pid 3521) exited with status 255
<13>[ 119.140934] init: Service 'ppd' (pid 3521) killing any children in process group
所以在脚本device/qcom/K8/init.target.rc注释掉该服务,然后重新编译kernel即可。
pr_debug("=== 1.mdp3_ctrl_on\n");//不能打印出来
pr_err("===2.mdp3_ctrl_on===\n");//能打印出来
pr_warning("===3.mdp3_ctrl_on===\n");//能打印出来
pr_info("===4.mdp3_ctrl_on===\n");//能打印出来
=======================================================================
du -lh --max-depth=1 : 查看当前目次下一级子文件和子目次占用的磁盘容量。
=======================================================================
修改开机动画文件:frameworks/base/core/res/assets/images/android-logo-mask.png
编译:mmm frameworks/base/core/res/
最好要更新一下时间戳:touch frameworks/base/core/res/assets/images/*,否则很大概编译不到
编译后生成APK是
out/target/product/K8/system/framework/framework-res.apk
framework-res.apk改为framework-res.zip可以解压看到一些源文件
=============
SPI和DSI有区别的配置:
1.lk
--- a/bootable/bootloader/lk/dev/gcdb/display/gcdb_display.c
+++ b/bootable/bootloader/lk/dev/gcdb/display/gcdb_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -216,6 +216,8 @@ bool gcdb_display_cmdline_arg(char *panel_name, char *pbuf, uint16_t buf_size)
} else {
if (target_is_edp())
default_str = "0:edp:";
+ /*else if (target_is_spi())
+ default_str = "0:spi:0";*/
else
default_str = "0:dsi:0:";
@@ -285,6 +287,57 @@ end:
return ret;
}
0:spi:0参数会传递给kernel,假如lk判断target_is_spi()为真则kernel不会匹配到dsi的屏幕
Kernel command line: sched_enable_hmp=0 console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom msm _rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk buildvariant=userdebug andr oidboot.bootdevice=7824900.sdhci androidboot.verifiedbootstate=orange androidboot.veritymode=enforcing androidboot.keymaster=1 androidboot .serialno=2e591f71 androidboot.baseband=msm mdss_mdp3.panel=0:dsi:0:
2.lk
diff --git a/bootable/bootloader/lk/target/msm8909/oem_panel.c b/bootable/bootloader/lk/target/msm8909/oem_panel.c
index ba54226..3765237 100644
--- a/bootable/bootloader/lk/target/msm8909/oem_panel.c
+++ b/bootable/bootloader/lk/target/msm8909/oem_panel.c
case UNKNOWN_PANEL:
default:
memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -573,9 +588,10 @@ int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
panel_id = AUO_H245QBN02_CMD_PANEL;
#elif defined(PANEL_LH154Q01_CMD)/* whl@pubtron.com.cn 20171012 */
panel_id = LH154Q01_CMD_PANEL;
+ //panel_id = GC9305_QVGA_SPI_CMD_PANEL;
#else
panel_id = AUO_CX_QVGA_CMD_PANEL;
- #endif
+ #endif
}
else
panel_id = HX8394D_480P_VIDEO_PANEL;
3.内核
diff --git a/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi b/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi
index 5fac90f..7474789 100644
--- a/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom/msm8909-mtp.dtsi
@@ -350,6 +350,7 @@
};
&mdss_mdp {
+ //qcom,mdss-pref-prim-intf = "spi";
qcom,mdss-pref-prim-intf = "dsi";
};
@@ -439,6 +440,15 @@
};
};
+&mdss_spi {
+ qcom,spi-pref-prim-pan = <&spi_gc9305_qvga_cmd>;
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_te_active>;
+ pinctrl-1 = <&mdss_te_suspend>;
+
+ qcom,platform-te-gpio = <&msm_gpio 24 0>;
+ qcom,platform-reset-gpio = <&msm_gpio 25 0>;
+ };
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_hx8394d_720_vid>;
1.对比和patch有差异的地方
(1)kernel/include/linux/mdss_io_util.h msm8909w代码enable_load/disable_load是放在load[DSS_REG_MODE_ENABLE]/load[DSS_REG_MODE_DISABLE]里
(2)内存管理接口有不一样的地方
=====================================
ubuntu下挂载远程文件体系/目次
sudo sshfs wanghl@192.168.1.46:/home/wanghl/work /home/whl/remote_server -o idmap=user -o allow_other
-----------------------------------------------------------------------------------------------------------
diff --git a/device/qcom/K8/init.target.rc b/device/qcom/K8/init.target.rc
index 7914bae..9574c73 100755
--- a/device/qcom/K8/init.target.rc
+++ b/device/qcom/K8/init.target.rc
@@ -147,12 +147,12 @@ service wcnss-service /system/bin/wcnss_service
group system wifi radio
oneshot
-service ppd /system/bin/mm-pp-daemon
- class late_start
- disabled
- user system
- socket pps stream 0660 system system
- group system graphics
+#service ppd /system/bin/mm-pp-daemon
+# class late_start
+# disabled
+# user system
+# socket pps stream 0660 system system
+# group system graphics
service per_mgr /system/bin/pm-service
动画在logcat报错
frameworks/base/cmds/bootanimation/BootAnimation.cpp:274: ALOGE("Get Carrier Animation file,since it's not support carrier");
logcat.txt:1395:01-01 01:12:49.071 649 973 E BootAnimation: Get Carrier Animation file,since it's not support carrier
logcat.txt:1396:01-01 01:12:49.072 649 973 E BootAnimation: Get Carrier Animation file,since it's not support carrier
-----------
录制视频:
adb root;adb remount;adb shell;
system/bin/screenrecord data/1.mp4 --time-limit 30
adb pull
========================
AFE4400血氧芯片
LED1 (IR) and LED2 (Red)
512HZ配合心电丈量PPG血压的时候,只上报LED1红外值,由于我们硬件只接了一个红外灯,没有接红光灯。
=========================================================================
H10 OTG调试:
根本流程,MSM8909的VBUS不带有输出5V的能力,所以必要增加外围提供5V输出的电路,
OTG设备插入之后,USB_ID硬件被拉低,USB驱动里的状态时机去拉高OTG_EN,使能外部的DC-DC电路输出5V给OTG设备供电,
同时硬件电路会断开模块VBUS与硬件VBUS的毗连。
1:串口实行cat /sys/kernel/debug/gpio
127|la2017:/ # cat /sys/kernel/debug/gpio
GPIOs 588-619, platform/qcom,smp2pgpio-ssr-smp2p-1-out.17, master-kernel:
GPIOs 620-651, platform/qcom,smp2pgpio-ssr-smp2p-1-in.16, slave-kernel:
GPIOs 652-683, platform/qcom,smp2pgpio-ssr-smp2p-4-out.15, master-kernel:
GPIOs 684-715, platform/qcom,smp2pgpio-ssr-smp2p-4-in.14, slave-kernel:
GPIOs 716-747, platform/qcom,smp2pgpio-smp2p-4-out.12, smp2p:
GPIOs 748-779, platform/qcom,smp2pgpio-smp2p-4-in.10, smp2p:
GPIOs 780-811, platform/qcom,smp2pgpio-smp2p-1-out.8, smp2p:
GPIOs 812-843, platform/qcom,smp2pgpio-smp2p-1-in.6, smp2p:
GPIOs 844-875, platform/qcom,smp2pgpio-smp2p-7-out.4, smp2p:
GPIOs 876-907, platform/qcom,smp2pgpio-smp2p-7-in.2, smp2p:
GPIOs 908-909, spmi/qpnp-pin-3, pm8909-gpio:
gpio-908 (hsusb-otg-vbus-en ) out hi->说明已经实行了拉高操纵!
GPIOs 910-910, spmi/qpnp-pin-2, pm8909-mpp:
GPIOs 911-1023, platform/1000000.pinctrl, msm_tlmm_gpio:
gpio-927 (mmr901xa_rpt ) in hi
gpio-928 (pump_vdd_en ) out hi
gpio-943 (bid0_gpio ) in lo
gpio-949 (7864900.sdhci cd ) in hi
gpio-999 ([auto] ) out hi
gpio-1001 (volume_up ) in hi
gpio-1002 (volume_down ) in hi
gpio-1005 (afe4400_gpio_int ) in lo
gpio-1009 (MLX_VDD_EN ) out hi
gpio-1010 (motor_ctrl_pin ) out lo」
2:从模块上量下pm8909_gpio1的电平
0.8V,正常应该是1.8V,说明PMU_GPIO_1的配置有问题
3:cat /sys/kernel/debug/msm_otg/otg_state
la2017:/ # cat /sys/kernel/debug/msm_otg/otg_state
a_wait_bcon,正常应该是a_host
4:打开usb干系动态log:
echo 8 > /proc/sys/kernel/printk
echo 'file phy-msm-usb.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'file udc-core.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'file ci13xxx_msm.c +p' > /sys/kernel/debug/dynamic_debug/control
拔出OTG设备再插入的LOG:
[ 496.087688] msm_otg_set_suspend(1) in a_wait_bcon state
[ 496.087915] host bus suspend
[ 496.087960] AFE4400 spi3.0: afe_spo2_suspend
[ 496.088522] mlx90615 1-005b: MLX90615_suspend
[ 496.088539] bma2x2-accel 1-0018: bma2x2_suspend
[ 496.088559] bma2x2-accel 1-0018: bma2x2_set_enable enable = 0
[ 496.091377] msm_otg 78d9000.usb: OTG PM suspend
[ 496.091396] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[ 496.114689] PM: suspend of devices complete after 38.744 msecs
[ 496.115998] PM: late suspend of devices complete after 1.288 msecs
[ 496.117662] PM: noirq suspend of devices complete after 1.650 msecs
[ 496.117675] Disabling non-boot CPUs ...
[ 496.121212] CPU0:msm_cpu_pm_enter_sleep mode:3 during suspend
[ 496.122047] Enabling non-boot CPUs ...
[ 496.123645] CPU3 is up
[ 496.124553] PM: noirq resume of devices complete after 0.888 msecs
[ 496.126428] PM: early resume of devices complete after 0.851 msecs
[ 496.131466] msm_otg 78d9000.usb: OTG PM resume
[ 496.131602] [15:14:50.405375] [000000031F5E7562] [VosRX] wlan: [E :WDI] WDTS_RxPacketDump RX Data frame is UC
[ 496.131626] [15:14:50.405403] [000000031F5E7769] [VosRX] wlan: [E :WDI] WDTS_RxPacketDump: Data subtype:8 SA:ec:88:8f:d2:a5:3e DA:b4:36:a9:4a:3a:21
[ 496.131688] [15:14:50.405464] [000000031F5E7C0C] [VosRX] wlan: [E :HDD] hdd_log_ip_addr: src addr 203:208:41:55
[ 496.131704] [15:14:50.405482] [000000031F5E7D57] [VosRX] wlan: [E :HDD] hdd_log_ip_addr: dst addr 192:168:119:112
[ 496.147569] bma2x2-accel 1-0018: bma2x2_resume
[ 496.147597] mlx90615 1-005b: MLX90615_resume
[ 496.147872] AFE4400 spi3.0: afe_spo2_resume
[ 496.148119] msm_otg_set_suspend(0) in a_wait_bcon state
[ 496.148144] msm_otg 78d9000.usb: OTG runtime resume
[ 496.148163] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x140,state=9
[ 496.173136] msm_otg 78d9000.usb: USB exited from low power mode
[ 496.238088] PM: resume of devices complete after 111.638 msecs
[ 496.411728] Restarting tasks ... [ 496.415650] msm_otg_set_suspend(0) in a_wait_bcon state
[ 496.421752] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
done.
[ 496.431183] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:0
[ 496.432479] msm_otg_set_suspend(1) in a_wait_bcon state
[ 496.432490] host bus suspend
[ 496.432558] a_wait_bcon work
[ 496.432579] msm_otg 78d9000.usb: OTG runtime idle
[ 496.432593] msm_otg 78d9000.usb: OTG runtime suspend
[ 496.432609] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[ 496.432616] msm_bam_device_lpm_ok: Going to LPM now
[ 496.432631] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x100,state=9
[ 496.432641] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x100,state=9
[ 496.432652] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[ 496.432659] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[ 496.432667] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x100,state=9
[ 496.432678] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x100,state=9
[ 496.432685] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x100,state=9
[ 496.432698] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 1
[ 496.432748] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x100,state=9
[ 496.432756] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x100,state=9
[ 496.535958] PM: suspend exit 2018-10-19 07:14:50.809728927 UTC
[ 496.539570] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x100,state=9
[ 496.539594] msm_otg 78d9000.usb: LPM caps = 90 flags = 12
[ 496.539601] msm_otg 78d9000.usb: USB in low power mode
[ 496.728120] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 496.873671] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 496.916184] PM: suspend entry 2018-10-19 07:14:51.189949083 UTC
[ 496.921089] PM: Syncing filesystems ... done.
[ 496.929747] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 496.934593] Freezing user space processes ... [ 496.943403] Error: returning -512 value
(elapsed 0.010 seconds) done.
[ 496.951584] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[ 496.962270] Suspending console(s) (use no_console_suspend to debug)
[ 496.982163] msm_otg_set_suspend(1) in a_wait_bcon state
[ 496.982177] host bus suspend
[ 496.982230] AFE4400 spi3.0: afe_spo2_suspend
[ 496.983513] mlx90615 1-005b: MLX90615_suspend
[ 496.983534] bma2x2-accel 1-0018: bma2x2_suspend
[ 496.983556] bma2x2-accel 1-0018: bma2x2_set_enable enable = 0
[ 496.989645] msm_otg 78d9000.usb: OTG PM suspend
[ 496.989670] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[ 496.997116] PM: suspend of devices complete after 26.876 msecs
[ 496.998413] PM: late suspend of devices complete after 1.284 msecs
[ 497.000389] PM: noirq suspend of devices complete after 1.963 msecs
[ 497.000405] Disabling non-boot CPUs ...
[ 497.004138] CPU0:msm_cpu_pm_enter_sleep mode:3 during suspend
[ 497.005617] Enabling non-boot CPUs ...
[ 497.007941] CPU2 is up
[ 497.009299] PM: noirq resume of devices complete after 1.326 msecs
[ 497.010150] OTG IRQ: 172 in LPM
[ 497.010242] PHY ID IRQ in LPM
[ 497.011695] PM: early resume of devices complete after 1.183 msecs
[ 497.016058] msm_otg 78d9000.usb: OTG PM resume
[ 497.016094] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x100,state=9
[ 497.036740] msm_otg 78d9000.usb: ID status_w
[ 497.036958] ID set
[ 497.037047] msm_otg 78d9000.usb: USB exited from low power mode
[ 497.061292] bma2x2-accel 1-0018: bma2x2_resume
[ 497.061331] mlx90615 1-005b: MLX90615_resume
[ 497.061708] AFE4400 spi3.0: afe_spo2_resume
[ 497.061842] msm_otg_set_suspend(0) in a_wait_bcon state
[ 497.138326] PM: resume of devices complete after 126.597 msecs
[ 497.276500] Restarting tasks ... [ 497.281161] msm_otg_set_suspend(0) in a_wait_bcon state
done.
[ 497.301774] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:1
[ 497.308398] PM: suspend exit 2018-10-19 07:15:35.050993076 UTC
[ 497.309521] a_wait_bcon work
[ 497.309540] (id && id_a/b/c) || a_bus_drop ||a_wait_bcon_tmout
[ 497.309563] deleting a_wait_vrise timer. remaining -1677 msec
[ 497.309581] msm_otg 78d9000.usb: host off
[ 497.309604] msm_hsusb_host msm_hsusb_host: remove, state 85
[ 497.309678] usb usb1: USB disconnect, device number 1
[ 497.330847] cma: dma_release_from_contiguous(pfn af0dc)
[ 497.330878] cma: dma_release_from_contiguous(pfn af0d5)
[ 497.330944] msm_hsusb_host msm_hsusb_host: USB bus 1 deregistered
[ 497.331558] starting a_wait_vfall timer
[ 497.333931] msm_otg_set_suspend(1) in a_wait_vfall state
[ 497.375857] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 497.516795] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 497.707974] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 497.833054] expired a_wait_vfall timer
[ 497.836872] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 497.843421] a_wait_vfall work
[ 497.846134] a_idle work
[ 497.848288] id && !id_a
[ 497.850790] b_idle work
[ 497.853146] chg_work cancel
[ 497.855938] msm_otg 78d9000.usb: OTG runtime suspend
[ 497.860885] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x1,state=1
[ 497.867210] msm_bam_device_lpm_ok: Going to LPM now
[ 497.871994] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x1,state=1
[ 497.878201] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x1,state=1
[ 497.883792] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[ 497.894907] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[ 497.901604] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x1,state=1
[ 497.907587] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x1,state=1
[ 497.912786] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x1,state=1
[ 497.918949] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[ 497.925116] USB PHY is in retention
[ 497.928757] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x1,state=1
[ 497.937090] msm_hsusb_ldo_enable: USB reg mode (2) (OFF/HPM/LPM)
[ 497.942094] msm_hsusb_config_vddcx: min_vol:0 max_vol:1200000
[ 497.948433] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x1,state=1
[ 497.970630] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x1,state=1
[ 497.975656] msm_otg 78d9000.usb: LPM caps = 90 flags = 30
[ 497.976193] PM: suspend entry 2018-10-19 07:15:35.718804117 UTC
[ 497.976824] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 497.982006] PM: Syncing filesystems ... done.
[ 497.999428] msm_otg 78d9000.usb: USB in low power mode
[ 498.000031] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 498.004386] Error: returning -512 value
[ 498.000087] Freezing user space processes ... (elapsed 0.067 seconds) done.
[ 498.073710] Freezing remaining freezable tasks ... (elapsed 0.004 seconds) done.
[ 498.084438] Suspending console(s) (use no_console_suspend to debug)
[ 498.105482] AFE4400 spi3.0: afe_spo2_suspend
[ 498.105977] mlx90615 1-005b: MLX90615_suspend
[ 498.105998] bma2x2-accel 1-0018: bma2x2_suspend
[ 498.106031] bma2x2-accel 1-0018: bma2x2_set_enable enable = 0
[ 498.110741] msm_otg 78d9000.usb: OTG PM suspend
[ 498.110767] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x1,state=1
[ 498.126138] PM: suspend of devices complete after 33.602 msecs
[ 498.127562] PM: late suspend of devices complete after 1.407 msecs
[ 498.129888] PM: noirq suspend of devices complete after 2.312 msecs
[ 498.129912] Disabling non-boot CPUs ...
[ 498.134808] CPU0:msm_cpu_pm_enter_sleep mode:3 during suspend
[ 498.135779] Enabling non-boot CPUs ...
[ 498.137331] CPU1 is up
[ 498.138210] PM: noirq resume of devices complete after 0.858 msecs
[ 498.138899] PHY ID IRQ in LPM
[ 498.139904] PM: early resume of devices complete after 0.819 msecs
[ 498.142115] msm_otg 78d9000.usb: OTG PM resume
[ 498.142138] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x1,state=1
[ 498.160833] msm_hsusb_ldo_enable: USB reg mode (3) (OFF/HPM/LPM)
[ 498.160850] msm_hsusb_config_vddcx: min_vol:1200000 max_vol:1200000
[ 498.160864] msm_otg_disable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[ 498.161072] USB PHY is exited from retention
[ 498.161149] msm_otg 78d9000.usb: ID status_w
[ 498.161359] ID clear
[ 498.161375] msm_otg 78d9000.usb: USB exited from low power mode
[ 498.178219] bma2x2-accel 1-0018: bma2x2_resume
[ 498.178245] mlx90615 1-005b: MLX90615_resume
[ 498.178513] AFE4400 spi3.0: afe_spo2_resume
[ 498.252493] PM: resume of devices complete after 112.570 msecs
[ 498.396348] Restarting tasks ... done.
[ 498.413979] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:1
[ 498.419808] b_idle work
[ 498.421722] !id || id_A
[ 498.424472] a_idle work
[ 498.427175] PM: suspend exit 2018-10-19 07:15:39.142090470 UTC
[ 498.432243] !a_bus_drop && (a_srp_det || a_bus_req)
[ 498.437967] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 498.444554] starting a_wait_vrise timer
[ 498.549024] expired a_wait_vrise timer
[ 498.551973] a_wait_vrise work
[ 498.554721] a_vbus_vld
[ 498.557184] msm_otg 78d9000.usb: host on
[ 498.560978] msm_hsusb_host msm_hsusb_host: EHCI Host Controller
[ 498.570474] msm_hsusb_host msm_hsusb_host: new USB bus registered, assigned bus number 1
[ 498.577888] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[ 498.586062] cma: dma_alloc_from_contiguous(): returned af0d5
[ 498.586202] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 498.598173] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[ 498.606200] cma: dma_alloc_from_contiguous(): returned af0dc
[ 498.610970] msm_hsusb_host msm_hsusb_host: irq 166, io mem 0x078d9000
[ 498.635883] msm_hsusb_host msm_hsusb_host: USB 2.0 started, EHCI 1.00
[ 498.641408] msm_otg_set_suspend(0) in a_wait_bcon state
[ 498.647185] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 498.653295] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 498.660850] usb usb1: Product: EHCI Host Controller
[ 498.665431] usb usb1: Manufacturer: Linux 3.10.49 ehci_hcd
[ 498.670828] usb usb1: SerialNumber: msm_hsusb_host
[ 498.682872] hub 1-0:1.0: USB hub found
[ 498.686299] hub 1-0:1.0: 1 port detected
[ 498.721426] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 498.786845] msm_otg_set_suspend(1) in a_wait_bcon state
[ 498.791063] host bus suspend
[ 498.794386] a_wait_bcon work
[ 498.797857] msm_otg 78d9000.usb: OTG runtime idle
[ 498.801553] msm_otg 78d9000.usb: OTG runtime suspend
[ 498.806647] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x100,state=9
[ 498.812913] msm_bam_device_lpm_ok: Going to LPM now
[ 498.818041] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x100,state=9
[ 498.823861] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x100,state=9
[ 498.830288] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[ 498.840645] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[ 498.847309] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x100,state=9
[ 498.853609] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x100,state=9
[ 498.859334] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x100,state=9
[ 498.865470] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 1
[ 498.866063] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 498.879215] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x100,state=9
[ 498.884873] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x100,state=9
[ 498.905926] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x100,state=9
[ 498.911025] msm_otg 78d9000.usb: LPM caps = 90 flags = 12
[ 498.911496] PM: suspend entry 2018-10-19 07:15:39.626414897 UTC
[ 498.914815] PM: Syncing filesystems ... done.
[ 498.927288] msm_otg 78d9000.usb: USB in low power mode
[ 498.927777] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 498.932673] Error: returning -512 value
[ 498.927810] Freezing user space processes ... (elapsed 0.032 seconds) done.
[ 498.966294] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[ 498.975776] Suspending console(s) (use no_console_suspend to debug)
根据以上log,高通总结如下:
Otg unplug:
[ 497.010242] PHY ID IRQ in LPM
[ 497.036958] ID set
[ 497.037047] msm_otg 78d9000.usb: USB exited from low power mode
[ 497.309581] msm_otg 78d9000.usb: host off
otg plug:
[ 498.161072] USB PHY is exited from retention
[ 498.161149] msm_otg 78d9000.usb: ID status_w
[ 498.161359] ID clear
[ 498.161375] msm_otg 78d9000.usb: USB exited from low power mode
[ 498.557184] msm_otg 78d9000.usb: host on
流程正常,但是没检测到从设备。
-------------------------------------------------------------------------
PM8909寄存器操纵GPIO,可以查PM8909的数据手册:80-np409-2x_c_pm8909_hardware_register_description_document_for_oems
拉高pm8909_gpio1
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 0x11 > data
echo 0x11 > data
echo 0xC040 > address
echo 0x11 > data
echo 0x11 > data
1.8V
拉低pm8909_gpio1:
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 0x10 > data
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 0x10 > data
0V
cd /sys/kernel/debug/spmi/spmi-0
echo 0xC040 > address
echo 1 > count
cat data
-----------------------------------------------------------
修改如下,OTG功能即正常:
wanghl@server:~/work/H10_msm8909_android$ git diff kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
diff --git a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
index 1c67a2da9e..803b4eb236 100755
--- a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909-pm8909-mtp.dtsi
@@ -52,8 +52,16 @@
&pm8909_gpios {
gpio@c000 { /* GPIO 1 */
- /* Battery UICC Alarm */
- status = "disabled";
+ /* OTG Otoscope add by whl@pubtron.com.cn @ 20181022 */
+ //status = "disabled";
+ qcom,mode = <1>; /* QPNP_PIN_MODE_DIG_OUT */
+ qcom,invert = <0>; /* QPNP_PIN_INVERT_DISABLE */
+ qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <0>; /* QPNP_PIN_VIN0,1,3 -> 1.8V, QPNP_PIN_VIN2 -> 1.2V */
+ qcom,out-strength = <3>; /* QPNP_PIN_OUT_STRENGTH_HIGH */
+ qcom,src-sel = <0>; /* QPNP_PIN_SEL_FUNC_CONSTANT */
+ qcom,master-en = <1>;
};
gpio@c100 { /* GPIO 2 */
wanghl@server:~/work/H10_msm8909_android$ git diff kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
diff --git a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
index 8d3fff081e..5467323250 100755
--- a/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
+++ b/kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
@@ -863,7 +863,8 @@
qcom,hsusb-otg-mpm-dpsehv-int = <49>;
qcom,hsusb-otg-mpm-dmsehv-int = <58>;
- qcom,hsusb-otg-vbus-en = <&pm8909_gpios 4 0>;
+ /* OTG Otoscope modify by whl@pubtron.com.cn @ 20181022 */
+ qcom,hsusb-otg-vbus-en = <&pm8909_gpios 1 0>;
qcom,msm-bus,name = "usb2";
qcom,msm-bus,num-cases = <3>;
------------------------------------------------------------
修改完之后,OTG耳窥镜正常工作的串口log:
插入:
[ 1326.018261] PHY ID IRQ in LPM
[ 1326.020464] msm_otg 78d9000.usb: OTG runtime resume
[ 1326.026045] msm_otg 78d9000.usb: LPM EXIT START:inputs=0x1,state=1
[ 1326.050242] msm_hsusb_ldo_enable: USB reg mode (3) (OFF/HPM/LPM)
[ 1326.056467] msm_hsusb_config_vddcx: min_vol:1200000 max_vol:1200000
[ 1326.063284] msm_otg_disable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[ 1326.069087] USB PHY is exited from retention
[ 1326.073299] msm_otg 78d9000.usb: ID status_w
[ 1326.077515] ID clear
[ 1326.079528] msm_otg 78d9000.usb: USB exited from low power mode
[ 1326.085882] b_idle work
[ 1326.087814] !id || id_A
[ 1326.091359] a_idle work
[ 1326.092787] !a_bus_drop && (a_srp_det || a_bus_req)
[ 1326.112908] starting a_wait_vrise timer
[ 1326.122082] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.215756] expired a_wait_vrise timer
[ 1326.218556] a_wait_vrise work
[ 1326.221659] a_vbus_vld
[ 1326.223795] msm_otg 78d9000.usb: host on
[ 1326.227694] msm_hsusb_host msm_hsusb_host: EHCI Host Controller
[ 1326.238294] msm_hsusb_host msm_hsusb_host: new USB bus registered, assigned bus number 1
[ 1326.246208] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.246562] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[ 1326.260474] cma: dma_alloc_from_contiguous(): returned af0d5
[ 1326.265603] cma: dma_alloc_from_contiguous(cma 00000000, count 1, align 0)
[ 1326.275071] cma: dma_alloc_from_contiguous(): returned af0dc
[ 1326.280743] msm_hsusb_host msm_hsusb_host: irq 166, io mem 0x078d9000
[ 1326.300254] msm_hsusb_host msm_hsusb_host: USB 2.0 started, EHCI 1.00
[ 1326.305780] msm_otg_set_suspend(0) in a_wait_bcon state
[ 1326.306007] portsc = 80000803
[ 1326.314459] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 1326.320990] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1326.327814] usb usb1: Product: EHCI Host Controller
[ 1326.333401] usb usb1: Manufacturer: Linux 3.10.49 ehci_hcd
[ 1326.338168] usb usb1: SerialNumber: msm_hsusb_host
[ 1326.345100] hub 1-0:1.0: USB hub found
[ 1326.347884] hub 1-0:1.0: 1 port detected
[ 1326.411838] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.528418] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.607954] portsc = 88001205
[ 1326.671267] usb 1-1: new high-speed USB device number 2 using msm_hsusb_host
[ 1326.681173] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.736442] portsc = 88001205
[ 1326.802103] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1326.873805] usb 1-1: New USB device found, idVendor=f007, idProduct=b999
[ 1326.879572] usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 1326.887717] usb 1-1: Product: Teslong Endoscope
[ 1326.914395] B_CONN set
[ 1326.915751] deleting a_wait_vrise timer. remaining -700 msec
[ 1326.920072] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1327.070314] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1327.145791] SELinux: initialized (dev fuse, type fuse), uses mountpoint labeling
拔出:
[ 1418.897633] portsc = 8c00100a
[ 1418.900740] PHY ID IRQ outside LPM
[ 1418.901761] usb 1-1: USB disconnect, device number 2
[ 1418.902982] B_CONN clear
[ 1418.904459] a_host work
[ 1418.904472] !b_conn
[ 1418.904488] deleting a_wait_vrise timer. remaining -92688 msec
[ 1418.921774] msm_otg 78d9000.usb: ID status_w
[ 1418.926223] ID set
[ 1418.928399] a_wait_bcon work
[ 1418.932604] (id && id_a/b/c) || a_bus_drop ||a_wait_bcon_tmout
[ 1418.937716] deleting a_wait_vrise timer. remaining -92721 msec
[ 1418.945315] msm_otg 78d9000.usb: host off
[ 1418.948327] msm_hsusb_host msm_hsusb_host: remove, state 1
[ 1418.954338] usb usb1: USB disconnect, device number 1
[ 1418.980360] msm_otg_set_suspend(1) in a_wait_bcon state
[ 1418.984581] host bus suspend
[ 1418.987742] msm_otg_set_suspend(0) in a_wait_bcon state
[ 1418.997637] cma: dma_release_from_contiguous(pfn af0dc)
[ 1419.002020] cma: dma_release_from_contiguous(pfn af0d5)
[ 1419.007130] msm_hsusb_host msm_hsusb_host: USB bus 1 deregistered
[ 1419.013636] msm_otg_set_suspend(1) in a_wait_bcon state
[ 1419.015170] starting a_wait_vfall timer
[ 1419.090964] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.291910] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.441944] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.515639] expired a_wait_vfall timer
[ 1419.518475] a_wait_vfall work
[ 1419.521477] a_idle work
[ 1419.523760] id && !id_a
[ 1419.526257] b_idle work
[ 1419.528618] chg_work cancel
[ 1419.531723] msm_otg 78d9000.usb: OTG runtime suspend
[ 1419.536358] msm_otg 78d9000.usb: LPM ENTER START:inputs=0x1,state=1
[ 1419.542668] msm_bam_device_lpm_ok: Going to LPM now
[ 1419.547469] msm_otg 78d9000.usb: LPM ENTER 1:inputs=0x1,state=1
[ 1419.550815] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.560980] msm_otg 78d9000.usb: LPM ENTER 2:inputs=0x1,state=1
[ 1419.566300] msm_otg 78d9000.usb: LPM ENTER 2:B_SESS_VLD=0,device_bus_suspend=0,dcp=0,prop_charger=0,floated_charger=0
[ 1419.576962] msm_otg 78d9000.usb: LPM ENTER 2:A_BUS_REQ=0,sm_work_busy=0
[ 1419.583639] msm_otg 78d9000.usb: LPM ENTER 3:inputs=0x1,state=1
[ 1419.589390] msm_otg 78d9000.usb: LPM ENTER 4:inputs=0x1,state=1
[ 1419.595530] msm_otg 78d9000.usb: LPM ENTER 6:inputs=0x1,state=1
[ 1419.601290] msm_otg_enable_phy_hv_int: bsv_id_hv = 1 dp_dm_hv_int = 0
[ 1419.607615] USB PHY is in retention
[ 1419.611370] msm_otg 78d9000.usb: LPM ENTER 7:inputs=0x1,state=1
[ 1419.617936] msm_hsusb_ldo_enable: USB reg mode (2) (OFF/HPM/LPM)
[ 1419.623538] msm_hsusb_config_vddcx: min_vol:0 max_vol:1200000
[ 1419.628702] msm_otg 78d9000.usb: LPM ENTER 8:inputs=0x1,state=1
[ 1419.643034] msm_otg 78d9000.usb: LPM ENTER 9:inputs=0x1,state=1
[ 1419.647951] msm_otg 78d9000.usb: LPM caps = 90 flags = 30
[ 1419.648284] PM: suspend entry 2018-10-22 07:59:26.416279999 UTC
[ 1419.659962] msm_otg 78d9000.usb: USB in low power mode
[ 1419.664982] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.672900] PM: Syncing filesystems ... done.
[ 1419.690784] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 1419.695635] Freezing user space processes ... [ 1419.704806] Error: returning -512 value
[ 1419.707912] last active wakeup source: eventpoll
[ 1419.712469]
[ 1419.713861] Freezing of tasks aborted after 0.012 seconds (196 tasks refusing to freeze, wq_busy=0):
[ 1419.723012]
[ 1419.724444] Restarting tasks ... done.
[ 1419.732239] msm_otg 78d9000.usb: OTG PM notify:4, sm_pending:0
[ 1419.737721] PM: suspend exit 2018-10-22 07:59:26.505714738 UTC
[ 1419.844143] PM: suspend entry 2018-10-22 07:59:26.612132759 UTC
[ 1419.849037] PM: Syncing filesystems ... done.
[ 1419.857303] msm_otg 78d9000.usb: OTG PM notify:3, sm_pending:0
[ 1419.862769] Freezing user space processes ... [ 1419.862874] IPC_RTR: msm_ipc_router_bind: pm-service Do not have permissions
[ 1419.877909] Error: returning -512 value
(elapsed 0.086 seconds) done.
[ 1419.962052] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[ 1419.971743] Suspending console(s) (use no_console_suspend to debug)
模组厂商增加了驱动去拉OTG_EN输出5V的代码:
kernel/drivers/usb/phy/phy-msm-usb.c
- static int msm_otg_vbus_power_on(bool on)//拉高拉低OTG_EN
- {
- struct msm_otg *msm_otg = the_msm_otg;
- if(gpio_is_valid(msm_otg->pdata->vbus_en_pin))
- {
- if(on)
- {
- gpio_direction_output(msm_otg->pdata->vbus_en_pin, 1);
- }
- else
- {
- gpio_direction_output(msm_otg->pdata->vbus_en_pin, 0);
- }
- return 0;
- }
- return -1;
- }
- static int msm_otg_probe(struct platform_device *pdev)
- {
- ...
- if(pdata->vbus_en_pin > 0)
- {
- if(!pdata->vbus_power)
- pdata->vbus_power = msm_otg_vbus_power_on;
- }
- ...
- }
- struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev)
- {
- ...
- pdata->vbus_en_pin = of_get_named_gpio(node, "qcom,hsusb-otg-vbus-en", 0);
- if(pdata->vbus_en_pin > 0)
- {
- res_gpio = gpio_request(pdata->vbus_en_pin, "hsusb-otg-vbus-en");//关联设备树文件:kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi
- if(res_gpio < 0)
- {
- pr_err("gpio_request hsusb-otg-vbus-en failed.\n");
- }
- }
- ...
- }
复制代码
kernel/arch/arm/boot/dts/qcom/sc806-evk/msm8909.dtsi:
qcom,hsusb-otg-vbus-en = <&pm8909_gpios 1 0>;//PMU_GPIO_1
======================================================================
K8小手机不毗连USB线到电脑,且不合盖子的情况下,屏幕本身休眠之后又本身唤醒的问题:
查看串口log:
1.打印所有级别log:
echo 8 > /proc/sys/kernel/printk
2.禁止串口进入休眠:
echo N > sys/module/printk/parameters/console_suspend
断开USB与电脑的毗连,主动休眠后的log
K8:/ # [ 341.229232] PM: suspend entry 1970-01-01 00:18:04.652428469 UTC
[ 341.234170] PM: Syncing filesystems ... done.
[ 341.253790] Freezing user space processes ...
[ 341.260215] Error: returning -512 value
[ 341.260924] PM: Wakeup pending, aborting suspend
[ 341.260994] last active wakeup source: eventpoll
[ 341.261016]
[ 341.261026] Freezing of tasks aborted after 0.003 seconds
[ 341.265349] Restarting tasks ... done.
[ 341.265593] PM: suspend exit 1970-01-01 00:18:04.688792271 UTC
[ 341.368118] PM: suspend entry 1970-01-01 00:18:04.791315917 UTC
[ 341.373074] PM: Syncing filesystems ... done.
[ 341.379457] Freezing user space processes ...
[ 341.383976] Error: returning -512 value
[ 341.388896] (elapsed 0.006 seconds) done.
[ 341.391869] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[ 341.418843] K8_keypad_suspend
[ 341.420883] K8_keypad_goto_sleep[ 341.424623] i2c-msm-v2 78b5000.i2c: msm_bus_scale_register_client(mstr-id:86):0x11 (ok)
[ 341.441536] PM: suspend of devices complete after 39.335 msecs
[ 341.448329] PM: late suspend of devices complete after 1.983 msecs
[ 341.456925] PM: noirq suspend of devices complete after 3.346 msecs
[ 341.462246] Disabling non-boot CPUs ...
[ 341.466720] migrate_irqs: 630 callbacks suppressed
[ 341.466726] IRQ0 no longer affine to CPU3
[ 341.466733] IRQ1 no longer affine to CPU3
[ 341.466738] IRQ2 no longer affine to CPU3
[ 341.466744] IRQ3 no longer affine to CPU3
[ 341.466749] IRQ4 no longer affine to CPU3
[ 341.466755] IRQ5 no longer affine to CPU3
[ 341.466761] IRQ6 no longer affine to CPU3
[ 341.466766] IRQ7 no longer affine to CPU3
[ 341.466772] IRQ8 no longer affine to CPU3
[ 341.466778] IRQ9 no longer affine to CPU3
[ 341.467908] CPU3: shutdown
[ 341.515869] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//正常灭屏幕后log打到这里,
//但是一会儿马上又唤醒打了以下的log
[ 341.516064] Enabling non-boot CPUs ...
[ 341.519232] CPU3: Booted secondary processor
[ 341.519970] CPU3 is up
[ 341.526583] PM: noirq resume of devices complete after 1.002 msecs
[ 341.533318] PM: early resume of devices complete after 1.101 �[ 341.541481] gpio_keys_resume
[ 341.543425] gpio_keys_report_state
[ 341.546729] gpio_keys_report_state
[ 341.550235] gpio_keys_report_state
[ 341.553502] away from hall switch,wakeup//kernel/drivers/input/keyboard/gpio_keys.c 驱动又上报了一次WAKE_UP按键事件
[ 341.559551] K8_keypad_resume
[ 341.561450] K8_keypad_wakeup[ 341.635291] PM: resume of devices complete after 96.810 msecs
[ 341.642193] Restarting tasks ... done.
[ 341.650492] PM: suspend exit 1970-01-01 00:18:09.141911383 UTC
[ 341.758332] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
发现是gpio_keys_report_state函数调用了gpio_keys_gpio_report_event进行的上报,gpio_keys_gpio_report_event又是由gpio_keys_resume调用引起的。
正常翻开盖子的时候log如下:
[ 616.257782] Enabling non-boot CPUs ...
[ 616.261085] CPU3: Booted secondary processor
[ 616.261820] CPU3 is up
[ 616.268425] PM: noirq resume of devices complete after 0.999 msecs
[ 616.275333] PM: early resume of devices complete after 1.105 m�[ 616.283851] gpio_keys_resume
[ 616.285796] gpio_keys_report_state
[ 616.289099] gpio_keys_report_state
[ 616.292712] gpio_keys_report_state
[ 616.295864] approach hall switch,sleep
[ 616.302899] K8_keypad_resume
[ 616.304747] K8_keypad_wakeup[ 616.379184] PM: resume of devices complete after 98.533 msecs
[ 616.385566] Restarting tasks ... done.
[ 616.393697] PM: suspend exit 1970-01-01 00:23:03.197882410 UTC
[ 616.500630] PM: suspend entry 1970-01-01 00:23:03.304811212 UTC
[ 616.505523] PM: Syncing filesystems ... done.
[ 616.521108] Freezing user space processes ...
[ 616.527270] Error: returning -512 value
[ 616.532500] (elapsed 0.008 seconds) done.
[ 616.535474] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[ 616.561780] K8_keypad_suspend
[ 616.563716] K8_keypad_goto_sleep[ 616.575923] PM: suspend of devices complete after 30.244 msecs
[ 616.582888] PM: late suspend of devices complete after 1.996 msecs
[ 616.591384] PM: noirq suspend of devices complete after 3.340 msecs
[ 616.596637] Disabling non-boot CPUs ...
[ 616.602259] CPU3: shutdown
[ 616.604704] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
[ 616.604910] Enabling non-boot CPUs ...
[ 616.608075] CPU3: Booted secondary processor
[ 616.608857] CPU3 is up
[ 616.615493] PM: noirq resume of devices complete after 0.997 msecs
[ 616.622443] PM: early resume of devices complete after 1.100 m�[ 616.630841] gpio_keys_resume
[ 616.632787] gpio_keys_report_state//这里会调用gpio_keys_gpio_report_event上报
[ 616.636090] gpio_keys_report_state
[ 616.639470] gpio_keys_report_state
[ 616.642993] gpio_keys_gpio_work_func//这里会调用gpio_keys_gpio_report_event上报
[ 616.646418] away from hall switch,wakeup//第一次上报翻盖事件
[ 616.650402] away from hall switch,wakeup//第二次上报翻盖事件
[ 616.657223] K8_keypad_resume
[ 616.659072] K8_keypad_wakeup[ 616.735058] PM: resume of devices complete after 107.343 msecs
[ 616.741507] Restarting tasks ... done.
[ 616.748687] PM: suspend exit 1970-01-01 00:23:29.574660055 UTC
所以可以把异常调用gpio_keys_report_state上报翻盖事件的地方注释掉,规避这个问题,也就是在gpio_keys_resume里注释掉gpio_keys_report_state,正常翻盖不会受到影响,由于
还有gpio_keys_gpio_work_func会去上报翻盖事件。缘故原由大概是体系休眠的时候没有休眠乐成,会resume起来尝试第二次休眠,结果gpio_keys_resume就resume起来把WAKEUP按键报上去了,体系就
点亮屏幕,体系不绝睡不下去,就不断的灭屏再亮屏。
--------------------------------------------------------
修改完之后,不接USB线,主动灭屏的log:
K8:/ # [ 424.051754] PM: suspend entry 1970-01-01 00:49:04.809607142 UTC
[ 424.056646] PM: Syncing filesystems ... done.
[ 424.132267] Freezing user space processes ...
[ 424.138592] Error: returning -512 value
[ 424.138624] PM: Wakeup pending, aborting suspend
[ 424.138693] last active wakeup source: eventpoll
[ 424.138715]
[ 424.138724] Freezing of tasks aborted after 0.003 seconds
[ 424.141386] Restarting tasks ... done.
[ 424.141590] PM: suspend exit 1970-01-01 00:49:04.899447506 UTC
[ 424.243332] PM: suspend entry 1970-01-01 00:49:05.001186725 UTC
[ 424.248222] PM: Syncing filesystems ... done.
[ 424.255580] Freezing user space processes ...
[ 424.260015] Error: returning -512 value
[ 424.265075] (elapsed 0.006 seconds) done.
[ 424.268049] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[ 424.295419] K8_keypad_suspend
[ 424.297353] K8_keypad_goto_sleep[ 424.310780] PM: suspend of devices complete after 32.348 msecs
[ 424.317557] PM: late suspend of devices complete after 1.968 msecs
[ 424.326167] PM: noirq suspend of devices complete after 3.347 msecs
[ 424.331464] Disabling non-boot CPUs ...
[ 424.335956] migrate_irqs: 1270 callbacks suppressed
[ 424.335962] IRQ0 no longer affine to CPU3
[ 424.335968] IRQ1 no longer affine to CPU3
[ 424.335973] IRQ2 no longer affine to CPU3
[ 424.335979] IRQ3 no longer affine to CPU3
[ 424.335985] IRQ4 no longer affine to CPU3
[ 424.335990] IRQ5 no longer affine to CPU3
[ 424.335995] IRQ6 no longer affine to CPU3
[ 424.336001] IRQ7 no longer affine to CPU3
[ 424.336007] IRQ8 no longer affine to CPU3
[ 424.336012] IRQ9 no longer affine to CPU3
[ 424.337124] CPU3: shutdown
[ 424.384767] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//第一次睡
[ 424.384962] Enabling non-boot CPUs ...//又起来了
[ 424.388122] CPU3: Booted secondary processor
[ 424.388853] CPU3 is up
[ 424.395482] PM: noirq resume of devices complete after 0.989 msecs
[ 424.402343] PM: early resume of devices complete after 1.088 �[ 424.410628] gpio_keys_resume//虽然调用,但是注释掉了上报,就不会再上报WAKEUP事件
[ 424.415367] K8_keypad_resume
[ 424.417217] K8_keypad_wakeup[ 424.492404] PM: resume of devices complete after 84.896 msecs
[ 424.500452] Restarting tasks ... done.
[ 424.509145] PM: suspend exit 1970-01-01 00:49:09.333290785 UTC
[ 424.616406] PM: suspend entry 1970-01-01 00:49:09.440550576 UTC
[ 424.621411] PM: Syncing filesystems ... done.
[ 424.627693] Freezing user space processes ...
[ 424.633948] Error: returning -512 value
[ 424.638873] (elapsed 0.007 seconds) done.
[ 424.641846] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[ 424.669867] K8_keypad_suspend
[ 424.671804] K8_keypad_goto_sleep[ 424.684245] PM: suspend of devices complete after 32.246 msecs
[ 424.691159] PM: late suspend of devices complete after 2.098 msecs
[ 424.699752] PM: noirq suspend of devices complete after 3.438 msecs
[ 424.705005] Disabling non-boot CPUs ...
[ 424.710754] CPU3: shutdown
[ 424.713204] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//第二次睡下乐成,
//后面也不会再唤醒,不会再有其他log,除非按POWER键唤醒
-----------------------------------------------------------------------------------------
修改完之后,手动翻盖唤醒log:
[ 446.164109] Enabling non-boot CPUs ...
[ 446.167269] CPU3: Booted secondary processor
[ 446.167996] CPU3 is up
[ 446.174590] PM: noirq resume of devices complete after 0.986 msecs
[ 446.181453] PM: early resume of devices complete after 1.115 �[ 446.189639] gpio_keys_resume//不上报
[ 446.194193] K8_keypad_resume
[ 446.196040] K8_keypad_wakeup[ 446.199543] gpio_keys_gpio_work_func//只剩下这次有效上报
[ 446.202639] away from hall switch,wakeup//只报一次
[ 446.278385] PM: resume of devices complete after 91.765 msecs
[ 446.284939] Restarting tasks ...
[ 446.304268] healthd: battery l=98 v=3969 t=28.0 h=2 st=3 c=-4 chg=
[ 446.315530] done.
[ 446.320480] PM: suspend exit 1970-01-01 00:53:07.192713505 UTC
[ 446.352997] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
===============================================================================================================================================================
void gr_fb_blank(bool blank); /* panel power on/off */
static void fbdev_blank(minui_backend* backend __unused, bool blank)
{
int ret;
ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
if (ret < 0)
perror("ioctl(): blank");
}
android recovery mode debug notes on msm8909 platform
https://blog.csdn.net/ic_soc_arm_robin/article/details/71652423
高通LCD之亮灭屏过程简析
https://blog.csdn.net/liwei16611/article/details/52830697
ioctl命令
FB_BLANK_POWERDOWN 是灭屏操纵; MDSS_EVENT_PANEL_OFF MDSS_PANEL_POWER_OFF MDSS_EVENT_BLANK
FB_BLANK_UNBLANK 是亮屏操纵; MDSS_EVENT_PANEL_ON MDSS_PANEL_POWER_ON MDSS_EVENT_UNBLANK
make recoveryimage同时也会编译bootimage,
假如修改recovery的内容,不能单单编译recovery,
同时要编译kernel,
否则kenel的驱动在recovery下被调用的时候并不会被更新。
======================================================================
recovery打开串口log:
1.修改TEMPORARY_LOG_FILE:"/tmp/recovery.log"为"/dev/ttyHSL0"
diff --git a/bootable/recovery/recovery.cpp b/bootable/recovery/recovery.cpp
index 320df59080..edac3d16ca 100755
--- a/bootable/recovery/recovery.cpp
+++ b/bootable/recovery/recovery.cpp
@@ -115,7 +115,9 @@ static const char *CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
static const char *CACHE_ROOT = "/cache";
static const char *DATA_ROOT = "/data";
static const char *SDCARD_ROOT = "/sdcard";
-static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
+//static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
+static const char *TEMPORARY_LOG_FILE = "/dev/ttyHSL0";
但是只修改以上log会提示权限问题,
[ 18.418291] audit: type=1400 audit(12392.159:10): avc: denied { append } for pid=294 comm="recovery" name="ttyHSL0" dev="tmpfs" ino=3616 scontext=u:r:recovery:s0 tcontext=u bject_r:console_device:s0 tclass=chr_file permissive=0
[ 18.466362] init: Service 'recovery' (pid 293) killed by signal 13
[ 18.471565] init: Service 'recovery' (pid 293) killing any children in process group
重要是由于是selinux的问题
2.device/qcom/K8/BoardConfig.mk添加BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
diff --git a/device/qcom/K8/BoardConfig.mk b/device/qcom/K8/BoardConfig.mk
index 0d1c71cdf4..e62c6d599f 100755
--- a/device/qcom/K8/BoardConfig.mk
+++ b/device/qcom/K8/BoardConfig.mk
@@ -109,7 +109,7 @@ ifeq ($(HOST_OS),linux)
endif
endif
-BOARD_KERNEL_CMDLINE := console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk
+BOARD_KERNEL_CMDLINE := console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk androidboot.selinux=permissive
修改device/qcom/K8/BoardConfig.mk是比较暴力的方式,像定制小手机就出现了显示不正常或其他未知问题,会把kernel的selinux也关了,但是如许就可以printf打印串口信息了。
最好还是使用第二种方法:
diff --git a/bootable/recovery/recovery.cpp b/bootable/recovery/recovery.cpp
index 82d64ca..e3cd48f 100755
--- a/bootable/recovery/recovery.cpp
+++ b/bootable/recovery/recovery.cpp
@@ -109,7 +109,7 @@ static const char *CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
static const char *CACHE_ROOT = "/cache";
static const char *DATA_ROOT = "/data";
static const char *SDCARD_ROOT = "/sdcard";
-static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
+static const char *TEMPORARY_LOG_FILE = "/dev/console";//或改成/dev/ttyHSL0(真实串口设备)也可以
static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";
3.修改selinux权限文件device/qcom/msm8909w/sepolicy/common/recovery.te
diff --git a/device/qcom/msm8909w/sepolicy/common/recovery.te b/device/qcom/msm8909w/sepolicy/common/recovery.te
index c83bc974b2..1014737747 100644
--- a/device/qcom/msm8909w/sepolicy/common/recovery.te
+++ b/device/qcom/msm8909w/sepolicy/common/recovery.te
@@ -16,4 +16,5 @@ recovery_only(`
allow recovery sg_device:chr_file rw_file_perms;
allow recovery self:capability sys_rawio;
allow recovery sg_device:chr_file ioctl;
+ allow recovery console_device:chr_file rw_file_perms;
')
增补:
system/sepolicy/file_contexts:66:/dev/console u bject_r:console_device:s0
system/core/init/init.cpp:78:std::string console_name = "/dev/console";
可以看出/dev/console就是一个console_device
device/qcom/msm8909w/sepolicy/common/file_contexts:36:/dev/ttyHSL0 u bject_r:console_device:s0
/dev/ttyHSL0也是一个console_device,所以static const char *TEMPORARY_LOG_FILE 改成 "/dev/ttyHSL0";这种方法也可以。
改完必要全编,否则不生效
===================================
充电口vid和pid
Bus 001 Device 122: ID 05c6:f000 Qualcomm, Inc.
===============================================
SPI屏幕数据发送接口:
平凡模式发送SPI数据:
mdss_spi_panel_kickoff(mdp3_session->panel,
(void *)(int)data->addr,//-495185920
(int)data->len,//122880
stride);//stride = mdp3_session->dma->source_config.stride = 512
recovery模式发送SPI数据:
mdss_spi_panel_kickoff(mdp3_session->panel,
(void *)(int)(mfd->fbi->screen_base + offset),
(int)fbi->fix.smem_len,//smemlen = 245760,由于双缓存:fix.smem_len = 240*512*2 = 245760
stride);//stride = fbi->fix.line_length = 512
调试留意事项:
(1)
在recovery模式下,假如要防止死机后重复进入recovery模式,可以屏蔽掉get_args(&argc, &argv);由于这句会调用write_bootloader_message写
"boot-recovery"和"recovery\n"到misc分区的command和recovery字段,直到调用finish_recovery() 才会被清除,所以假如还没跑到finish_recovery()就死机,下次还是会进入recovery模式。
struct bootloader_message {
char command[32];
char status[32];
char recovery[768];
// The 'recovery' field used to be 1024 bytes. It has only ever
// been used to store the recovery command line, so 768 bytes
// should be plenty. We carve off the last 256 bytes to store the
// stage string (for multistage packages) and possible future
// expansion.
char stage[32];
char slot_suffix[32];
char reserved[192];
};
(2)recovery模式下抓死机的dump信息和正常抓dump信息一样,CONFIG_MSM_DLOAD_MODE开关默认就是打开的,必要将CONFIG_MAGIC_SYSRQ = y也打开
It's same as normal mode. System will enter into dump mode if you enable it before.
How to make device enter download mode:
1. first you should have CONFIG_MAGIC_SYSRQ = y and CONFIG_MSM_DLOAD_MODE=y enabled when building kernel
2. enable download mode
echo 1 > /sys/module/restart/parameters/download_mode #我们的msm8909w体系没有这个目次,但是不影响QPST抓dump信息
echo 1 > /sys/module/msm_poweroff/parameters/download_mode
3. echo 1 > /proc/sys/kernel/sysrq #我们的msm8909w体系没有这个目次,也不影响QPST抓dump信息
4. make system enter into dump mode
echo c > /proc/sysrq-trigger
it would trigger panic and device would go into dump mode.
调试recovery显示过程中出现了两个重要问题:1.死机 2.发送SPI数据总是超时,没有显示。办理这两个问题SPI屏幕就能在recovery模式下正常显示了
1.死机问题,通过QCAP分析dump数据可以看到问题处在kenel crash上面(dmesg log):
9.150236: <6> ===MDSS_EVENT_PANEL_ON===
9.295802: <2> Division by zero in kernel.
9.295812: <6> ------------[ cut here ]------------
9.295818: <6> kernel BUG at /home/whl/work/msm8909w_law_android/kernel/arch/arm/kernel/traps.c:855!
9.295822: <6> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
9.295830: <2> Modules linked in:
9.295837: <6> CPU: 0 PID: 266 Comm: recovery Not tainted 3.18.24 #255
9.295843: <6> task: dce60000 ti: dba28000 task.ti: dba28000
9.295854: <2> PC is at __div0+0xc/0x14
9.295860: <2> LR is at __div0+0xc/0x14
9.295866: <2> pc : [<c0011b10>] lr : [<c0011b10>] psr: 600b0013 sp : dba29cd8 ip : 0000000b fp : 00000001
9.295869: <2> r10: 00000000 r9 : 00000000 r8 : 00010000
9.295874: <2> r7 : dc456290 r6 : dbf60800 r5 : dba29e30 r4 : dbf60800
9.295878: <2> r3 : 00000000 r2 : 00000000 r1 : 200b0013 r0 : 0000001b
9.295883: <2> Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
9.295888: <2> Control: 10c5387d Table: 9ba3006a DAC: 00000015
9.295892: <6> Process recovery (pid: 266, stack limit = 0xdba28238)
9.295896: <6> Stack: (0xdba29cd8 to 0xdba2a000)
........................
9.296136: <2> [<c0011b10>] (__div0) from [<c026a250>] (Ldiv0+0x8/0x10)
9.296152: <2> [<c026a250>] (Ldiv0) from [<c03276a0>] (mdss_fb_var_to_panelinfo+0xb0/0xd8)
9.296165: <2> [<c03276a0>] (mdss_fb_var_to_panelinfo) from [<c0328390>] (mdss_fb_check_var+0x2dc/0x338)
9.296177: <2> [<c0328390>] (mdss_fb_check_var) from [<c02a4ee0>] (fb_set_var+0x168/0x330)
9.296188: <2> [<c02a4ee0>] (fb_set_var) from [<c02a529c>] (do_fb_ioctl+0x194/0x5dc)
9.296200: <2> [<c02a529c>] (do_fb_ioctl) from [<c01384e0>] (do_vfs_ioctl+0x480/0x57c)
9.296210: <2> [<c01384e0>] (do_vfs_ioctl) from [<c0138628>] (SyS_ioctl+0x4c/0x74)
9.296221: <2> [<c0138628>] (SyS_ioctl) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
9.296230: <6> Code: c0bc9d60 e92d4008 e59f0004 eb24dc86 (e7f001f2)
9.296235: <6> ---[ end trace d06f2bd2169e5490 ]---
发现有除0操纵导致体系崩溃,详细调用位置是体系调用do_fb_ioctl,从而调用了fb_set_var函数,终极调用了mdss_fb_var_to_panelinfo函数,该函数
出现了除零操纵。详细流程是在recovery模式下bootable/recovery/recovery.cpp的main()函数跑到 ui->Init();的时候调用了void ScreenRecoveryUI::Init(),
里面调用了gr_init();gr_init()里实行了open_fbdev并进行了相应的初始化static GRSurface* fbdev_init(minui_backend* backend),该函数打开了
/dev/graphics/fb0设备并通过ioctl获取了屏幕的参数FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO并进行了mmap内存映射都没有问题,并支持了double_buffered
双缓存,但是在跑到set_displayed_framebuffer(0);设置参数的时候出了问题:该函数调用了ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi);于是就会调用到内核的
kernel/drivers/video/fbdev/core/fbmem.c的ioctl的处置惩罚函数:
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg, struct file *file)
在该函数的FBIOPUT_VSCREENINFO的case分支里调用了fb_set_var(info, &var);函数,这就和死机log的堆栈信息对应上了,fb_set_var里调用了info->fbops->fb_check_var,这个实际上从高通屏幕的驱动kernel/drivers/video/msm/mdss/mdss_fb.c可以看出是调用了.fb_check_var = mdss_fb_check_var, /* vinfo check */函数,进入该函数发现是mdss_fb_check_var又调用了mdss_fb_var_to_panelinfo,该函数将fb_var_screeninfo信息传给了mdss_panel_info
pinfo->xres = var->xres;
pinfo->yres = var->yres;
pinfo->lcdc.v_front_porch = var->lower_margin;
pinfo->lcdc.v_back_porch = var->upper_margin;
pinfo->lcdc.v_pulse_width = var->vsync_len;
pinfo->lcdc.h_front_porch = var->right_margin;
pinfo->lcdc.h_back_porch = var->left_margin;
pinfo->lcdc.h_pulse_width = var->hsync_len;
这些也没有问题,并且从log可以看到打印出来也是对的,和dtsi的设置对应上的,但是跑到
pinfo->clk_rate = PICOS2KHZ(var->pixclock) * 1000;
这句就出问题了,由于对于SPI 屏幕来说,var->pixclock打印出来的值是0,所以实行
#define PICOS2KHZ(a) (1000000000UL/(a))
就出现了PICOS2KHZ(0)除0操纵,体系就崩溃了。
对于定制小手机 mipi屏幕(240*432)来说,var->pixclock = 5446,pinfo->clk_rate算出来是183621006(180多M)
所以这里对SPI屏幕强行设置一个clkrate:
pinfo->clk_rate = PICOS2KHZ(66666) * 1000;
pr_info("===spi pinfo->clk_rate = %lld===\n", pinfo->clk_rate); //15M多
或者直接加一个判断条件:
if(var->pixclock != 0)
pinfo->clk_rate = PICOS2KHZ(var->pixclock) * 1000;
不进行pinfo->clk_rate的设置也可以,这里采用第二种方法。
2.发送数据30S超时:
[ 9.652811] ===fb_set_var===
[ 9.652812] ===fb_pan_display===
[ 9.652816] mdss_fb_pan_display: ===mdss_fb_pan_display===
[ 9.652818] mdss_fb_pan_display_ex: ===mdss_fb_pan_display_ex===
[ 39.650119] mdss_fb_wait_for_kickoff: mdss_fb_pan_display_ex+0x90/0x22c: wait for kickoff timeout koff=1 commits=0
[ 39.650135] mdp3_runtime_resume:2990 =>[0 :1026764 : 1026764][1 ]:1111
[ 39.650143] mdp3_footswitch_ctrl:2697 =>[1 :1026767 : 3][1 ]:1
[ 39.650151] mdp3_clk_update:448 =>[2 :1026840 : 73][1 ]:1
[ 39.650159] mdp3_clk_update:456 =>[3 :1026868 : 28][1 ]:0
[ 39.650167] mdp3_runtime_suspend:3015 =>[4 :1026949 : 81][35 ]:1111
[ 39.650175] mdp3_footswitch_ctrl:2697 =>[5 :1026951 : 2][35 ]:0
[ 39.650184] mdp3_runtime_resume:2990 =>[6 :1035856 : 8905][1 ]:1111
[ 39.650192] mdp3_footswitch_ctrl:2697 =>[7 :1035859 : 3][1 ]:1
[ 39.650199] mdp3_clk_update:448 =>[8 :1035931 : 72][1 ]:1
[ 39.650209] mdp3_ctrl_on:861 =>[9 :8219429 : 7183498][267 ]:1111 35d 0
[ 39.650218] mdp3_ctrl_on:886 =>[10 :8490180 : 270751][267 ]:2222 376 0
[ 39.650228] mdp3_ctrl_off:1013 =>[11 :8511951 : 21771][267 ]:1111 3f5 0 0
[ 39.650237] mdp3_ctrl_off:1178 =>[12 :8800258 : 288307][267 ]:2222 49a
[ 39.650246] mdp3_ctrl_on:861 =>[13 :8834631 : 34373][267 ]:1111 35d 0
[ 39.650254] mdss_smmu_attach:120 =>[14 :8834668 : 37][267 ]:0
[ 39.650263] mdp3_ctrl_on:973 =>[15 :9390650 : 555982][267 ]:2222 3cd 0
[ 39.650272] __mdss_fb_display_thread:3585 =>[16 :9438156 : 47506][280 ]:0 1111
[ 39.650280] __mdss_fb_display_thread:3587 =>[17 :9520206 : 82050][280 ]:0 2222
[ 39.650284] ======== VBIF Debug bus DUMP =========
[ 39.650286] ======== NRT VBIF Debug bus DUMP =========
[ 39.650290] mdss_fb_pan_display_ex: wait_for_kick failed. rc=-110
体系每次革新数据调用fbdev_flip都会调用set_displayed_framebuffer(1-displayed_buffer);从而发送ioctl的FBIOPUT_VSCREENINFO命令,调用到
内核的对应的do_fb_ioctl的case分支,FBIOPUT_VSCREENINFO,从而调用到fb_set_var,它会调用fb_pan_display(info, &info->var);然后调用
info->fbops->fb_pan_display(),详细就会调用到高通的显示驱动
.fb_pan_display = mdss_fb_pan_display, /* pan display */
从而又调用到mdss_fb_pan_display_ex(info, &disp_commit);接着调用mdss_fb_wait_for_kickoff(mfd);打印出超时log
ret = wait_event_timeout(mfd->kickoff_wait_q,
(!atomic_read(&mfd->kickoff_pending) ||
mfd->shutdown_pending),
msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
if (!ret) {
pr_err("%pS: wait for kickoff timeout koff=%d commits=%d\n",
__builtin_return_address(0),
atomic_read(&mfd->kickoff_pending),
atomic_read(&mfd->commits_pending));
MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
"dbg_bus", "vbif_dbg_bus");
ret = -ETIMEDOUT;
} else if (mfd->shutdown_pending) {
pr_debug("Shutdown signalled\n");
ret = -ESHUTDOWN;
} else {
ret = 0;
}
查看wait_event_timeout - sleep until a condition gets true or a timeout elapses
可以看出只有条件为真,休眠才会跳出来,否则就不绝比及超时才跳出来,
缘故原由就在于atomic_read(&mfd->kickoff_pending)读出来是1(不绝在等候kickoff完成),!atomic_read(&mfd->kickoff_pending)不为真,mfd->shutdown_pending也不为真,查找代码发现这个变量只有在注册的时候mdss_fb_register设置为0:atomic_set(&mfd->kickoff_pending, 0);还有就是在mdss_fb_release_kickoff的时候设置为0,
static void mdss_fb_release_kickoff(struct msm_fb_data_type *mfd)
{
if (mfd->wait_for_kickoff) {
atomic_set(&mfd->kickoff_pending, 0);
wake_up_all(&mfd->kickoff_wait_q);
}
}
搜所这个函数可以发现他在两个地方被调用:
1.
__mdss_fb_sync_buf_done_callback函数里的
case MDP_NOTIFY_FRAME_CTX_DONE:
pr_info("===MDP_NOTIFY_FRAME_CTX_DONE===\n");
mdss_fb_release_kickoff(mfd);
break;
}
说明收到MDP_NOTIFY_FRAME_CTX_DONE关照的时候会去清零&mfd->kickoff_pending
2.
__mdss_fb_perform_commit
if (IS_ERR_VALUE(ret) || !sync_pt_data->flushed) {
pr_info("===mdss_fb_release_kickoff __mdss_fb_perform_commit===\n");
mdss_fb_release_kickoff(mfd);
mdss_fb_signal_timeline(sync_pt_data);
}
但是打印的log显示IS_ERR_VALUE(ret)为0,sync_pt_data->flushed为1,条件不满足
3.__mdss_fb_display_thread
while (1) {
wait_event(mfd->commit_wait_q,
(atomic_read(&mfd->commits_pending) ||
kthread_should_stop()));
if (kthread_should_stop())
break;
MDSS_XLOG(mfd->index, XLOG_FUNC_ENTRY);
ret = __mdss_fb_perform_commit(mfd);
MDSS_XLOG(mfd->index, XLOG_FUNC_EXIT);
atomic_dec(&mfd->commits_pending);
wake_up_all(&mfd->idle_wait_q);
}
pr_info("===mdss_fb_release_kickoff in __mdss_fb_display_thread===\n");
mdss_fb_release_kickoff(mfd);
这个是已经跳出整个内核显示线程了才释放清零,也清除.
所以只能是第一种情况,查找MDP_NOTIFY_FRAME_CTX_DONE发现问题出在mdp3_ctrl.c里的mdp3_ctrl_pan_display函数
if (mdp3_ctrl_get_intf_type(mfd) ==
MDP3_DMA_OUTPUT_SEL_SPI_CMD) {
stride = fbi->fix.line_length;
pr_info("addr = %x, smemlen = %d, stride = %d, offset = %x\n",
(int)mfd->iova, (int)fbi->fix.smem_len,
stride, (int)offset);
rc = mdss_spi_panel_kickoff(mdp3_session->panel,
(void *)(int)(mfd->fbi->screen_base + offset),
(int)fbi->fix.smem_len,
stride);
pr_info("===mdss_spi_panel_kickoff ret = %d===\n", rc);
} else {
rc = mdp3_session->dma->update(mdp3_session->dma,
(void *)(int)(mfd->iova + offset), mdp3_session->intf,
mdp3_session->first_commit, NULL);
}
/* This is for the previous frame */
if (rc < 0) {
pr_info("===MDP_NOTIFY_FRAME_TIMEOUT===\n");
mdp3_ctrl_notify(mdp3_session,
MDP_NOTIFY_FRAME_TIMEOUT);
} else {
pr_info("===MDP_NOTIFY_FRAME_DONE and MDP_NOTIFY_FRAME_CTX_DONE===\n");
if (mdp3_ctrl_get_intf_type(mfd) ==
MDP3_DMA_OUTPUT_SEL_DSI_VIDEO /*||
mdp3_ctrl_get_intf_type(mfd) ==
MDP3_DMA_OUTPUT_SEL_SPI_CMD*/) {
mdp3_ctrl_notify(mdp3_session,
MDP_NOTIFY_FRAME_DONE);
mdp3_ctrl_notify(mdp3_session,
MDP_NOTIFY_FRAME_CTX_DONE);
}
}
mdss_spi_panel_kickoff发完SPI数据之后,没有通过mdp3_ctrl_notify关照MDP_NOTIFY_FRAME_CTX_DONE事件完成,加上这个判断之后,显示就正常了。
当然recovery层要做RGBA8888到RGB565的格式转换,
至此,显示OK。
别的,mdp3_ctrl_pan_display是怎么革新数据的?
查看log:
[ 8.206292] ===fb_blank===
[ 8.206296] ===info->fbops->fb_blank(blank, info);===
[ 8.206300] mdss_fb_blank: ===5===
[ 8.206303] mdss_fb_blank_sub: ==mdss_fb_blank_sub==
[ 8.206308] mdss_fb_blank_unblank: ===mdss_fb_blank_unblank===
[ 8.206324] mdss_fb_start_disp_thread: ===mdss_fb_blank_unblank.part.27+0x110/0x26c: start display thread fb0
查看代码:
fbdev_init的末了会调用
fbdev_blank(backend, true);关闭显示
fbdev_blank(backend, false);打开显示
fbdev_blank调用了ioctl函数发送FBIOBLANK命令: ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
这个命令处置惩罚do_fb_ioctl里面会实行 fb_blank(info, arg);函数,接着调用(info->fbops->fb_blank),fb_blank又对应到高通驱动
.fb_blank = mdss_fb_blank, /* blank display */
然后调用mdss_fb_blank_sub,然后调用mdss_fb_blank_unblank,在mdss_fb_blank_unblank调用mdss_fb_start_disp_thread启用了一个内核线程:
mfd->disp_thread = kthread_run(__mdss_fb_display_thread,
mfd, "mdss_fb%d", mfd->index);
static int __mdss_fb_display_thread(void *data)
{
struct msm_fb_data_type *mfd = data;
int ret;
struct sched_param param;
/*
* this priority was found during empiric testing to have appropriate
* realtime scheduling to process display updates and interact with
* other real time and normal priority tasks
*/
param.sched_priority = 16;
ret = sched_setscheduler(current, SCHED_FIFO, ¶m);
if (ret)
pr_warn("set priority failed for fb%d display thread\n",
mfd->index);
while (1) {
wait_event(mfd->commit_wait_q,
(atomic_read(&mfd->commits_pending) ||
kthread_should_stop()));
if (kthread_should_stop())
break;
MDSS_XLOG(mfd->index, XLOG_FUNC_ENTRY);
ret = __mdss_fb_perform_commit(mfd);
MDSS_XLOG(mfd->index, XLOG_FUNC_EXIT);
atomic_dec(&mfd->commits_pending);
wake_up_all(&mfd->idle_wait_q);
}
pr_info("===mdss_fb_release_kickoff in __mdss_fb_display_thread===\n");
mdss_fb_release_kickoff(mfd);
atomic_set(&mfd->commits_pending, 0);
wake_up_all(&mfd->idle_wait_q);
return ret;
}
__mdss_fb_perform_commit里面就会调用mdss_fb_pan_display_sub实行mfd->mdp.dma_fnc(mfd);
它就对应了高通驱动:
mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
所以说recovery模式下的显示是通过mdp3_ctrl_pan_display不绝在革新数据,死循环不绝在跑。
=======================================================================================
高通开机logo要求:
图片资源必须为png,且色深为8-bit的RGB或者RGBA格式。
制作splash.img开机logo分区的脚本:device/qcom/msm8909w/common/display/logo/logo_gen.py
=======================================================================================
NV项说明:
MSM8953定制手机
NV项 定义
2499 NV_FACTORY_DATA_3_I
1943 MEID
550 IMEI
7233 OPTION
MSM8909W手表
2499 NV_FACTORY_DATA_3_I
1943 NV_MEID_I 7个字节
550 NV_UE_IMEI_I 9个字节
7233 OPTION 这一项我们不必要读,这个是做产测工具的同事用的,用来多次写MEID和IMEI,由于用QXDM写550和1943只能写一次,做产测工具的同事工厂写MEID和IMEI到7233项,底层再写到550和1943项
7234 NV_OEM_WATCH_INFO_I 此中dev_id占四个字节(CCF00015),akey占8个字节(4455DB91),qr_code占20个字节(0AD9F46F4B0872AC683E94717AB79676F4D9),实际写了18个字节,qxdm读不了这一项
7235 NV_OEM_CSS_URL_I 服务器地址128个字节,以ascii码字符串写入,所以不必要做格式转换,qxdm读不了这一项
adb shell am start -n com.android.dialer/.DialtactsActivity
打开拨号键盘,输入“*#06#”实际MEID和IMEI号码为:
MEID:A10000470107A5
QXDM查看1943项为meid:0xA10000470107A5(meid为uint64类型,56 bits/8 bit=7 byte),用户看起来就是14个字符
IMEI:869303030000218 用户看起来是15个字符
QXDM查看00550项:
ue_imei[0] 0x08 //长度
ue_imei[1] 0x8A //A不显示,从8开始显示
ue_imei[2] 0x96 //以下开始高低字节反序
ue_imei[3] 0x03
ue_imei[4] 0x03
ue_imei[5] 0x03
ue_imei[6] 0x00
ue_imei[7] 0x20
ue_imei[8] 0x81
qcril读回来ue_imei后要转成16进制字符串“088A96030303002081”再传到android应用层,然后应用层再做格式转化,否则上层调用方法nvReadItem读item ID的时候遇到0x00就会被截断了。所以NV_OEM_WATCH_INFO_I、NV_UE_IMEI_I、NV_OEM_WATCH_INFO_I都会有0x00的情况或大于127(上层显示不出来)的情况,所以必要做格式转换,NV_OEM_CSS_URL_I为服务器地址,以ascii字符串写入,所以不必要转格式。
===============================
原生Dialer(蓝色) 没有被overlay覆盖的就走这个工程
mmm packages/apps/Dialer/
out/target/product/MSM8909W/system/priv-app/Dialer/Dialer.apk
MSM8909W手表改过的Dialer(玄色)
mmm packages/apps/pubtron/MSM8909W/Dialer/
out/target/product/MSM8909W/system/priv-app/MSM8909WDialer/MSM8909WDialer.apk
===================================================================
MSM8909W手表 modem死机的缘故原由:MODEM - sns_smgr_sensor.c:307 config_odr - sensor=1 odr=16 status=7
log打印config_odr - sensor=1 是ACC传感器
status=7是SNS_DDF_EBUS, /**< Failure in the underlying bus or bus driver. */总线驱动的潜伏缘故原由导致
typedef enum
{
SNS_DDF_SUCCESS, /**< No error. */
SNS_DDF_PENDING, /**< Status cannot be provided immediately and will
be returned asynchronously instead. */
SNS_DDF_EFAIL, /**< Unspecified error. */
SNS_DDF_ENOMEM, /**< Insufficient memory to process the request. */
SNS_DDF_EINVALID_DATA, /**< Invalid data found in input buffer. */
SNS_DDF_EINVALID_PARAM, /**< Invalid value of an input parameter. */
SNS_DDF_EINVALID_ATTR, /**< Invalid attribute ID. */
SNS_DDF_EBUS, /**< Failure in the underlying bus or bus driver. */
SNS_DDF_EDEVICE, /**< Failure in the device. */
SNS_DDF_EDATA_BOUND, /**< One or more data samples are out-of-bound. */
SNS_DDF_EDEVICE_BUSY, /**< Device is busy and can't service the request. */
SNS_DDF_EINVALID_TEST, /**< Invalid test case requested for this device. */
SNS_DDF_EINVALID_DAF_REQ, /**< Invalid Driver Access request. */
SNS_DDF_ELAST
} sns_ddf_status_e;
代码出错的地方:
ddf_status = sns_smgr_set_attr(sensor_ptr, sensor_type, SNS_DDF_ATTRIB_ODR, &odr);//设置ODR的时候这里返回7:SNS_DDF_EBUS
if ( SNS_DDF_SUCCESS == ddf_status )
{
ddf_sensor_ptr->requested_odr = odr;
if ( SMGR_SENSOR_IS_SELF_SCHED(sensor_ptr) &&
!SMGR_SENSOR_FIFO_IS_ENABLE(sensor_ptr) )
{
if ( odr > 0 )
{
sns_smgr_update_ewur( FX_CONV_Q16(odr,0), FX_CONV_Q16(ddf_sensor_ptr->current_odr,0),
sensor_ptr->is_uimg_refac,
!sns_smgr_ddf_sensor_is_event_sensor(ddf_sensor_ptr) );
/* trigger self schedule */
sns_smgr_dd_enable_sched_data(sensor_ptr, sensor_type, true);
}
else
{
sns_smgr_update_ewur( 0, FX_CONV_Q16(ddf_sensor_ptr->current_odr,0),
sensor_ptr->is_uimg_refac,
!sns_smgr_ddf_sensor_is_event_sensor(ddf_sensor_ptr) );
/* stops streaming */
sns_smgr_dd_enable_sched_data(sensor_ptr, sensor_type, false);
}
}
}
//高通的措施是else if ( (SNS_DDF_EBUS != ddf_status) && (SNS_DDF_EDEVICE != ddf_status) ),让其不要产生fatal err
else if ( (SNS_DDF_EBUS != ddf_status) || (SNS_DDF_EDEVICE != ddf_status) )
{
/* should not fail */
ERR_FATAL("config_odr - sensor=%u odr=%u status=%u",
sensor_type, odr, ddf_status);
}
======================================================================================================================
关于屏幕送显示数据与TE信号的同步问题:
画面革新有残留(tearing effect,即TE)的问题。根本缘故原由是主控写图像数据的速率与LCM刷屏的速率差别等造成的,详细是刷屏速率要快于主控写速率。好在很多LCM驱动芯片都有一个Fmark脚,用来与主控同步,当Fmark发出一个信号给主控时,主控才开始写一帧数据,如许就可以保证两边同步。所以屏幕革新数据的时候必要等候TE中断信号到来了才能革新数据,假如TE信号没来就等候。假如TE信号来了就在中断处置惩罚函数里去唤醒一个完成量,通过函数
complete(struct completion *x);//(1)x->done++,(2)唤醒一个处于等候该完成量x的历程或线程
唤醒正在处于等候的革新屏幕数据的历程或线程
革新数据的函数里就不绝在等候这个完成量被唤醒,革新函数里其实必要做三件事情:
1.使能TE中断
2.动态将完成量清零,通过动态初始化:void init_completion(struct completion *x);//x->done=0;
3.进入等候状态,等候TE中断到来,等候完成量被唤醒,通过unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout);//在规定的时间内等候
等候到完成量被唤醒之后就可以发送显示数据了。
详细来说:
在SPI屏幕中,完成量x是struct completion spi_panel_te;等候发数据的线程是:mdss_spi_panel_kickoff,将被mdp3_ctrl_pan_display(recovery模式)或mdp3_ctrl_display_commit_kickoff(正常模式)在mdp3_ctrl.c中被调用,这两个函数是在显示的内核线程中死循环实行的。TE中断处置惩罚函数:spi_panel_te_handler(),调用complete(&ctrl_pdata->spi_panel_te);唤醒革新数据的历程函数:
int mdss_spi_panel_kickoff(struct mdss_panel_data *pdata,
char *buf, int len, int dma_stride)
看下完成量的原型:
struct completion {
unsigned int done;
wait_queue_head_t wait;
};
除了有一个用于计数用的done,还有一个等候队列,
* Completions currently use a FIFO to queue threads that have to wait for
* the "completion" event.
可以看出完成量现在使用一个FIFO队列来存放那些必要等候完成量的线程,
typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
spinlock_t lock;
struct list_head task_list;
};
wait_queue_head_t等候队列由一个自旋锁lock和一个链表task_list构成。完成量重要用于实实际行单元A和实行单元B的同步功能。completion是一种轻量级的机制,它答应一个线程告诉另一个线程某个工作已经完成。
========================================================
panel crash现象:
195.340327: <6> BUG: spinlock lockup suspected on CPU#3, mdss_fb0/5348
195.345485: <6> lock: 0xdd80a53c, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
dump信息:
CPU 1 Call Stacks (dumped by TZ):
-000|arch_timer_read_counter_long()
-001|read_current_timer()
-002|__timer_delay()
-003|do_raw_spin_lock()
-004|_raw_spin_lock_irqsave()
-005|complete()
-006|spi_panel_te_handler()
-007|handle_irq_event_percpu()
-008|handle_irq_event()
-009|handle_edge_irq()
-010|generic_handle_irq()
-011|msm_gpio_irq_handler()
-012|generic_handle_irq()
-013|__handle_domain_irq()
-014|gic_handle_irq()
-015|__irq_usr()
----|end of frame
可以看到死机的时候,跑到了TE的中断处置惩罚函数里spi_panel_te_handler(),查看该函数源码可以看到:
irqreturn_t spi_panel_te_handler(int irq, void *data)
{
struct spi_panel_data *ctrl_pdata = (struct spi_panel_data *)data;
static int count = 2;
if (!ctrl_pdata) {
pr_err("%s: SPI display not available\n", __func__);
return IRQ_HANDLED;
}
complete(&ctrl_pdata->spi_panel_te);
if (ctrl_pdata->vsync_client.handler && !(--count)) {
ctrl_pdata->vsync_client.handler(ctrl_pdata->vsync_client.arg);
count = 2;
}
return IRQ_HANDLED;
}
调用了complete修改完成量来唤醒发显示数据的函数,complete调用了spin_lock_irqsave(&x->wait.lock, flags);不绝去获取等候队列的自旋锁,然后大概不绝获取
不到锁,然后就造成了死锁,体系就crash了。别的一个大概拥有锁的地方就是在刷数据里的等候:wait_for_completion_timeout,这里面也会去获得锁和释放锁。
void complete(struct completion *x)
{
unsigned long flags;
spin_lock_irqsave(&x->wait.lock, flags);
x->done++;
__wake_up_locked(&x->wait, TASK_NORMAL, 1);//唤醒一个处于等候该完成量x的历程或线程
spin_unlock_irqrestore(&x->wait.lock, flags);
}
关于这个自旋锁的API:
spin_lock_irqsave(lock, flags)该宏获得自旋锁的同时把标志寄存器的值生存到变量flags中并失效本地中断。
spin_unlock_irqrestore(lock, flags)该宏释放自旋锁lock的同时,也规复标志寄存器的值为变量flags生存的值。它与spin_lock_irqsave配对使用。
在使用spin_lock_irq和spin_unlock_irq的情况下,完全可以用spin_lock_irqsave和spin_unlock_irqrestore代替,那详细应该使用哪一个也必要依情况而定,假如可以确信在对共享资源访问前中断是使能的,那么使用spin_lock_irq更好一些。由于它比spin_lock_irqsave要快一些,但是假如你不能确定是否中断使能,那么使用spin_lock_irqsave和spin_unlock_irqrestore更好,由于它将规复访问共享资源前的中断标志而不是直接使能中断。
关于自旋锁的特性:
1.假如自旋锁已经被别的实行单元持有,调用者就不绝循环在那边看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。只有在占用时间极短的情况下,使用自旋锁才是公道的,假如要长时间占据锁,使用自旋锁会降低体系的性能。
2.自旋锁使用者一样平常保持锁时间非常短,不会引起调用者睡眠;信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在历程上下文使用
3.假如被掩护的共享资源必要在中断上下文访问(包罗顶半部即中断处置惩罚句柄和底半部即软中断),就必须使用自旋锁。上(顶)半部指的是中断处置惩罚程序,下(底)半部BH(bottom half)则指的是一些虽然与中断有干系性但是可以延后实行的任务。下半部的机制实际上包罗软中断、tasklet和工作队列3种机制。软中断可以并发运行在多个CPU上(纵然同一类型的也可以)。所以软中断必须设计为可重入的函数(答应多个CPU同时操纵),因此也必要使用自旋锁来掩护其数据布局。一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行实行。 工作队列可以把工作推后,交由一个内核线程去实行,可以睡眠。所以tasklet和工作队列应该不会用到自旋锁,假如被掩护的共享资源只在一个tasklet或timer上下文访问,那么不必要任何自旋锁掩护,由于同一个tasklet或timer只能在一个CPU上运行,纵然是在SMP情况下也是如此。实际上tasklet在调用tasklet_schedule标记其必要被调度时已经把该tasklet绑定到当前CPU,因此同一个tasklet决不大概同时在其他CPU上运行。timer也是在其被使用add_timer添加到timer队列中时已经被帮定到当前CPU,所以同一个timer绝不大概运行在其他CPU上。软中断必要用到自旋锁,但是驱动编写者很少直接使用软中断。
4.自旋锁保持期间是会抢占内核的,在单CPU且内核可抢占的体系中,自旋锁持有期间内核的抢占将被禁止,而信号量和读写信号量保持期间内核是可以被抢占的。自旋锁只有在单CPU但内核可抢占或SMP的情况下才真正必要,在单CPU且不可抢占的内核下,自旋锁的所有操纵都是空操纵。
5.尽管使用了自旋锁可以保证临界区不受别的CPU和本CPU内的抢占历程打搅,但是得到锁的代码路径在实行临界区的时候,还大概受到中断和底半部BH的影响。为了防止这种影响才会有自旋锁的衍生。
spin_lock_irqsave() = spin_lock() + local_irq_save()
spin_unlock_irqrestore() = spin_unlock() + local_irq_restore()
spin_lock_irq() = spin_lock() + local_irq_disable()关中断 --避免突如其来的中断驶入对体系的危害
spin_unlock_irq() = spin_unlock() + local_irq_enable()开中断
spin_lock_bh() = spin_lock() + local_bh_disable()--在得到自旋锁的同时失效本地软中断。
spin_unlock_bh() = spin_unlock() + local_bh_enable()
看下spinlock_t的定义:
typedef struct spinlock {
union {
struct raw_spinlock rlock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
struct {
u8 __padding[LOCK_PADSIZE];
struct lockdep_map dep_map;
};
#endif
};
} spinlock_t;
再看下原始的raw_spinlock:
typedef struct raw_spinlock {
arch_spinlock_t raw_lock;
#ifdef CONFIG_GENERIC_LOCKBREAK//userdebug、user版本都没有定义
unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK//userdebug有定义,user版本并没有定义
unsigned int magic, owner_cpu;
void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC//userdebug、user版本都没有定义
struct lockdep_map dep_map;
#endif
} raw_spinlock_t;
从上面代码来分析一个完整的spinlock_t的布局至少有4个成员:raw_lock/ magic/ owner_cpu/ owner
他们的初始值由spin_lock_init末了调用到__raw_spin_lock_init给出来
void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
struct lock_class_key *key)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->raw_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;//解锁状态
lock->magic = SPINLOCK_MAGIC;//#define SPINLOCK_MAGIC 0xdead4ead
lock->owner = SPINLOCK_OWNER_INIT;//#define SPINLOCK_OWNER_INIT ((void *)-1L)
lock->owner_cpu = -1;
}
spin_lock_irqsave的调用关系:
#define spin_lock_irqsave(lock, flags) \
do { \
raw_spin_lock_irqsave(spinlock_check(lock), flags); \
} while (0)
#define raw_spin_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
flags = _raw_spin_lock_irqsave(lock); \
} while (0)
_raw_spin_lock_irqsave(lock)就与dump信息的调用关系
_raw_spin_lock_irqsave()同等了,证实了死机的时候就是跑到这里来了
继续往下追:
somehow,
_raw_spin_lock_irqsave调用到了do_raw_spin_lock()
do_raw_spin_lock()调用了debug_spin_lock_before
void do_raw_spin_lock(raw_spinlock_t *lock)
{
debug_spin_lock_before(lock);
if (unlikely(!arch_spin_trylock(&lock->raw_lock)))
__spin_lock_debug(lock);
debug_spin_lock_after(lock);
}
debug_spin_lock_before调用了SPIN_BUG_ON
static inline void
debug_spin_lock_before(raw_spinlock_t *lock)
{
SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
SPIN_BUG_ON(lock->owner == current, lock, "recursion");
SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
lock, "cpu recursion");
}
#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)
static void spin_bug(raw_spinlock_t *lock, const char *msg)
{
if (!debug_locks_off())
return;
spin_dump(lock, msg);
}
static void spin_dump(raw_spinlock_t *lock, const char *msg)
{
struct task_struct *owner = NULL;
if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
owner = lock->owner;
printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
msg, raw_smp_processor_id(),
current->comm, task_pid_nr(current));
printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, "
".owner_cpu: %d\n",
lock, lock->magic,
owner ? owner->comm : "<none>",
owner ? task_pid_nr(owner) : -1,
lock->owner_cpu);
#ifdef CONFIG_DEBUG_SPINLOCK_BITE_ON_BUG
msm_trigger_wdog_bite();
#elif defined(CONFIG_DEBUG_SPINLOCK_PANIC_ON_BUG)
BUG();
#endif
dump_stack();
}
spin_dump就是末了打印了dump信息的地方:
195.340327: <6> BUG: spinlock lockup suspected on CPU#3, mdss_fb0/5348
195.345485: <6> lock: 0xdd80a53c, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
mdss_fb0是current->comm,5348是mdss_fb0的pid,
查看comm的定义:
struct task_struct {
...
char comm[16]; //历程正在运行的可实行文件名
...
}
造成体系死锁的大概缘故原由:
1.假如该锁不绝获取不到,死锁了,大概有历程持有相应的锁而不绝不释放,导致本历程不绝获取不到锁。
2.多做了一次unlock操纵(出现的大概性极小,由于,spin_lock和spin_unlock操纵肯定是配对的,内核中有相应的静态查抄机制,也有相应的死锁检测机制,出现这种直接错误的大概性极小。)
3.并发修改该spinlock。比如:在该spinlock还在被使用时,有其它历程并发修改该spinlock。更详细的例子:在CPU1上,某上下文进行spin_lock操纵后,在spin_unlock之前;在CPU2上,另一上下文对该spinlock重新进行了初始化(即将该lock值改为0);然后在CPU1上实行unlock操纵,此时该lock的Owner就被多unlock了1次,其Owner就被多加了1(但是据高通复兴,kickoff是单线程,只会在一个CPU上跑)
4.递归使用一个自旋锁,假如一个已经拥有某个自旋锁的CPU想第二次获得这个自旋锁,则该CPU将死锁。
5.自旋锁锁定期间不能调用大概引起历程调度的函数。假如历程获得锁之后再阻塞,如调用copy_from_user(),copy_to_user(),kmalloc(),msleep()函数,大概会导致内核崩溃。
办理路径:
1.Removing CONFIG_DEBUG_SPINLOCK=y 关闭debug宏开关,user版本已经默认关闭了。
2.大概是问题3,继续分析这个completion的使用逻辑,发显示数据的函数在init_completion后,调用wait_for_completion_timeout等候该completion变量完成,即等候其它地方调用completion()函数来唤醒该历程。看起来逻辑没啥问题,但问题在于:假如在调用init_completion之前,就有地方调用complete()函数的话,大概就有问题了(但其实应该也不会,由于probe的时候已经有init_completion了一次了),此时,假如别的的上下文刚好在lock之后unlock之前,就刚好符合之前说的情况3了。其实该问题的本质在于对completion布局的访问没有进行掩护,由于大概在多CPU上并发访问,按理应该有相应的机制进行掩护才对(比如锁)
这个问题由于只复现过一次,目前还没有对应措施去对应办理,只是先分析到这里。
=====================================================================================
当体系crash的时候,假如机器有接串口线,也可以查看到死机的信息,比如modem crash
[ 71.991405] Fatal error on the modem.
[ 71.994052] modem subsystem failure reason: sns_smgr_sensor.c:307:config_odr - sensor=1 odr=16 status=7.
[ 72.003834] M-Notify: General: 8
[ 72.110245] Kernel panic - not syncing: subsys-restart: Resetting the SoC - modem crashed.
[ 72.117498] CPU: 2 PID: 2736 Comm: kworker/2:2 Not tainted 3.18.24 #11
假如是整机,没有串口线,那就只能通过QPST来抓取crash log,再用QCAP来分析了。
=====================================================================================
MSM8909W待机功耗高的问题(到达20几mA),待机底电流1mA以下正常,1mA以上就不正常了
<3>[ 4042.193513] BUG: sleeping function called from invalid context at /home//work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[ 4042.204716] in_atomic(): 1, irqs_disabled(): 0, pid: 2096, name: android.bg
<3>[ 4042.211669] Preemption disabled at:[< (null)>] (null)
<6>[ 4042.216895]
<6>[ 4042.216918] CPU: 3 PID: 2096 Comm: android.bg Tainted: G O 3.18.24 #2
<6>[ 4042.216956] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[ 4042.216981] [<c0011c34>] (show_stack) from [<c0948c94>] (dump_stack+0x6c/0xb8)
<6>[ 4042.217002] [<c0948c94>] (dump_stack) from [<c0950ccc>] (mutex_lock+0x18/0x3c)
<6>[ 4042.217023] [<c0950ccc>] (mutex_lock) from [<c03bbe20>] (kgsl_get_egl_counts+0x24/0x98)
<6>[ 4042.217046] [<c03bbe20>] (kgsl_get_egl_counts) from [<c03d05c0>] (print_mem_entry+0x128/0x224)
<6>[ 4042.217068] [<c03d05c0>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[ 4042.217087] [<c026cf90>] (idr_for_each) from [<c03d0740>] (process_mem_print+0x84/0xcc)
<6>[ 4042.217109] [<c03d0740>] (process_mem_print) from [<c01466b0>] (seq_read+0x1a8/0x400)
<6>[ 4042.217131] [<c01466b0>] (seq_read) from [<c0128f0c>] (vfs_read+0x90/0x124)
<6>[ 4042.217150] [<c0128f0c>] (vfs_read) from [<c012944c>] (SyS_read+0x40/0x80)
<6>[ 4042.217169] [<c012944c>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
<6>[ 4062.063296] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
先看下这个log在哪里打印,
打印的源码位置:
void __might_sleep(const char *file, int line, int preempt_offset)
{
...
printk(KERN_ERR
"BUG: sleeping function called from invalid context at %s:%d\n",
file, line);
printk(KERN_ERR
"in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
in_atomic(), irqs_disabled(),
current->pid, current->comm);
...
}
这段代码受到宏开关CONFIG_DEBUG_ATOMIC_SLEEP控制,user版本关闭,userdebug版本打开。
<3>[ 4042.193513] BUG: sleeping function called from invalid context at /home//work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[ 4042.204716] in_atomic(): 1, irqs_disabled(): 0, pid: 2096, name: android.bg
说明是mutex.c调用了,大概会进入休眠操纵,这个只是个提示信息:
void __sched mutex_lock(struct mutex *lock)
{
might_sleep();
/*
* The locking fastpath is the 1->0 transition from
* 'unlocked' into 'locked' state.
*/
__mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
mutex_set_owner(lock);
}
表现代码在原子上下文中休眠了!
kernel BUG() was trigged due to mutex call(can be slept) inside invalid context( atomic environment) in below call stack.
-----------------------------------------------
别的一些提示报错:
Freezing of tasks aborted after 0.005 seconds
Error: returning -512 value
冻结任务被终止
kernel\power\process.c
static int try_to_freeze_tasks(bool user_only)
{
...
while (true) {
...
if (pm_wakeup_pending()) {//实行pm_wakeup_pending,用来判断当前的的power transition是否应该终止。正常情况下这里不应该终止,
#ifdef CONFIG_PM_SLEEP//user和debug都没有定义
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
#endif
wakeup = true;
break;
}
...
}
...
if (wakeup) {//说明是有唤醒事件在等候,所以没有睡下去
printk("\n");
printk(KERN_ERR "Freezing of tasks aborted after %d.%03d seconds",
elapsed_msecs / 1000, elapsed_msecs % 1000);
} else if (todo) {
printk("\n");
printk(KERN_ERR "Freezing of tasks failed after %d.%03d seconds"
" (%d tasks refusing to freeze, wq_busy=%d):\n",
elapsed_msecs / 1000, elapsed_msecs % 1000,
todo - wq_busy, wq_busy);
...
} else {
printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
elapsed_msecs % 1000);
}
return todo ? -EBUSY : 0;
}
android手机频繁地进出suspend/resume状况,因此必要pm_wakeup_pending()机制,用来查抄进入这段时间是否有被唤醒的事件发生。
/**
* pm_wakeup_pending - Check if power transition in progress should be aborted.
*
* Compare the current number of registered wakeup events with its preserved
* value from the past and return true if new wakeup events have been registered
* since the old value was stored. Also return true if the current number of
* wakeup events being processed is different from zero.
*/
bool pm_wakeup_pending(void)
{
unsigned long flags;
bool ret = false;
spin_lock_irqsave(&events_lock, flags);
if (events_check_enabled) {
unsigned int cnt, inpr;
split_counters(&cnt, &inpr);
ret = (cnt != saved_count || inpr > 0);//假如注册的wakeup events 数目有厘革,或是目前wakeup events数(in progress wakeup_sources数)大于0,则True,表现要终止suspend,即resume起来后再suspend动作
events_check_enabled = !ret;
}
spin_unlock_irqrestore(&events_lock, flags);
if (ret) {
pr_info(" M: Wakeup pending, aborting suspend\n");
pm_print_active_wakeup_sources();
}
return ret || pm_abort_suspend;
}
/*
* Combined counters of registered wakeup events and wakeup events in progress.
* They need to be modified together atomically, so it's better to use one
* atomic variable to hold them both.
*/
static void split_counters(unsigned int *cnt, unsigned int *inpr)
{
unsigned int comb = atomic_read(&combined_event_count);
*cnt = (comb >> IN_PROGRESS_BITS);//counters of registered wakeup events
*inpr = comb & MAX_IN_PROGRESS;//wakeup events in progress.
}
可看出实际是:combined_event_count发生了厘革导致的,有两个函数会去改变这个变量:
1.wakeup_source_activate
2.wakeup_source_deactivate
添加打印,查看ws->name
if(events_check_enabled)
printk(KERN_ERR "wakeup_source_activate(), ws->name = %s", ws->name);
查看体系中的wakeup_source
adb shell cat sys/kernel/debug/wakeup_sources > wakeup_source.txt
然后看log,确实suspend过程中有一些wakeup_source出现,不外体系会尝试去关闭这些wakeup_source并终极到达休眠的目的。所以关键是要看suspend的流程有没有
正常走完,高通给了正常和异常的两个参考log:
1. abnormal suspend log as below,
<6>[ 325.473149] Freezing user space processes ...
<3>[ 325.477249] Error: returning -512 value
<6>[ 325.497303] PM: Wakeup pending, aborting suspend
<6>[ 325.497326] active wakeup source: wlan
<6>[ 325.497437]
<3>[ 325.497441] Freezing of tasks aborted after 0.024 seconds//出现了我们此次出现的错误log
<6>[ 325.497447] Restarting tasks ... done.
<6>[ 325.519114] PM: suspend exit 1970-01-01 04:08:55.139500300 UTC
2. normal suspend log as below,
<6>[ 327.744179] PM: suspend entry 1970-01-01 04:09:45.013117468 UTC
<6>[ 327.744191] PM: Syncing filesystems ... done.
<7>[ 327.810413] PM: Preparing system for mem sleep
<6>[ 327.811782] Freezing user space processes ...
<3>[ 327.815645] Error: returning -512 value
<6>[ 327.855215] (elapsed 0.043 seconds) done.
<6>[ 327.855230] Freezing remaining freezable tasks ... (elapsed 0.004 seconds) done.
<7>[ 327.859799] PM: Entering mem sleep
<6>[ 327.859805] Suspending console(s) (use no_console_suspend to debug)
<6>[ 327.909332] PM: suspend of devices complete after 48.306 msecs
<6>[ 327.911141] PM: late suspend of devices complete after 1.802 msecs
<6>[ 327.917696] PM: noirq suspend of devices complete after 6.547 msecs
<6>[ 327.917702] Disabling non-boot CPUs ...
- - - - - - - - - - - - - - - - - - -
至于log不绝返回-512是怎么回事?
网上的解释:
每次设备进入睡眠的时候,有个历程总是会打印出-512的错误,经查这个是由于daemon被wake_up后,condition不满足但是daemon收到了signal导致的。
daemon通过体系调用ioctl进入内核空间,然后调用wait_event_interruptible函数让自身休眠,留意这个wait_event_interruptible是可以被signal打断的。
wait_event_interruptible的详细代码如下,其只是对__wait_event_interruptible的封装,所以直接看封装前的代码,如下:
/**
* wait_event_interruptible - sleep until a condition gets true
* @wq: the waitqueue to wait on
* @condition: a C expression for the event to wait for
*
* The process is put to sleep (TASK_INTERRUPTIBLE) until the
* @condition evaluates to true or a signal is received.
* The @condition is checked each time the waitqueue @wq is woken up.
*
* wake_up() has to be called after changing any variable that could
* change the result of the wait condition.
*
* The function will return -ERESTARTSYS if it was interrupted by a
* signal and 0 if @condition evaluated to true.
*/
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__ret = __wait_event_interruptible(wq, condition); \
__ret; \
})
末了会调用到long prepare_to_wait_event(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
unsigned long flags;
if (signal_pending_state(state, current))
return -ERESTARTSYS;//#define ERESTARTSYS 512
...
return 0;
}
那是哪里不绝打印:“Error: returning -512 value”
搜刮代码发现是kernel/drivers/usb/gadget/function/f_fs.c
static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
{
... /*
* if ep is disabled, this fails all current IOs
* and wait for next epfile open to happen
*/
if (!atomic_read(&epfile->error)) {
ret = wait_event_interruptible(epfile->wait,
(ep = epfile->ep));//休眠直到ep = epfile->ep为true,当休眠由于收到signal而中断的时候返回-ERESTARTSYS
//ep = epfile->ep为true为true之后,函数返回0
if (ret < 0)
goto error;
}
...
if (ret < 0)
pr_err_ratelimited("===Error: returning %zd value\n", ret);
return ret;
}函数
ffs_epfile_read(),ffs_epfile_write(),ffs_epfile_aio_write(),ffs_epfile_aio_read()会去调用ffs_epfile_io()接口
都是该驱动提供的一些读写接口:
static const struct file_operations ffs_epfile_operations = {
.llseek = no_llseek,
.open = ffs_epfile_open,
.write = ffs_epfile_write,
.read = ffs_epfile_read,
.aio_write = ffs_epfile_aio_write,
.aio_read = ffs_epfile_aio_read,
.release = ffs_epfile_release,
.unlocked_ioctl = ffs_epfile_ioctl,
};
PC一样平常是USB Host 手机等数码设备通常是USB Device
OTG则使设备既可以是USB Device, 也可以是USB Host
在Linux中, 作为USB Device的设备被称为gadget.当把pad/手机插到pc上时,可以作为u盘、网卡等usb功能设备呈现,这个就叫做gadget。可以理解为usb 从设备端,和host对应。初步理解应该是USB构建文件体系干系的读写接口,报错了。
但是这个log,MIPI屏幕也会报。而且是插着USB线不会报(大概是手表这时候正常的充当着gadget的脚色),不插USB先才会报,而且高通的参考log,正常休眠也会报这个log,所以suspend异常的问题与此并无关系。
-------------------------------------
下一个问题
[ 197.691250] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -16
[ 197.691261] PM: Device alarmtimer failed to suspend: error -16
[ 197.691269] PM: Some devices failed to suspend, or early wake event detected
标准的linux休眠则实行error = enter_state(state);
调用流程是(调用者->被调用者):state_store->pm_suspend->pm_suspend_marker(entry)->enter_state->suspend_devices_and_enter
->dpm_suspend_start->dpm_suspend->dpm_show_time->suspend_enter->dpm_suspend_late->dpm_suspend_noirq->disable_nonboot_cpus
->msm_cpu_pm_enter_sleep(串口log打印打开的情况下,这是串口log打印末了一条并保持很久直到power按键唤醒)
/**
* enter_state - Do common work needed to enter system sleep state.
* @state: System sleep state to enter.
*
* Make sure that no one else is trying to put the system into a sleep state.
* Fail if that's not the case. Otherwise, prepare for system suspend, make the
* system enter the given sleep state and clean up after wakeup.
*/
MIPI 320P正常休眠过程,待机功耗0.4mA正常的,
按POWER按键休眠,断开USB,只接串口,然后 cat proc/kmsg
<6>[ 140.830151] ===state_store,state = 3//3是mem
<6>[ 140.830169] ===pm_suspend,state = 3
<6>[ 140.830188] ===PM: suspend entry 1970-01-01 00:05:40.128041187 UTC
[ 140.854684] ===Error: returning -512 value
(串口log只打到这里,由于串口也休眠了,所以有一部门休眠log要唤醒的时候才看得到)
[ 140.899711] migrate_irqs: 310 callbacks suppressed
[ 140.899716] IRQ0 no longer affine to CPU3
[ 140.899722] IRQ1 no longer affine to CPU3
[ 140.899728] IRQ2 no longer affine to CPU3
[ 140.899733] IRQ3 no longer affine to CPU3
[ 140.899739] IRQ4 no longer affine to CPU3
[ 140.899744] IRQ5 no longer affine to CPU3
[ 140.899750] IRQ6 no longer affine to CPU3
[ 140.899755] IRQ7 no longer affine to CPU3
[ 140.899761] IRQ8 no longer affine to CPU3
[ 140.899766] IRQ9 no longer affine to CPU3
[ 140.901008] CPU3: shutdown
<6>[ 140.830200] ===PM: Syncing filesystems ... done.
<6>[ 140.850555] ===PM: Preparing system for mem sleep
<6>[ 140.85116[ 141.045131] healthd: battery l=65 v=3901 t=34.0 h=2 st=3 c=1 chg=
6] Freezing user space processes ...
<3>[ 140.854684] ===Error: returning -512 value
<6>[ 140.863249] (elapsed 0.012 seconds) done.
<6>[ 140.863273] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 140.865806] ===PM: suspend_prepare return 0
<6>[ 140.865818] ===PM: Entering mem sleep
<6>[ 140.865828] Suspending console(s) (use no_console_suspend to debug)
<6>[ 140.893443] PM: suspend of devices complete after 26.281 msecs
<6>[ 140.895458] PM: late suspend of devices complete after 2.002 msecs
<6>[ 140.898929] PM: noirq suspend of devices complete after 3.456 msecs
<6>[ 140.898941] Disabling non-boot CPUs ...//休眠乐成
<4>[ 140.899711] migrate_irqs: 310 callbacks suppressed
<4>[ 140.899716] IRQ0 no longer affine to CPU3
<4>[ 140.899722] IRQ1 no longer affine to CPU3
<4>[ 140.899728] IRQ2 no longer affine to CPU3
<4>[ 140.899733] IRQ3 no longer affine to CPU3
<4>[ 140.899739] IRQ4 no longer affine to CPU3
<4>[ 140.899744] IRQ5 no longer affine to CPU3
<4>[ 140.899750] IRQ6 no longer affine to CPU3
<4>[ 140.899755] IRQ7 no longer affine to CPU3
<4>[ 140.899761] IRQ8 no longer affine to CPU3
<4>[ 140.899766] IRQ9 no longer affine to CPU3
<5>[ 140.901008] CPU3: shutdown
<6>[ 140.902151] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend//休眠乐成
-----------------真正POWER键唤醒应该是从这里开始打印:--------------
<6>[ 140.902351] Enabling non-boot CPUs ...
<6>[ 140.902791] CPU3: Booted secondary processor
<6>[ 140.903577] CPU3 is up
<6>[ 140.904607] PM: noirq resume of devices complete after 1.010 msecs
<6>[ 140.906389] PM: early resume of devices complete after 1.135 msecs
<6>[ 140.983662] PM: resume of devices complete after 77.257 msecs
<6>[ 141.033011] ===PM: suspend_devices_and_enter return 0
<6>[ 141.033022] Restarting tasks ... done.
<12>[ 141.045131] healthd: battery l=65 v=3901 t=34.0 h=2 st=3 c=1 chg=
以上的log看起来挺正常的,但是有时候也会出现如许的log:
MSM8909W手表:/ # cat proc/kmsg
[ 97.473874] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
[ 97.485286] in_atomic(): 1, irqs_disabled(): 0, pid: 2045, name: android.bg
[ 97.492155] Preemption disabled at:[< (null)>] (null)
<3>[ 97.492155] Preemption disabled at:[< (null)>] (null)
<6>[ 97.497340]
<6>[ 97.497359] CPU: 2 PID: 2045 Comm: android.bg Not tainted 3.18.24 #19
<6>[ 97.497396] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[ 97.497419] [<c0011c34>] (show_stack) from [<c09469e8>] (dump_stack+0x6c/0xb8)
<6>[ 97.497441] [<c09469e8>] (dump_stack) from [<c094ea1c>] (mutex_lock+0x18/0x3c)
<6>[ 97.497465] [<c094ea1c>] (mutex_lock) from [<c03b9ab8>] (kgsl_get_egl_counts+0x24/0x98)
<6>[ 97.497488] [<c03b9ab8>] (kgsl_get_egl_counts) from [<c03ce258>] (print_mem_entry+0x128/0x224)
<6>[ 97.497509] [<c03ce258>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[ 97.497528] [<c026cf90>] (idr_for_each) from [<c03ce3d8>] (process_mem_print+0x84/0xcc)
<6>[ 97.497551] [<c03ce3d8>] (process_mem_print) from [<c01466cc>] (seq_read+0x1a8/0x400)
<6>[ 97.497573] [<c01466cc>] (seq_read) from [<c0128f28>] (vfs_read+0x90/0x124)
<6>[ 97.497593] [<c0128f28>] (vfs_read) from [<c0129468>] (SyS_read+0x40/0x80)
<6>[ 97.497613] [<c0129468>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
<6>[ 97.657302] ===state_store,state = 3
<6>[ 97.657320] ===pm_suspend,state = 3
<6>[ 97.657340] ===PM: suspend entry 1970-01-01 00:47:21.383590845 UTC
[ 97.673111] ===wakeup_source_activate(), ws->name = NETLINK
[ 97.678855] ===wakeup_source_activate(), ws->name = eventpoll
<6>[ 97.657352] ===PM: Syncing filesystems ... done.
<6>[ 9[ 97.684877] ===wakeup_source_deactivate(), ws->name = NETLINK
[ 97.692116] Freezing of tasks aborted after 0.002 seconds
[ 97.694130] ===Error: returning -512 value
7.671736] ===PM: Preparing system for mem sleep
<3>[ 97.673111] ===wakeup_source_activate(), ws->name = NETLINK
<3>[ 97.678855] ===wakeup_source_activate(), ws->name = eventpoll
<3>[ 97.684877] ===wakeup_source_deactivate(), ws->name = NETLINK
<6>[ 97.692016] Freezing user space processes ...
<6>[ 97.692017] ===PM: Wakeup pending, aborting suspend
<6>[ 97.692066] ===active wakeup source: eventpoll
<6>[ 97.692107]
<3>[ 97.692116] Freezing of tasks aborted after 0.002 seconds
<6>[ 97.694129] Restarting tasks ...
<3>[ 97.694130] ===Error: returning -512 value
<6>[ 97.701218] done.
<6>[ 97.701442] ===PM: suspend_prepare return -16
<6>[ 97.701456] ===PM: suspend exit 1970-01-01 00:47:21.427707772 UTC
//休眠失败了,退出
[ 97.810280] ===Error: returning -512 value
[ 97.858261] migrate_irqs: 310 callbacks suppressed
[ 97.858267] IRQ0 no longer affine to CPU3
[ 97.858273] IRQ1 no longer affine to CPU3
[ 97.858279] IRQ2 no longer affine to CPU3
[ 97.858284] IRQ3 no longer affine to CPU3
[ 97.858289] IRQ4 no longer affine to CPU3
[ 97.858295] IRQ5 no longer affine to CPU3
[ 97.858300] IRQ6 no longer affine to CPU3
[ 97.858305] IRQ7 no longer affine to CPU3
[ 97.858311] IRQ8 no longer affine to CPU3
[ 97.858317] IRQ9 no longer affine to CPU3
[ 97.859469] CPU3: shutdown
//继续休眠
<6>[ 97.803013] ===state_store,state = 3
<6>[ 97.803031] 98.003484] healthd: battery l=62 v=3837 t=34.0 h=2 st=3 c=14 chg=
=pm_suspend,state = 3
<6>[ 97.803050] ===PM: suspend entry 1970-01-01 00:47:21.529301731 UTC
<6>[ 97.803062] ===PM: Syncing filesystems ... done.
<6>[ 97.806178] ===PM: Preparing system for mem sleep
<6>[ 97.806798] Freezing user space processes ...
<3>[ 97.810280] ===Error: returning -512 value
<6>[ 97.815187] (elapsed 0.008 seconds) done.
<6>[ 97.815211] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 97.817978] ===PM: suspend_prepare return 0
<6>[ 97.817989] ===PM: Entering mem sleep
<6>[ 97.818000] Suspending console(s) (use no_console_suspend to debug)
<6>[ 97.852280] PM: suspend of devices complete after 32.947 msecs
<6>[ 97.854288] PM: late suspend of devices complete after 1.995 msecs
<6>[ 97.857649] PM: noirq suspend of devices complete after 3.347 msecs
<6>[ 97.857661] Disabling non-boot CPUs ...
<4>[ 97.858261] migrate_irqs: 310 callbacks suppressed
<4>[ 97.858267] IRQ0 no longer affine to CPU3
<4>[ 97.858273] IRQ1 no longer affine to CPU3
<4>[ 97.858279] IRQ2 no longer affine to CPU3
<4>[ 97.858284] IRQ3 no longer affine to CPU3
<4>[ 97.858289] IRQ4 no longer affine to CPU3
<4>[ 97.858295] IRQ5 no longer affine to CPU3
<4>[ 97.858300] IRQ6 no longer affine to CPU3
<4>[ 97.858305] IRQ7 no longer affine to CPU3
<4>[ 97.858311] IRQ8 no longer affine to CPU3
<4>[ 97.858317] IRQ9 no longer affine to CPU3
<5>[ 97.859469] CPU3: shutdown
<6>[ 97.861096] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//正常休眠乐成
//正常唤醒
<6>[ 97.861313] Enabling non-boot CPUs ...
<6>[ 97.861759] CPU3: Booted secondary processor
<6>[ 97.862545] CPU3 is up
<6>[ 97.863581] PM: noirq resume of devices complete after 1.016 msecs
<6>[ 97.865331] PM: early resume of devices complete after 1.138 msecs
<6>[ 97.947246] PM: resume of devices complete after 81.898 msecs
<6>[ 97.995430] ===PM: suspend_devices_and_enter return 0
//有时候的log是如许的:
<6>[ 113.772929] ===state_store,state = 3
<6>[ 113.772947] ===pm_suspend,state = 3
<6>[ 113.772967] ===PM: suspend entry 1970-01-01 00:54:45.106990988 UTC
[ 113.824586] ===wakeup_source_activate(), ws->name = modem_IPCRTR
[ 113.829615] ===wakeup_source_deactivate(), ws->name = modem_IPCRTR
<6>[ 113.772979] ===PM: Syncing filesystems ...
[ 113.836149] ===wakeup_source_activate(), ws->name = ipc00000084_Binder:1974_1
<3>[ 113.824586] ===wakeup_source_activate(), ws->name = mode
[ 113.847456] ===wakeup_source_deactivate(), ws->name = ipc00000084_Binder:19741
[ 113.852951] Freezing of tasks aborted after 0.004 seconds
m_IPCRTR
<3>[ 113.829615] ===wakeup_source_deactivate(), ws->n[ 113.866763] ===Error: returning -512 value
ame = modem_IPCRTR
<3>[ 113.836149] ===wakeup_source_activate(), ws->name = ipc00000084_Binder:1974_1
<3>[ 113.847456] ===wakeup_source_deactivate(), ws->name = ipc00000084_Binder:1974_1
<6>[ 113.848195] done.
<6>[ 113.848201] ===PM: Preparing system for mem sleep
<6>[ 113.852842] Freezing user space processes ...
<6>[ 113.852843] ===PM: Wakeup pending, aborting suspend
<6>[ 113.852919] last active wakeup source: ipc00000084_Binder:1974_1
<6>[ 113.852943]
<3>[ 113.852951] Freezing of tasks aborted after 0.004 seconds
<6>[ 113.860052] Restarting tasks ... done.
<6>[ 113.860225] ===PM: suspend_prepare return -16
<6>[ 113.860239] ===PM: suspend exit 1970-01-01 00:54:45.194264894 UTC
[ 113.965998] ===Error: returning -512 value
//刚开始没睡下去
//再次休眠
[ 114.009964] CPU3: shutdown
<6>[ 113.961509] ===state_store,state = 3
<6>[ 113.961527] 114.108368] healthd: battery l=62 v=3848 t=27.0 h=2 st=3 c=13 chg=
=pm_suspend,state = 3
<6>[ 113.961547] ===PM: suspend entry 19[ 114.119482] healthd: battery l=62 v=3846 t=27.0 h=2 st=3 c=13 chg=
70-01-01 00:54:45.295572290 UTC
<6>[ 113.961558] ===PM: Syncing filesystems ... done.
<6>[ 113.963923] ===PM: Preparing system for mem sleep
<6>[ 113.964527] Freezing user space processes ...
<3>[ 113.965998] ===Error: returning -512 value
<12>[ 114.119482] healthd: battery l=62 v=3846 t=27.0 h=2 st=3 c=13 chg=
[ 114.215436] ===Error: returning -512 value
[ 114.255245] migrate_irqs: 630 callbacks suppressed
[ 114.255250] IRQ0 no longer affine to CPU3
[ 114.255257] IRQ1 no longer affine to CPU3
[ 114.255262] IRQ2 no longer affine to CPU3
[ 114.255268] IRQ3 no longer affine to CPU3
[ 114.255274] IRQ4 no longer affine to CPU3
[ 114.255279] IRQ5 no longer affine to CPU3
[ 114.255284] IRQ6 no longer affine to CPU3
[ 114.255290] IRQ7 no longer affine to CPU3
[ 114.255296] IRQ8 no longer affine to CPU3
[ 114.255302] IRQ9 no longer affine to CPU3
[ 114.256435] CPU3: shutdown
<6>[ 114.209101] ===PM: Syncing filesystems ... done.
<6>[ 114.213389] ===PM: Preparing system for mem sleep
<6>[ 114.213993] Freezing user space processes ...
<3>[ 114.215436] ===Error: returning -512 value
//这里不知道睡下去了没有,log不知道是没打出来还是没睡下去,但是电流值已经是满足要求了,暂且认为是正常休眠了
//唤醒了
<6>[ 114.259938] PM: noirq resume of devices complete after 1.166 msecs
<6>[ 114.261686] PM: early resume of devices complete after 1.149 msecs
<6>[ 114.340672] PM: resume of devices complete after 78.971 msecs
<6>[ 114.389310] ===PM: suspend_devices_and_enter return 0
-------------------------------------------------------------
SPI 240P 屏幕suspend 过程:
t86:/ # cat proc/kmsg
[ 195.054625] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
[ 195.065964] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
[ 195.072874] Preemption disabled at:[< (null)>] (null)
<3>[ 195.054625] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[ 195.065964] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
<3>[ 195.072874] Preemption disabled at:[< (null)>] (null)
<6>[ 195.078086]
<6>[ 195.078102] CPU: 2 PID: 2043 Comm: android.bg Not tainted 3.18.24 #20
<6>[ 195.078148] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[ 195.078172] [<c0011c34>] (show_stack) from [<c0948d74>] (dump_stack+0x6c/0xb8)
[ 200.737128] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[ 200.760478] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[ 200.737128] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[ 200.760478] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[ 201.074644] ===state_store,state = 3
<6>[ 201.074663] ===pm_suspend,state = 3
<6>[ 201.074682] ===PM: suspend entry 1970-01-01 00:24:05.337336245 UTC
[ 201.092553] ===wakeup_source_activate(), ws->name = NETLINK
[ 201.098961] ===wakeup_source_activate(), ws->name = eventpoll
<6>[ 201.074694] ===PM: Syncing filesystems ... done.
<6>[ 20[ 201.104656] ===wakeup_source_deactivate(), ws->name = NETLINK
[ 201.111697] Freezing of tasks aborted after 0.002 seconds
[ 201.113765] ===Error: returning -512 value
1.091252] ===PM: Preparing system for mem sleep
<3>[ 201.092553] ===wakeup_source_activate(), ws->name = NETLINK
<3>[ 201.098961] ===wakeup_source_activate(), ws->name = eventpoll
<6>[ 201.111599] Freezing user space processes ...
<6>[ 201.111601] ===PM: Wakeup pending, aborting suspend
<6>[ 201.111649] ===active wakeup source: eventpoll//休眠失败,被终止
<6>[ 201.111687]
<3>[ 201.111697] Freezing of tasks aborted after 0.002 seconds
<6>[ 201.113764] Restarting tasks ...
<3>[ 201.113765] ===Error: returning -512 value
<6>[ 201.116006] done.
<6>[ 201.116120] ===PM: suspend_prepare return -16
<6>[ 201.116135] ===PM: suspend exit 1970-01-01 00:24:05.378789370 UTC
//再次休眠
<6>[ 201.217760] ===state_store,state = 3
<6>[ 201.217778] ===pm_suspend,state = 3
<6>[ 201.217797] ===PM: suspend entry 1970-01-01 00:24:05.480451714 UTC
[ 201.243596] ===Error: returning -512 value
[ 201.287292] migrate_irqs: 310 callbacks suppressed
[ 201.287297] IRQ0 no longer affine to CPU3
[ 201.287304] IRQ1 no longer affine to CPU3
[ 201.287310] IRQ2 no longer affine to CPU3
[ 201.287316] IRQ3 no longer affine to CPU3
[ 201.287321] IRQ4 no longer affine to CPU3
[ 201.287328] IRQ5 no longer affine to CPU3
[ 201.287333] IRQ6 no longer affine to CPU3
[ 201.287339] IRQ7 no longer affine to CPU3
[ 201.287345] IRQ8 no longer affine to CPU3
[ 201.287351] IRQ9 no longer affine to CPU3
[ 201.288477] CPU3: shutdown
<6>[ 201.217809] ===PM: Syncing filesystems ... done.
<6>[ 201.241689] ===PM: Preparing system for mem sleep
<6>[ 201.24229[ 201.428326] healthd: battery l=42 v=3786 t=37.0 h=2 st=3 c=18 chg=
4] Freezing user space processes ...
<3>[ 201.243596] ===Error: returning -512 value
<6>[ 201.250110] (elapsed 0.007 seconds) done.
<6>[ 201.250135] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 201.252905] ===PM: suspend_prepare return 0
<6>[ 201.252918] ===PM: Entering mem sleep
<6>[ 201.252929] Suspending console(s) (use no_console_suspend to debug)
<6>[ 201.281101] PM: suspend of devices complete after 26.818 msecs
<6>[ 201.283135] PM: late suspend of devices complete after 2.022 msecs
<6>[ 201.286540] PM: noirq suspend of devices complete after 3.390 msecs
<6>[ 201.286556] Disabling non-boot CPUs ...
//至此挂起乐成了
<4>[ 201.287292] migrate_irqs: 310 callbacks suppressed
<4>[ 201.287297] IRQ0 no longer affine to CPU3
<4>[ 201.287304] IRQ1 no longer affine to CPU3
<4>[ 201.287310] IRQ2 no longer affine to CPU3
<4>[ 201.287316] IRQ3 no longer affine to CPU3
<4>[ 201.287321] IRQ4 no longer affine to CPU3
<4>[ 201.287328] IRQ5 no longer affine to CPU3
<4>[ 201.287333] IRQ6 no longer affine to CPU3
<4>[ 201.287339] IRQ7 no longer affine to CPU3
<4>[ 201.287345] IRQ8 no longer affine to CPU3
<4>[ 201.287351] IRQ9 no longer affine to CPU3
<5>[ 201.288477] CPU3: shutdown
<6>[ 201.289925] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//按POWER按键唤醒
<6>[ 201.290263] Enabling non-boot CPUs ...
<6>[ 201.290705] CPU3: Booted secondary processor
<6>[ 201.291468] CPU3 is up
<6>[ 201.292519] PM: noirq resume of devices complete after 1.024 msecs
<6>[ 201.294300] PM: early resume of devices complete after 1.126 msecs
<6>[ 201.367715] PM: resume of devices complete after 73.397 msecs
<6>[ 201.415807] ===PM: suspend_devices_and_enter return 0
<6>[ 201.486073] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23//屏幕复位
//有时候的log是如许的
[ 388.085659] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[ 388.111414] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[ 388.085659] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[ 388.111414] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[ 388.426952] ===state_store,state = 3
<6>[ 388.426970] ===pm_suspend,state = 3
<6>[ 388.426989] ===PM: suspend entry 1970-01-01 00:27:23.126746647 UTC
[ 388.450149] ===wakeup_source_activate(), ws->name = NETLINK
[ 388.454733] ===wakeup_source_activate(), ws->name = eventpoll
<3>[ 388.454733] ===wakeup_source_activate(), ws->name = eventp[ 388.460687] ===wakeup_source_deactivate(), ws->name = NETLINK
[ 388.467401] Freezing of tasks aborted after 0.002 seconds
[ 388.469106] ===Error: returning -512 value
oll
<3>[ 388.460687] ===wakeup_source_deactivate(), ws->name = NETLINK
<6>[ 388.467300] Freezing user space processes ...
<6>[ 388.467301] ===PM: Wakeup pending, aborting suspend
<6>[ 388.467350] ===active wakeup source: eventpoll
<6>[ 388.467392]
<3>[ 388.467401] Freezing of tasks aborted after 0.002 seconds
<6>[ 388.469105] Restarting tasks ...
<3>[ 388.469106] ===Error: returning -512 value
<6>[ 388.481344] done.
<6>[ 388.481553] ===PM: suspend_prepare return -16
<6>[ 388.481576] ===PM: suspend exit 1970-01-01 00:27:23.181333105 UTC//休眠失败了
[ 388.590301] ===Error: returning -512 value
[ 388.631445] migrate_irqs: 310 callbacks suppressed
[ 388.631451] IRQ0 no longer affine to CPU3
[ 388.631457] IRQ1 no longer affine to CPU3
[ 388.631463] IRQ2 no longer affine to CPU3
[ 388.631469] IRQ3 no longer affine to CPU3
[ 388.631474] IRQ4 no longer affine to CPU3
[ 388.631481] IRQ5 no longer affine to CPU3
[ 388.631486] IRQ6 no longer affine to CPU3
[ 388.631492] IRQ7 no longer affine to CPU3
[ 388.631497] IRQ8 no longer affine to CPU3
[ 388.631504] IRQ9 no longer affine to CPU3
[ 388.632646] CPU3: shutdown
//再次休眠
<6>[ 388.582090] ===state_store,state = 3
<6>[ 388.582108] ===pm_suspend,state = 3
<6>[ 388.582127] =[ 388.771733] healthd: battery l=41 v=3788 t=33.0 h=2 st=3 c=22 chg=
==PM: suspend entry 1970-01-01 00:27:23.281884199 UTC
<6>[ 388.582138] ===PM: Syncing filesystems ... done.
<6>[ 388.586276] ===PM: Preparing system for mem sleep
<6>[ 388.586868] Freezing user space processes ...
<3>[ 388.590301] ===Error: returning -512 value
<6>[ 388.599558] (elapsed 0.012 seconds) done.
<6>[ 388.599586] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 388.602440] ===PM: suspend_prepare return 0
<6>[ 388.602452] ===PM: Entering mem sleep
<6>[ 388.602463] Suspending console(s) (use no_console_suspend to debug)
<6>[ 388.625211] PM: suspend of devices complete after 21.392 msecs
<6>[ 388.627250] PM: late suspend of devices complete after 2.025 msecs
<6>[ 388.630815] PM: noirq suspend of devices complete after 3.548 msecs
<6>[ 388.630833] Disabling non-boot CPUs ...
//正常suspend了
<4>[ 388.631445] migrate_irqs: 310 callbacks suppressed
<4>[ 388.631451] IRQ0 no longer affine to CPU3
<4>[ 388.631457] IRQ1 no longer affine to CPU3
<4>[ 388.631463] IRQ2 no longer affine to CPU3
<4>[ 388.631469] IRQ3 no longer affine to CPU3
<4>[ 388.631474] IRQ4 no longer affine to CPU3
<4>[ 388.631481] IRQ5 no longer affine to CPU3
<4>[ 388.631486] IRQ6 no longer affine to CPU3
<4>[ 388.631492] IRQ7 no longer affine to CPU3
<4>[ 388.631497] IRQ8 no longer affine to CPU3
<4>[ 388.631504] IRQ9 no longer affine to CPU3
<5>[ 388.632646] CPU3: shutdown
<6>[ 388.634094] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//POWER按键唤醒了
<6>[ 388.634309] Enabling non-boot CPUs ...
<6>[ 388.634754] CPU3: Booted secondary processor
<6>[ 388.635531] CPU3 is up
<6>[ 388.636581] PM: noirq resume of devices complete after 1.022 msecs
<6>[ 388.638350] PM: early resume of devices complete after 1.126 msecs
<6>[ 388.713135] PM: resume of devices complete after 74.767 msecs
<6>[ 388.761268] ===PM: suspend_devices_and_enter return 0
<6>[ 388.761279] Restarting tasks ... done.
<6>[ 388.769017] ===PM: suspend exit 1970-01-01 00:27:39.078235547 UTC
<12>[ 388.771733] healthd: battery l=41 v=3788 t=33.0 h=2 st=3 c=22 chg=
<6>[ 388.845212] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
//有时候的log是如许:
[ 660.012739] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
[ 660.024107] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
[ 660.031016] Preemption disabled at:[< (null)>] (null)
<3>[ 660.012739] BUG: sleeping function called from invalid context at /home/whl/work/msm8909w_law_android/kernel/kernel/locking/mutex.c:97
<3>[ 660.024107] in_atomic(): 1, irqs_disabled(): 0, pid: 2043, name: android.bg
<3>[ 660.031016] Preemption disabled at:[< (null)>] (null)
<6>[ 660.036201]
<6>[ 660.036220] CPU: 2 PID: 2043 Comm: android.bg Not tainted 3.18.24 #20
<6>[ 660.036256] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[ 660.036281] [<c0011c34>] (show_stack) from [<c0948d74>] (dump_stack+0x6c/0xb8)
<6>[ 660.036301] [<c0948d74>] (dump_stack) from [<c0950dac>] (mutex_lock+0x18/0x3c)
<6>[ 660.036323] [<c0950dac>] (mutex_lock) from [<c03bbe44>] (kgsl_get_egl_counts+0x24/0x98)
<6>[ 660.036346] [<c03bbe44>] (kgsl_get_egl_counts) from [<c03d05e4>] (print_mem_entry+0x128/0x224)
<6>[ 660.036367] [<c03d05e4>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[ 660.036387] [<c026cf90>] (idr_for_each) from [<c03d0764>] (process_mem_print+0x84/0xcc)
<6>[ 660.036410] [<c03d0764>] (process_mem_print) from [<c01466cc>] (seq_read+0x1a8/0x400)
<6>[ 660.036432] [<c01466cc>] (seq_read) from [<c0128f28>] (vfs_read+0x90/0x124)
<6>[ 660.036450] [<c0128f28>] (vfs_read) from [<c0129468>] (SyS_read+0x40/0x80)
<6>[ 660.036470] [<c0129468>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
[ 660.101324] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[ 660.130359] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
[ 660.403810] ===wakeup_source_activate(), ws->name = PowerManagerService.Broadcasts
<3>[ 660.101324] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[ 660.130359] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[ 660.403294] ===state_store,state = 3
<6>[ 660.403311] ===pm_suspend,state = 3
<6>[ 660.403329] ===PM: suspend entry 1970-01-01 00:32:18.604926534 UTC
<6>[ 660.403341] ===PM: Syncing filesystems ...
<3>[ 660.403810] ===wakeup_source_a[ 660.439197] ===wakeup_source_activate(), ws->name = NETLINK
ctivate(), ws->name = PowerManagerService.Broadcasts
[ 660.449994] ===wakeup_source_activate(), ws->name = eventpoll
[ 660.459654] ===wakeup_source_deactivate(), ws->name = NETLINK
<6>[ 660.437900] done.
<6>[ 660.437922] ===PM: Preparing syst[ 660.466390] ===wakeup_source_deactivate(), ws->name = PowerManagerService.Broadcasts
[ 660.472932] Freezing of tasks aborted after 0.002 seconds
[ 660.474160] ===Error: returning -512 value
em for mem sleep
<3>[ 660.439197] ===wakeup_source_activate(), ws->name = NETLINK
<3>[ 660.449994] ===wakeup_source_activate(), ws->name = eventpoll
<6>[ 660.472836] Freezing user space processes ...
<6>[ 660.472837] ===PM: Wakeup pending, aborting suspend
<6>[ 660.472884] ===active wakeup source: eventpoll
<6>[ 660.472924]
<3>[ 660.472932] Freezing of tasks aborted after 0.002 seconds
<6>[ 660.474159] Restarting tasks ...
<3>[ 660.474160] ===Error: returning -512 value
<6>[ 660.474289] done.
<6>[ 660.474450] ===PM: suspend_prepare return -16
<6>[ 660.474464] ===PM: suspend exit 1970-01-01 00:32:18.676061065 UTC//休眠失败
[ 660.582369] ===Error: returning -512 value
[ 660.620211] migrate_irqs: 310 callbacks suppressed
[ 660.620217] IRQ0 no longer affine to CPU3
[ 660.620223] IRQ1 no longer affine to CPU3
[ 660.620229] IRQ2 no longer affine to CPU3
[ 660.620235] IRQ3 no longer affine to CPU3
[ 660.620241] IRQ4 no longer affine to CPU3
[ 660.620246] IRQ5 no longer affine to CPU3
[ 660.620253] IRQ6 no longer affine to CPU3
[ 660.620258] IRQ7 no longer affine to CPU3
[ 660.620264] IRQ8 no longer affine to CPU3
[ 660.620270] IRQ9 no longer affine to CPU3
[ 660.621415] CPU3: shutdown
<6>[ 660.575870] ===state_store,state = 660.760744] healthd: battery l=39 v=3788 t=34.0 h=2 st=3 c=22 chg=
<6>[ 660.575888] ===pm_suspend,state = 3//再次休眠
<6>[ 660.575907] ===PM: suspend entry 1970-01-01 00:32:18.777503617 UTC
<6>[ 660.575919] ===PM: Syncing filesystems ... done.
<6>[ 660.578345] ===PM: Preparing system for mem sleep
<6>[ 660.578953] Freezing user space processes ...
<3>[ 660.582369] ===Error: returning -512 value
<6>[ 660.587419] (elapsed 0.008 seconds) done.
<6>[ 660.587445] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 660.590297] ===PM: suspend_prepare return 0
<6>[ 660.590310] ===PM: Entering mem sleep
<6>[ 660.590321] Suspending console(s) (use no_console_suspend to debug)
<6>[ 660.613996] PM: suspend of devices complete after 22.325 msecs
<6>[ 660.616035] PM: late suspend of devices complete after 2.025 msecs
<6>[ 660.619435] PM: noirq suspend of devices complete after 3.386 msecs
<6>[ 660.619453] Disabling non-boot CPUs ...
//休眠乐成
<4>[ 660.620211] migrate_irqs: 310 callbacks suppressed
<4>[ 660.620217] IRQ0 no longer affine to CPU3
<4>[ 660.620223] IRQ1 no longer affine to CPU3
<4>[ 660.620229] IRQ2 no longer affine to CPU3
<4>[ 660.620235] IRQ3 no longer affine to CPU3
<4>[ 660.620241] IRQ4 no longer affine to CPU3
<4>[ 660.620246] IRQ5 no longer affine to CPU3
<4>[ 660.620253] IRQ6 no longer affine to CPU3
<4>[ 660.620258] IRQ7 no longer affine to CPU3
<4>[ 660.620264] IRQ8 no longer affine to CPU3
<4>[ 660.620270] IRQ9 no longer affine to CPU3
<5>[ 660.621415] CPU3: shutdown
<6>[ 660.622703] CPU2:msm_cpu_pm_enter_sleep mode:3 during suspend
//POWER按键唤醒
<6>[ 660.622923] Enabling non-boot CPUs ...
<6>[ 660.623366] CPU3: Booted secondary processor
<6>[ 660.624144] CPU3 is up
<6>[ 660.625197] PM: noirq resume of devices complete after 1.026 msecs
<6>[ 660.626962] PM: early resume of devices complete after 1.127 msecs
<6>[ 660.705031] PM: resume of devices complete after 78.051 msecs
<6>[ 660.753109] ===PM: suspend_devices_and_enter return 0
<6>[ 660.753120] Restarting tasks ... done.
<6>[ 660.759976] ===PM: suspend exit 1970-01-01 00:32:29.074370331 UTC
<12>[ 660.760744] healthd: battery l=39 v=3788 t=34.0 h=2 st=3 c=22 chg=
<6>[ 660.841382] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
说明不管是MIPI屏幕还是SPI屏幕,其实串口log都是正常打印的,有实行正常的suspend流程,
虽然SPI屏幕不能一下子就休眠乐成,但是终极也是有正常休眠下去
----------------------------------------------------------------------------
高通给出了以下方法查看体系信息:
1) cat /sys/kernel/debug/rpm_master_stats
2) cat /sys/kernel/debug/rpm_stats
SPI屏幕,实行频频休眠操纵之后,实行结果如下:
1.MSM8909W手表:/ # cat sys/kernel/debug/rpm_master_stats
APSS
shutdown_req:0x27D7B5FF2
wakeup_ind:0x27D7C642E
bringup_req:0x27D7C64CA
bringup_ack:0x27D7C651A
last_sleep_transition_duration:0x2694
last_wake_transition_duration:0x4cd
wakeup_reason:0x1
numshutdowns:0x191d
active_cores:0x1//说明休眠的时候,AP侧在运动,
core0
MPSS
shutdown_req:0x27D790F10
wakeup_ind:0x27D78B0AA
bringup_req:0x27D78B188
bringup_ack:0x27D78B1D8
last_sleep_transition_duration:0x3550
last_wake_transition_duration:0x4057
wakeup_reason:0x0
numshutdowns:0x3faa
active_cores:0x0//说明休眠的时候,Modem已经不在激活状态,已经睡下去了
PRONTO
shutdown_req:0x41FEF1B7
wakeup_ind:0x22A54001
bringup_req:0x41FDB9A8
bringup_ack:0x41FDDD94
last_sleep_transition_duration:0x1aa5
last_wake_transition_duration:0x1f74
wakeup_reason:0x0
numshutdowns:0x8
active_cores:0x0//说明休眠的时候,wlan已经不在激活状态,已经睡下去了
2.
130|MSM8909W手表:/ # cat /sys/kernel/debug/rpm_stats
RPM Mode:vlow
count:0//说明一次vlow的计数都没有
time in last mode(msec):0
time since last mode(sec):605
actual last sleep(msec):0
client votes: 0x03010301
RPM Mode:vmin
count:0//说明一次vmin的计数都没有,说明一次进入低功耗休眠都没有
time in last mode(msec):0
time since last mode(sec):605
actual last sleep(msec):0
client votes: 0x00000000
MIPI屏的结果如下:
MSM8909W手表:/ # cat sys/kernel/debug/rpm_stats
RPM Mode:vlow
count:0
time in last mode(msec):0
time since last mode(sec):510
actual last sleep(msec):0
client votes: 0x03010301
RPM Mode:vmin
count:13//说明白实有频频进入了低功耗模式
time in last mode(msec):2000
time since last mode(sec):2
actual last sleep(msec):25000
client votes: 0x00000000
由此可以确认SPI屏幕虽然有走完suspend的流程,但是体系其实并没有真正进入低功耗模式。
-----------------------------------------------------------------
高通再次提供几个log开关,实行以下几个开关
1) echo 9 > /sys/module/mpm_of/parameters/debug_mask //这条log太多,而且参考意义不大
我们查看下面三个开关的log
2) echo 1 > /sys/module/msm_show_resume_irq/parameters/debug_mask
3) echo 0 >/sys/module/qpnp_rtc/parameters/poweron_alarm
4) echo 1 > /sys/kernel/debug/clk/debug_suspend
//按POWER按键休眠,一会儿后再按POWER按键唤醒
//后抓取SPI suspend的log:
[ 264.990537] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[ 265.021330] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[ 264.990537] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[ 265.021330] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[ 265.327869] ===state_store,state = 3
<6>[ 265.327887] ===pm_suspend,state = 3
<6>[ 265.327905] ===PM: suspend entry 1970-01-01 01:19:57.968042290 UTC
[ 265.357053] ===Error: returning -512 value
[ 265.400397] migrate_irqs: 310 callbacks suppressed
[ 265.400403] IRQ0 no longer affine to CPU3
[ 265.400409] IRQ1 no longer affine to CPU3
[ 265.400415] IRQ2 no longer affine to CPU3
[ 265.400421] IRQ3 no longer affine to CPU3
[ 265.400426] IRQ4 no longer affine to CPU3
[ 265.400432] IRQ5 no longer affine to CPU3
[ 265.400438] IRQ6 no longer affine to CPU3
[ 265.400443] IRQ7 no longer affine to CPU3
[ 265.400450] IRQ8 no longer affine to CPU3
[ 265.400455] IRQ9 no longer affine to CPU3
[ 265.401558] CPU3: shutdown
[ 265.402823] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
[ 265.402823] gic_show_resume_irq: 200 triggered qcom,smd-rpm
[ 265.402823] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[ 265.327917] ===PM: Syncing filesystems ... done.
<6>[ 265.353215] ===PM: Preparing system for mem sleep
<6>[ 265.353812] Freezing user space processes ...
<3>[ 265.357053] ===Error: returning -512 value
<6>[ 265.360946] (elapsed 0.007 seconds) done.
<6>[ 265.360970] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 265.363531] ===PM: suspend_prepare return 0
<6>[ 265.363544] ===PM: Entering mem sleep
<6>[ 265.363555] Suspending console(s) (use no_console_suspend to debug)
<6>[ 265.394219] PM: suspend of devices complete after 29.329 msecs
<6>[ 265.396241] PM: late suspend of devices complete after 2.008 msecs
<6>[ 265.399617] PM: noirq suspend of devices complete after 3.361 msecs
<6>[ 265.399635] Disabling non-boot CPUs ...
<4>[ 265.400397] migrate_irqs: 310 callbacks suppressed
<4>[ 265.400403] IRQ0 no longer affine to CPU3
<4>[ 265.400409] IRQ1 no longer affine to CPU3
<4>[ 265.400415] IRQ2 no longer affine to CPU3
<4>[ 265.400421] IRQ3 no longer affine to CPU3
<4>[ 265.400426] IRQ4 no longer affine to CPU3
<4>[ 265.400432] IRQ5 no longer affine to CPU3
<4>[ 265.400438] IRQ6 no longer affine to CPU3
<4>[ 265.400443] IRQ7 no longer affine to CPU3
<4>[ 265.400450] IRQ8 no longer affine to CPU3
<4>[ 265.400455] IRQ9 no longer affine to CPU3
<5>[ 265.401558] CPU3: shutdown
<6>[ 265.402823] Enabled clocks:
<6>[ 265.402823] xo_clk_src:1:1 [19200000]
<6>[ 265.402823] xo_a_clk_src:2:2 [19200000]
<6>[ 265.402823] pcnoc_a_clk:1:1 [19200000]
<6>[ 265.402823] bimc_clk:1:1 [95944704]
<6>[ 265.402823] bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
<6>[ 265.402823] bimc_a_clk:1:1 [383909888]
<6>[ 265.402823] bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
<6>[ 265.402823] pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
<6>[ 265.402823] qdss_clk:5:5 [1000]
<6>[ 265.402823] xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 265.402823] gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 265.402823] apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 265.402823] mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[ 265.402823] vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gcc_boot_rom_ahb_clk:1:1 [0]
<6>[ 265.402823] gcc_apss_tcu_clk:1:0 [0]
<6>[ 265.402823] gcc_gfx_tcu_clk:1:0 [0]
<6>[ 265.402823] gcc_smmu_cfg_clk:2:0 [0]
<6>[ 265.402823] gcc_mdss_ahb_clk:1:1 [0]
<6>[ 265.402823] gcc_mdss_axi_clk:1:1 [0]
<6>[ 265.402823] gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[ 265.402823] gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gcc_mss_cfg_ahb_clk:1:1 [0]
<6>[ 265.402823] gcc_mss_q6_bimc_axi_clk:1:1 [0]
<6>[ 265.402823] gcc_usb2a_phy_sleep_clk:1:1 [0]
<6>[ 265.402823] a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [192]
<6>[ 265.402823] Enabled clock count: 28
<6>[ 265.402823] CPU1:msm_cpu_pm_enter_sleep mode:3 during suspend//正常休眠
<4>[ 265.402823] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
<4>[ 265.402823] gic_show_resume_irq: 200 triggered qcom,smd-rpm
<4>[ 265.402823] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[ 265.403036] Enabling non-boot CPUs ...
<6>[ 265.403478] CPU3: Booted secondary processor
<6>[ 265.404268] CPU3 is up
<6>[ 265.405309] PM: noirq resume of devices complete after 1.013 msecs
<6>[ 265.407061] PM: early resume of devices complete after 1.120 msecs
<6>[ 265.484078] PM: resume of devices complete after 76.994 msecs
<6>[ 265.551232] ===PM: suspend_devices_and_enter return 0
<6>[ 265.627343] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
//别的一次的log:
[ 294.738757] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
[ 294.759936] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<3>[ 294.738757] mdss_spi_panel_event_handler: MDSS_EVENT_BLANK
<3>[ 294.759936] mdss_spi_panel_event_handler: MDSS_EVENT_PANEL_OFF
<6>[ 295.067956] ===state_store,state = 3
<6>[ 295.067975] ===pm_suspend,state = 3
<6>[ 295.067993] ===PM: suspend entry 1970-01-01 01:22:27.166584151 UTC
[ 295.104113] ===Error: returning -512 value
[ 295.151592] migrate_irqs: 950 callbacks suppressed
[ 295.151598] IRQ0 no longer affine to CPU3
[ 295.151603] IRQ1 no longer affine to CPU3
[ 295.151610] IRQ2 no longer affine to CPU3
[ 295.151616] IRQ3 no longer affine to CPU3
[ 295.151622] IRQ4 no longer affine to CPU3
[ 295.151627] IRQ5 no longer affine to CPU3
[ 295.151633] IRQ6 no longer affine to CPU3
[ 295.151638] IRQ7 no longer affine to CPU3
[ 295.151645] IRQ8 no longer affine to CPU3
[ 295.151650] IRQ9 no longer affine to CPU3
[ 295.152756] CPU3: shutdown
[ 295.154066] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
[ 295.154066] gic_show_resume_irq: 200 triggered qcom,smd-rpm
[ 295.154066] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[ 295.068005] ===PM: Syncing filesystems ... done.
<6>[ 295.101672] ===PM: Preparing system for mem sleep
<6>[ 295.102275] Freezing user space processes ...
<3>[ 295.104113] ===Error: returning -512 value
<6>[ 295.110054] (elapsed 0.007 seconds) done.
<6>[ 295.110080] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
<6>[ 295.112824] ===PM: suspend_prepare return 0
<6>[ 295.112836] ===PM: Entering mem sleep
<6>[ 295.112848] Suspending console(s) (use no_console_suspend to debug)
<6>[ 295.145565] PM: suspend of devices complete after 31.384 msecs
<6>[ 295.147593] PM: late suspend of devices complete after 2.014 msecs
<6>[ 295.150976] PM: noirq suspend of devices complete after 3.368 msecs
<6>[ 295.150993] Disabling non-boot CPUs ...
<4>[ 295.151592] migrate_irqs: 950 callbacks suppressed
<4>[ 295.151598] IRQ0 no longer affine to CPU3
<4>[ 295.151603] IRQ1 no longer affine to CPU3
<4>[ 295.151610] IRQ2 no longer affine to CPU3
<4>[ 295.151616] IRQ3 no longer affine to CPU3
<4>[ 295.151622] IRQ4 no longer affine to CPU3
<4>[ 295.151627] IRQ5 no longer affine to CPU3
<4>[ 295.151633] IRQ6 no longer affine to CPU3
<4>[ 295.151638] IRQ7 no longer affine to CPU3
<4>[ 295.151645] IRQ8 no longer affine to CPU3
<4>[ 295.151650] IRQ9 no longer affine to CPU3
<5>[ 295.152756] CPU3: shutdown
<6>[ 295.154066] Enabled clocks:
<6>[ 295.154066] xo_clk_src:1:1 [19200000]
<6>[ 295.154066] xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] pcnoc_a_clk:1:1 [19200000]
<6>[ 295.154066] bimc_clk:1:1 [95944704]
<6>[ 295.154066] bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
<6>[ 295.154066] bimc_a_clk:1:1 [383909888]
<6>[ 295.154066] bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
<6>[ 295.154066] pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
<6>[ 295.154066] qdss_clk:5:5 [1000]
<6>[ 295.154066] xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[ 295.154066] vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] gcc_boot_rom_ahb_clk:1:1 [0]
<6>[ 295.154066] gcc_apss_tcu_clk:1:0 [0]
<6>[ 295.154066] gcc_gfx_tcu_clk:1:0 [0]
<6>[ 295.154066] gcc_smmu_cfg_clk:2:0 [0]
<6>[ 295.154066] gcc_mdss_ahb_clk:1:1 [0]
<6>[ 295.154066] gcc_mdss_axi_clk:1:1 [0]
<6>[ 295.154066] gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[ 295.154066] gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] gcc_mss_cfg_ahb_clk:1:1 [0]
<6>[ 295.154066] gcc_mss_q6_bimc_axi_clk:1:1 [0]
<6>[ 295.154066] gcc_usb2a_phy_sleep_clk:1:1 [0]
<6>[ 295.154066] a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [192]
<6>[ 295.154066] Enabled clock count: 28
<6>[ 295.154066] CPU1:msm_cpu_pm_enter_sleep mode:3 during suspend//正常休眠
<4>[ 295.154066] __qpnpint_handle_irq: 43 triggered [0x0, 0x08,0x0] qpnp_kpdpwr_status
<4>[ 295.154066] gic_show_resume_irq: 200 triggered qcom,smd-rpm
<4>[ 295.154066] gic_show_resume_irq: 222 triggered 200f000.qcom,spmi
<6>[ 295.154275] Enabling non-boot CPUs ...
<6>[ 295.154716] CPU3: Booted secondary processor
<6>[ 295.155511] CPU3 is up
<6>[ 295.156551] PM: noirq resume of devices complete after 1.012 msecs
<6>[ 295.158328] PM: early resume of devices complete after 1.125 msecs
<6>[ 295.233722] PM: resume of devices complete after 75.378 msecs
<6>[ 295.301148] ===PM: suspend_devices_and_enter return 0
<6>[ 295.372174] ctrl_pdata->rst_gpio = 25,ctrl_pdata->disp_dc_gpio = 23
我们重点关注休眠的时候,enable的CLK和MIPI屏幕有什么区别,可以看到SPI屏幕有28个时钟源:
<6>[ 295.154066] Enabled clocks:
<6>[ 295.154066] xo_clk_src:1:1 [19200000]
<6>[ 295.154066] xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] pcnoc_a_clk:1:1 [19200000]
<6>[ 295.154066] bimc_clk:1:1 [95944704]
<6>[ 295.154066] bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
<6>[ 295.154066] bimc_a_clk:1:1 [383909888]
<6>[ 295.154066] bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
<6>[ 295.154066] pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
<6>[ 295.154066] qdss_clk:5:5 [1000]
<6>[ 295.154066] xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
<6>[ 295.154066] mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[ 295.154066] vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] gcc_boot_rom_ahb_clk:1:1 [0]
<6>[ 295.154066] gcc_apss_tcu_clk:1:0 [0]
<6>[ 295.154066] gcc_gfx_tcu_clk:1:0 [0]
<6>[ 295.154066] gcc_smmu_cfg_clk:2:0 [0]
<6>[ 295.154066] gcc_mdss_ahb_clk:1:1 [0]
<6>[ 295.154066] gcc_mdss_axi_clk:1:1 [0]
<6>[ 295.154066] gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[ 295.154066] gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 295.154066] gcc_mss_cfg_ahb_clk:1:1 [0]
<6>[ 295.154066] gcc_mss_q6_bimc_axi_clk:1:1 [0]
<6>[ 295.154066] gcc_usb2a_phy_sleep_clk:1:1 [0]
<6>[ 295.154066] a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [192]
<6>[ 295.154066] Enabled clock count: 28
而MIPI屏幕只有19个时钟源
[ 324.861193] Enabled clocks:
[ 324.861193] xo_a_clk_src:2:2 [19200000]
[ 324.861193] pcnoc_a_clk:1:1 [19200000]
[ 324.861193] bimc_clk:1:1 [95944704]
[ 324.861193] bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
[ 324.861193] bimc_a_clk:1:1 [383909888]
[ 324.861193] bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
[ 324.861193] pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
[ 324.861193] qdss_clk:5:5 [1000]
[ 324.861193] xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] gcc_boot_rom_ahb_clk:1:1 [0]
[ 324.861193] gcc_apss_tcu_clk:1:0 [0]
[ 324.861193] gcc_gfx_tcu_clk:1:0 [0]
[ 324.861193] gcc_smmu_cfg_clk:2:0 [0]
[ 324.861193] gcc_mss_cfg_ahb_clk:1:1 [0]
[ 324.861193] gcc_mss_q6_bimc_axi_clk:1:1 [0]
[ 324.861193] gcc_usb2a_phy_sleep_clk:1:1 [0]
[ 324.861193] a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 324.861193] Enabled clock count: 19
SPI多了以下9个时钟源没有被关闭:
<6>[ 265.402823] xo_clk_src:1:1 [19200000]
<6>[ 265.402823] xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [192000]
<6>[ 265.402823] vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
<6>[ 265.402823] gcc_mdss_ahb_clk:1:1 [0]
<6>[ 265.402823] gcc_mdss_axi_clk:1:1 [0]
<6>[ 265.402823] gcc_mdss_mdp_clk:1:1 [0] -> mdp_clk_src:2:2 [160000000, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:2:2 [1920000]
<6>[ 265.402823] gcc_mdss_vsync_clk:1:1 [0] -> vsync_clk_src:1:1 [19200000, 1] -> xo_clk_src:2:2 [19200000] -> xo_clk_src:1:1 [19200000]
mdp_clk_src,gcc_mdss_ahb_clk,gcc_mdss_axi_clk,gcc_mdss_mdp_clk,gcc_mdss_vsync_clk都是显示干系的CLK,
mdp3.h有相对应的CLK的定义:
enum {
MDP3_CLK_AHB,
MDP3_CLK_AXI,
MDP3_CLK_MDP_SRC,
MDP3_CLK_MDP_CORE,
MDP3_CLK_VSYNC,
MDP3_CLK_DSI,
MDP3_MAX_CLK
};
mdp3.c里mdp3_clk_enable有控制到这些时钟源:
int mdp3_clk_enable(int enable, int dsi_clk)
{
...
rc = mdp3_clk_update(MDP3_CLK_AHB, enable);
rc |= mdp3_clk_update(MDP3_CLK_AXI, enable);
rc |= mdp3_clk_update(MDP3_CLK_MDP_SRC, enable);
rc |= mdp3_clk_update(MDP3_CLK_MDP_CORE, enable);
rc |= mdp3_clk_update(MDP3_CLK_VSYNC, enable);
...
}
可以看出这些CLK都是MDP显示干系的CLK,说明MDP有些CLK没有关闭。搜刮mdp3_clk_enable被调用的地方,发现问题是在mdp3_is_display_on没有调用mdp3_clk_enable
来关闭时钟源。mdp3_is_display_on只会去关闭MIPI_CMD_PANEL的屏幕,并不会关闭SPI_PANEL的屏幕,所以要加上SPI_PANEL类型判断。
diff --git a/kernel/drivers/video/msm/mdss/mdp3.c b/kernel/drivers/video/msm/mdss/mdp3.c
index d8feb8c..79ba58f 100644
--- a/kernel/drivers/video/msm/mdss/mdp3.c
+++ b/kernel/drivers/video/msm/mdss/mdp3.c
@@ -2265,7 +2265,7 @@ static int mdp3_is_display_on(struct mdss_panel_data *pdata)
mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_ADDR);
- if ((pdata->panel_info.type == MIPI_CMD_PANEL) ||(!rc)) {
+ if ((pdata->panel_info.type == MIPI_CMD_PANEL) ||(!rc)||(pdata->panel_info.type == SPI_PANEL)) {
if (mdp3_clk_enable(0, 0))
pr_err("fail to turn off MDP core clks\n");
}
在这里关闭CLK,功耗就正常了,降落到0.4mA,
查看下mdp3_is_display_on的调用关系,看到底是哪里没有关闭时钟源,调用关系如下(被调用者<-调用者)
mdp3_is_display_on<-mdp3_panel_register_done<-mdp3_probe(.panel_register_done = mdp3_panel_register_done,)<-panel_register_done<-mdss_register_panel<-spi_panel_device_register<-mdss_spi_panel_probe(.probe = mdss_spi_panel_probe,)
说明是SPI屏幕驱动,在一开始probe的时候就没有去关闭,后面就不绝开着直到睡眠,由于SPI屏幕是通过内存映射直接将数据送到SPI接口,都没有走MDP3对应的接口,
所以后面也没有去关闭对应的MDP core clks的时钟。但是MIPI由于会走MDP3对应的接口,虽然一开始时钟也是关闭的,但是后面体系在正常运行的时候会去动态的打开
或关闭时钟,终极也是有关闭时钟的,所以MIPI的时钟终极关闭并到达要求的功耗。自此,问题办理。
---------------------------------------------------------------
调试技巧1:打开suspend模式的串口打印,禁止串口休眠,命令行实行命令:echo N > sys/module/printk/parameters/console_suspend
别的调试过程中,有个比较实用的调试技巧就是打开休眠状态下的串口打印,休眠不关闭串口打印log:
工程代码搜刮no_console_suspend,kernel/Documentation/kernel-parameters.txt
no_console_suspend [HW] Never suspend the console
Disable suspending of consoles during suspend and
hibernate operations. Once disabled, debugging
messages can reach various consoles while the rest
of the system is being put to sleep (ie, while
debugging driver suspend/resume hooks). This may
not work reliably with all consoles, but is known
to work with serial and VGA consoles.
To facilitate more flexible debugging, we also add
console_suspend, a printk module parameter to control
it. Users could use console_suspend (usually
/sys/module/printk/parameters/console_suspend) to
turn on/off it dynamically.
echo N > sys/module/printk/parameters/console_suspend
可以通过动态修改 sys/module/printk/parameters/console_suspend为N,就可以休眠时打开串口打印,但是终极也是会关闭,只是会尽大概打印更多的suspend Log
原来的值是Y,末了一条只会打印到:
[ 295.835596] Suspending console(s) (use no_console_suspend to debug)
没打印出来的log,只能在下次按POWER按键唤醒的时候,连同唤醒log一起打印出来。
[ 449.510464] Enabled clocks:
[ 449.510464] xo_clk_src:1:1 [19200000]
[ 449.510464] xo_a_clk_src:2:2 [19200000]
[ 449.510464] pcnoc_a_clk:1:1 [19200000]
[ 449.510464] bimc_clk:1:1 [95944704]
[ 449.510464] bimc_msmbus_clk:1:1 [95944704] -> bimc_clk:1:1 [95944704]
[ 449.510464] bimc_a_clk:1:1 [383909888]
[ 449.510464] bimc_msmbus_a_clk:1:1 [383909888] -> bimc_a_clk:1:1 [383909888]
[ 449.510464] pcnoc_keepalive_a_clk:1:1 [19200000] -> pcnoc_a_clk:1:1 [19200000]
[ 449.510464] qdss_clk:5:5 [1000]
[ 449.510464] xo_clk_src:1:1 [19200000] -> xo_clk_src:1:1 [19200000]
[ 449.510464] gpll0_clk_src:1:1 [800000000] -> xo_clk_src:1:1 [19200000] -> xo_clk_src:1:1 [19200000]
[ 449.510464] xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 449.510464] gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 449.510464] apss_ahb_clk_src:1:1 [19200000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 449.510464] blsp1_uart1_apps_clk_src:1:1 [7372800, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk_src:1:1 [19200000] -> xo_clk_src:1:1 [192]
[ 449.510464] gcc_blsp1_ahb_clk:1:1 [0]
[ 449.510464] gcc_boot_rom_ahb_clk:1:1 [0]
[ 449.510464] gcc_apss_tcu_clk:1:0 [0]
[ 449.510464] gcc_gfx_tcu_clk:1:0 [0]
[ 449.510464] gcc_smmu_cfg_clk:2:0 [0]
[ 449.510464] gcc_blsp1_uart1_apps_clk:1:1 [7372800] -> blsp1_uart1_apps_clk_src:1:1 [7372800, 1] -> gpll0_clk_src:1:1 [800000000] -> xo_clk]
[ 449.510464] gcc_mss_cfg_ahb_clk:1:1 [0]
[ 449.510464] gcc_mss_q6_bimc_axi_clk:1:1 [0]
[ 449.510464] gcc_usb2a_phy_sleep_clk:1:1 [0]
[ 449.510464] a7ssmux:1:1 [800000000, 1] -> gpll0_ao_clk_src:1:1 [800000000] -> xo_a_clk_src:2:2 [19200000] -> xo_a_clk_src:2:2 [19200000]
[ 449.510464] Enabled clock count: 25
但是打开串口开关,可以看到gcc_blsp1_uart1_apps_clk,串口的时钟源,不会被关闭,电流将到达20mA,msm8909w这个平台不会去真正关闭串口,其他平台有的会直接关闭串口时钟,平台有差异,所以打开串口只作为调试本领,真正测算功耗电流的时候应该把休眠下的串口打印关闭
echo Y > sys/module/printk/parameters/console_suspend
---------------------------------------------------------------
调试技巧2:让串口打印所有级别的log,命令行实行命令:# echo 8 > /proc/sys/kernel/printk
串口日记级别:
日誌級別一共有8個級別,printk的日誌級別定義如下
kernel/include/linux/kern_levels.h
#define KERN_EMERG KERN_SOH "0" /* system is unusable */
#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
#define KERN_CRIT KERN_SOH "2" /* critical conditions */
#define KERN_ERR KERN_SOH "3" /* error conditions */
#define KERN_WARNING KERN_SOH "4" /* warning conditions */
#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
#define KERN_INFO KERN_SOH "6" /* informational */
#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
MSM8909W手表:/ # cat proc/sys/kernel/printk
6 6 1 7
上面顯示的4個數據分別對應
控制台日誌級別:优先级高于该值的消息将被打印至控制台
默認的消息日誌級別:将用该优先级来打印没有优先级的消息(printk("HelloWorld");)
最低的控制台日誌級別:控制台日记级别可被设置的最小值(最高优先级)
默認的控制台日誌級別:控制台日记级别的缺省值
(1)第一个参数6 表现小于6优先级消息才会被输出到控制台。
(2)第二个参数6 表现默认的printk消息优先级别,即printk(“hell world”);优先级为6, 由于6不<6,故不可以被打印到控制台。
(3)第三个参数1 表现可吸取的最高优先级,当printk disable控制台输出时,设置第一个参数为1,但是,从内核品级来看,还有优先级0,这个是printk最高级优先级,一样平常用于内核严肃消息打印。比如内存错误或者 watchdog reset.也可以设置第一个和第三个参数为0
(4)第四个参数7 默认控制台优先级,即第一个参数的默认优先级。
當printk日誌級別小於console_loglevel時,消息才能顯示出來。 變量console_loglevel的初始值是CONSOLE_LOGLEVEL_DEFAULT(7),可以通過sys_syslog系統調用進行修改。調用klogd時可以指定-c開關選項來修改這個變量。假如要修改它的當前值,必須先殺掉klogd,再加-c選項重新啟動它。數值越小日誌級別越高,分為從 0-7共計8個日誌級別),假如該字段的日記級別高於console默認的日誌級別那麼才會打印出來。也就是printk日记级别小于7的才会被打印出来,至少要KERN_INFO及以上级别才会被打印出来
int console_printk[4] = {
CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */7
MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */
CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel */1
CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */7
};
所以printk() 可以如许用:printk(KERN_INFO "Hello, world!\n");
沒有指定日誌級別的printk語句默認採用的級別是:MESSAGE_LOGLEVEL_DEFAULT(這個默認級別一样平常為<4>,即與KERN_WARNING在一個級別上),其定義在kernel/printk.c中可以找到。但我们体系中是
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT
搜刮工程CONFIG_MESSAGE_LOGLEVEL_DEFAULT只发现以下
./out/target/product/MSM8909W/obj/KERNEL_OBJ/include/config/auto.conf:1219:CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
./out/target/product/MSM8909W/obj/KERNEL_OBJ/include/generated/autoconf.h:1221:#define CONFIG_MESSAGE_LOGLEVEL_DEFAULT 4
./out/target/product/MSM8909W/obj/KERNEL_OBJ/.config.old:3677:CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
./out/target/product/MSM8909W/obj/KERNEL_OBJ/.config:3677:CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
所以不知道为什么体系起来后看到的是6
可用下面的命令設置當前日誌級別:
# echo 8 > /proc/sys/kernel/printk
MSM8909W手表:/ # cat proc/sys/kernel/printk
8 6 1 7
這樣所有級別<8,(0-7)的消息都可以顯示在控制台上.
我想屏蔽掉所有的内核printk打印,那么我只必要把第一个数值调到最小值1或者0。
# echo 1 6 1 7> /proc/sys/kernel/printk
或者
# echo 0 6 0 7 > /proc/sys/kernel/printk
======================================================================
MSM8909W原生动绘图片: android闪动效果
frameworks/base/core/res/assets/images/android-logo-mask.png
==============================================================
关于panel crash的问题
<6>[ 660.036256] [<c00147f0>] (unwind_backtrace) from [<c0011c34>] (show_stack+0x10/0x14)
<6>[ 660.036281] [<c0011c34>] (show_stack) from [<c0948d74>] (dump_stack+0x6c/0xb8)
<6>[ 660.036301] [<c0948d74>] (dump_stack) from [<c0950dac>] (mutex_lock+0x18/0x3c)
<6>[ 660.036323] [<c0950dac>] (mutex_lock) from [<c03bbe44>] (kgsl_get_egl_counts+0x24/0x98)
<6>[ 660.036346] [<c03bbe44>] (kgsl_get_egl_counts) from [<c03d05e4>] (print_mem_entry+0x128/0x224)
<6>[ 660.036367] [<c03d05e4>] (print_mem_entry) from [<c026cf90>] (idr_for_each+0xac/0xd4)
<6>[ 660.036387] [<c026cf90>] (idr_for_each) from [<c03d0764>] (process_mem_print+0x84/0xcc)
<6>[ 660.036410] [<c03d0764>] (process_mem_print) from [<c01466cc>] (seq_read+0x1a8/0x400)
<6>[ 660.036432] [<c01466cc>] (seq_read) from [<c0128f28>] (vfs_read+0x90/0x124)
<6>[ 660.036450] [<c0128f28>] (vfs_read) from [<c0129468>] (SyS_read+0x40/0x80)
<6>[ 660.036470] [<c0129468>] (SyS_read) from [<c000e060>] (ret_fast_syscall+0x0/0x38)
关于内核会打印以上log,从print_mem_entry可以看出read the debugfs node too fast,
print_mem_entry()的调用关系是print_mem_entry()<-process_mem_print()<-process_mem_open(),
static const struct file_operations process_mem_fops = {
.open = process_mem_open,
终极是调用了kgsl_debugfs.c驱动的open,这个文件高通有个patch:
https://source.codeaurora.org/quic/la/kernel/msm-3.18/commit/?h=rel%2Fmsm-3.18&id=1868ddab68e2fe4b
合入这个patch之后,就不会有这个log打印了,关于这个patch的说明是:
msm: kgsl: use seq_file for mem_entry debugfs
A process may have many kgsl mem entries in use. Outputing all of them
as a single debugfs seq_file record takes twice as long as necessary
because seq_file must retry higher order page allocations for the output
buffer until it is large enough to hold all mem entries.
Additionally, process_mem_print() currently holds the spinlock
private->mem_lock during this process. This is too much time to
disable interrupts, and prevents locking mutex in print_mem_entry.
Change the kgsl_mem_entry debugfs functions to output one entry at a
time. Then the seq_file only need to kmalloc one page regardless of
the number of kgsl_mem_entries.
虽然不知道和panel crash有没有直接的关系,但是先把这个patch打上,后续有死机现象再详细分析。
看这个patch的说明,
Additionally, process_mem_print() currently holds the spinlock private->mem_lock during this process. This is too much time to disable interrupts, and prevents locking mutex in print_mem_entry.
有提到一个spinlock,但是似乎和crash dump的log不是同一个spinlock?
195.340327: <6> BUG: spinlock lockup suspected on CPU#3, mdss_fb0/5348
195.345485: <6> lock: 0xdd80a53c, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
由于你看QCAP的陈诉,死机的时候明显有调用到这个spinlock的流程,然后就死机了:
CPU 1 Call Stacks (dumped by TZ):
-000|arch_timer_read_counter_long()
-001|read_current_timer()
-002|__timer_delay()
-003|do_raw_spin_lock()
-004|_raw_spin_lock_irqsave()
-005|complete()//这里会去获取锁
-006|spi_panel_te_handler()
-007|handle_irq_event_percpu()
-008|handle_irq_event()
-009|handle_edge_irq()
-010|generic_handle_irq()
-011|msm_gpio_irq_handler()
-012|generic_handle_irq()
-013|__handle_domain_irq()
-014|gic_handle_irq()
-015|__irq_usr()
----|end of frame
=====================================================================================
MSM8909W手表 OTA升级说明
MSM8909W手表使用自定义ota的fotaapp,测试ota升级已经完成,必要测试部在测试一轮。
OTA初始包与后续ota升级包说明:
初始包最重要:
1.生成初始包必要先编译AP的代码(make -j)
2.将编译完后的out目次下的文件拷贝到MSM8909W手表工程LINUX目次下的out文件夹内
3.运行genbin后使用qfile的flat meta build生成emmc文件夹
4.将文件夹里的emmc_appsboot.mbn、 rpm.mbn 、tz.mbn、 sbl1.mbn、 NON-HLOS.bin 5个文件拷贝到AP devices/qcom/MSM8909W/radio/里
5.编译OTA包(make otapackage)
6.将编译完后的out目次下的文件拷贝到MSM8909W工程LINUX目次下的out文件夹内
7运行genbin后使用qfile的flat meta build生成emmc文件夹
8.将编译完OTA包的out文件夹里的emmc_appsboot.mbn、 rpm.mbn 、tz.mbn、 sbl1.mbn、 NON-HLOS.bin 5个文件拷贝到flat meta build生成emmc文件夹里替换原来的文件。
9.使用qfile下载初始版本到设备
OTA升级包
1.编译AP的代码(make -j)
2.将编译完后的out目次下的文件拷贝到MSM8909W工程LINUX目次下的out文件夹内
3.运行genbin后使用qfile的flat meta build生成emmc文件夹
4.将文件夹里的emmc_appsboot.mbn、 rpm.mbn 、tz.mbn、 sbl1.mbn、 NON-HLOS.bin 5个文件拷贝到AP devices/qcom/MSM8909W/radio/里
5.编译OTA升级包(make otapackage)
差分包生成与部署
1.打开艾拉比差分生成工具
2.选择原版本(初始包)与目的版本(升级包)的ota文件包(out下的target-files-package.zip)
3.不绝下一步直至部署完成。
=======================================
SPI屏幕在recovery模式显示显示异常的问题:
recovery模式下,adb shell默认进不了,必要在recovery菜单选择实行Mount /system终端才可以进入文件体系。recovery有本身的一套文件体系生成在out目次下:out/target/product/MSM8909W/recovery/root/res/images
进入之后所有的图片资源在体系目次下:/res/image/xxx.png
130|MSM8909W手表:/ # ls /res/images/
erasing_text.png loop00007.png loop00020.png loop00033.png loop00046.png loop00059.png loop00072.png loop00085.png
error_text.png loop00008.png loop00021.png loop00034.png loop00047.png loop00060.png loop00073.png loop00086.png
font.png loop00009.png loop00022.png loop00035.png loop00048.png loop00061.png loop00074.png loop00087.png
icon_error.png loop00010.png loop00023.png loop00036.png loop00049.png loop00062.png loop00075.png loop00088.png
installing_security_text.png loop00011.png loop00024.png loop00037.png loop00050.png loop00063.png loop00076.png loop00089.png
installing_text.png loop00012.png loop00025.png loop00038.png loop00051.png loop00064.png loop00077.png loop00090.png
loop00000.png loop00013.png loop00026.png loop00039.png loop00052.png loop00065.png loop00078.png no_command_text.png
loop00001.png loop00014.png loop00027.png loop00040.png loop00053.png loop00066.png loop00079.png progress_empty.png
loop00002.png loop00015.png loop00028.png loop00041.png loop00054.png loop00067.png loop00080.png progress_fill.png
loop00003.png loop00016.png loop00029.png loop00042.png loop00055.png loop00068.png loop00081.png stage_empty.png
loop00004.png loop00017.png loop00030.png loop00043.png loop00056.png loop00069.png loop00082.png stage_fill.png
loop00005.png loop00018.png loop00031.png loop00044.png loop00057.png loop00070.png loop00083.png
loop00006.png loop00019.png loop00032.png loop00045.png loop00058.png loop00071.png loop00084.png
然后把erasing_text.png拉出来看下是哪张图:adb pull res/images/erasing_text.png
android recovery模式支持adb shell必要在recovery菜单里选择Mount /system才能进行adb shell,
拉出来发现是351*5072的图片,对应分辨率是源码目次的msm8909w_law_android/bootable/recovery/res-xhdpi/images/erasing_text.png
定制小手机也是使用这个分辨率的图片(定制小手机 run graphic test除了进度条,其他笔墨图片显示正常),康健手表项目的320*320的屏幕也是使用xhdpi的图片(但是康健手表项目的run graphic test显示正常,且进度条也正常,APP同事之前OTA升级的时候,MSM8909W手表 320P的屏幕,显示也正常,进度条也正常)
其他分辨率的erasing_text.png图片巨细如下:
mdpi:173*2602
hdpi:266*3902
xhdpi:351*5072
xxhdpi:525*7542
xxxhdpi:703*10012
res-560dpi:703*10012 ?
可以通过以下的代码来设置本地语言为中文,查看run graphic test的中文效果。
locale = "zh_CN";//中文
ui->SetLocale(locale);
locale生存在"/cache/recovery/last_locale",以备下次进入recovery选择正确语言。
static void run_graphics_test(Device* device) {
// Switch to graphics screen.
printf("===run_graphics_test===\n");
ui->ShowText(false);//不显示菜单
ui->SetProgressType(RecoveryUI::INDETERMINATE);
ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);//“正在安装体系更新”
sleep(1);
ui->SetBackground(RecoveryUI::ERROR);//“出错了!”
sleep(1);
ui->SetBackground(RecoveryUI::NO_COMMAND);//“无命令”
sleep(1);
ui->SetBackground(RecoveryUI::ERASING);//“正在清空”
sleep(1);
ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);//“正在安装体系更新”
ui->SetProgressType(RecoveryUI: ETERMINATE);
ui->ShowProgress(1.0, 10.0);
float fraction = 0.0;
for (size_t i = 0; i < 100; ++i) {
fraction += .01;
ui->SetProgress(fraction);//进度条
usleep(100000);
}
ui->ShowText(true);//返回菜单
}
定制小手机分辨率是240*432,康健手表项目是320*320,康健手表项目能正常显示进度条,定制小手机不能是由于进度条的图片本身太大了,进度条progress_empty.png和progress_fill.png巨细是252*7,宽度大过了屏幕的最大宽度240,所以MSM8909W手表(240*240)和定制小手机的屏幕都不能显示出进度条,把进度条改成150*7就可以显示出来了。
$ pnginfo progress_empty.png
progress_empty.png...
Image Width: 252 Image Length: 7
Bitdepth (Bits/Sample): 1
Channels (Samples/Pixel): 1
Pixel depth (Pixel Depth): 1
Colour Type (Photometric Interpretation): PALETTED COLOUR (1 colours, 0 transparent)
Image filter: Single row per byte filter
Interlacing: No interlacing
Compression Scheme: Deflate method 8, 32k window
Resolution: 0, 0 (unit unknown)
FillOrder: msb-to-lsb
Byte Order: Network (Big Endian)
Number of text strings: 0 of 0
$ file progress_empty.png
progress_empty.png: PNG image data, 252 x 7, 1-bit colormap, non-interlaced
可以看出进度条图片的格式要求是1-bit PALETTED png;
至于为什么笔墨图片显示不出来是由于坐标不对,并不是图片太大,查看log可以看到图片的笔墨取出来并不会超标:
erasing_text: zh_CN (109 x 38 @ 4875)
no_command_text: zh_CN (83 x 38 @ 4875)
error_text: zh_CN (92 x 38 @ 4875)
installing_text: zh_CN (222 x 38 @ 5766)
最大的“正在安装体系更新”也才222,并不会超出屏幕的宽度。
追一下显示的流程:
画recovery 菜单:draw_screen_locked,
调用者->被调用者
SetBackground/StartMenu/SelectMenu/EndMenu/ShowText/Redraw->
update_screen_locked/update_progress_locked->
draw_screen_locked->
draw_background_locked
终极调用的是draw_background_locked来完成配景图以及笔墨图片的显示;调用gr_texticon函数来显示图片笔墨,末了调用text_blend来显示笔墨。
LoadBitmap用于加载配景图和进度条
LoadBitmap("icon_error", &error_icon);//配景图,出错的机器人
LoadBitmap("progress_empty", &progressBarEmpty);//进度条
LoadBitmap("progress_fill", &progressBarFill);//进度条填充
LoadBitmap("stage_empty", &stageMarkerEmpty);
LoadBitmap("stage_fill", &stageMarkerFill);
LoadBitmap(android::base::StringPrintf("loop%05d", i).c_str(), &loopFrames);//Init的时候会加载动画,但loop00000.png是400*400,太大,不显示
LoadLocalizedBitmap加载笔墨图片
LoadLocalizedBitmap("installing_security_text", &installing_text);//installing_security_text.png “正在安装安全更新”
LoadLocalizedBitmap("installing_text", &installing_text);//installing_text.png “正在安装体系更新”
LoadLocalizedBitmap("erasing_text", &erasing_text);//erasing_text.png “正在清空”
LoadLocalizedBitmap("no_command_text", &no_command_text);// no_command_text.png “无命令”
LoadLocalizedBitmap("error_text", &error_text);//error_text.png “出错了!”
图片格式要求:
if (bit_depth == 8 && *channels == 3 && color_type == PNG_COLOR_TYPE_RGB) {//8bit 3 channels PNG_COLOR_TYPE_RGB
// 8-bit RGB images: great, nothing to do.
} else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_GRAY) {//<=8bit 1 channel PNG_COLOR_TYPE_GRAY
// 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
png_set_expand_gray_1_2_4_to_8(*png_ptr);//扩充为8bit
} else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) {//<=8bit 1 channel PNG_COLOR_TYPE_PALETTE
// paletted images: expand to 8-bit RGB. Note that we DON'T
// currently expand the tRNS chunk (if any) to an alpha
// channel, because minui doesn't support alpha channels in
// general.
png_set_palette_to_rgb(*png_ptr);//PNG_COLOR_TYPE_PALETTE转为PNG_COLOR_TYPE_RGB
*channels = 3;
}
所以在显示图片笔墨的gr_texticon函数打印下坐标信息:
void ScreenRecoveryUI::draw_background_locked() {
pagesIdentical = false;
gr_color(0, 255, 0, 255);//green
gr_clear();
if (currentIcon != NONE) {
if (max_stage != -1) {
int stage_height = gr_get_height(stageMarkerEmpty);
int stage_width = gr_get_width(stageMarkerEmpty);
int x = (gr_fb_width() - max_stage * gr_get_width(stageMarkerEmpty)) / 2;
int y = gr_fb_height() - stage_height;
for (int i = 0; i < max_stage; ++i) {
GRSurface* stage_surface = (i < stage) ? stageMarkerFill : stageMarkerEmpty;
gr_blit(stage_surface, 0, 0, stage_width, stage_height, x, y);
x += stage_width;
}
}
GRSurface* text_surface = GetCurrentText();
int text_x = (gr_fb_width() - gr_get_width(text_surface)) / 2;
int text_y = GetTextBaseline();
gr_color(0, 0, 255, 255);//blue
//text_x = 0;
//text_y = 100;//假如强制设置坐标就能在run graphic test显示出笔墨了
printf("===text_x = %d, text_y = %d===\n", text_x, text_y);//text_y打印出来都是负的
gr_texticon(text_x, text_y, text_surface);
}
}
负的会导致什么后果呢?
void gr_texticon(int x, int y, GRSurface* icon) {
...
if (outside(x, y) || outside(x+icon->width-1, y+icon->height-1))
{
printf("===outside,x=%d,y=%d,icon->width =%d,icon->height = %d,return===\n", x, y, icon->width, icon->height);
return;
}
...
text_blend(src_p, icon->row_bytes,
dst_p, gr_draw->row_bytes,
icon->width, icon->height);
...
}
发现y坐标每次打印出来都是负数,实行outside(x,y)后直接return,都不会实行到text_blend来显示笔墨。这就是为什么图片笔墨显示不出来了,由于text_blend实际上会实行write_rgba_to_565进行格式转换的,所以数据的格式转换也是没有问题,
所以问题出在:int text_y = GetTextBaseline();
int ScreenRecoveryUI::GetAnimationBaseline() {
printf("===GetTextBaseline() = %d===\n", GetTextBaseline());//图片笔墨TEXT的y坐标
printf("===layout_ = %d===\n", layout_);//0
printf("===PixelsFromDp(kLayouts[layout_][ICON]) = %d===\n", PixelsFromDp(kLayouts[layout_][ICON]));//kLayouts[0][2]=68
printf("===gr_get_height(loopFrames[0]) = %d===\n", gr_get_height(loopFrames[0]));//400
return GetTextBaseline() - PixelsFromDp(kLayouts[layout_][ICON]) -
gr_get_height(loopFrames[0]);
}
int ScreenRecoveryUI::GetTextBaseline() {
printf("===GetProgressBaseline() = %d===\n", GetProgressBaseline());//进度条Progress的y坐标
printf("===layout_ = %d===\n", layout_);//0
printf("===PixelsFromDp(kLayouts[layout_][TEXT]) = %d===\n", PixelsFromDp(kLayouts[layout_][TEXT]));//kLayouts[0][1]=32
printf("===gr_get_height(installing_text) = %d===\n", gr_get_height(installing_text));//38
return GetProgressBaseline() - PixelsFromDp(kLayouts[layout_][TEXT]) -
gr_get_height(installing_text);
}
int ScreenRecoveryUI::GetProgressBaseline() {
printf("===gr_fb_height() = %d===\n", gr_fb_height());//240
printf("===layout_ = %d===\n", layout_);//0
printf("===PixelsFromDp(kLayouts[layout_][PROGRESS]) = %d===\n", PixelsFromDp(kLayouts[layout_][PROGRESS]));//kLayouts[0][0]=194
printf("===gr_get_height(progressBarFill) = %d===\n", gr_get_height(progressBarFill));//7
return gr_fb_height() - PixelsFromDp(kLayouts[layout_][PROGRESS]) -
gr_get_height(progressBarFill);
}
int ScreenRecoveryUI: ixelsFromDp(int dp) {
return dp * density_;//
}
体系dpi:[ro.sf.lcd_density]: [160]
所以:
density_ = static_cast<float>(property_get_int32("ro.sf.lcd_density", 160)) / 160.f;
printf("density_ = %f\n", density_);//density_ = 1.0
PixelsFromDp实际返回dp
layout_ = (gr_fb_width() > gr_fb_height()) ? LANDSCAPE : PORTRAIT;
竖屏幕,就是是等高240*240,也不会宽比高大,所以layout_ = PORTRAIT;
PORTRAIT = 0;
enum Dimension { PROGRESS = 0, TEXT = 1, ICON = 2, DIMENSION_MAX };
和这个kLayouts密切干系
static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
{ 194, 32, 68, }, // PORTRAIT
{ 340, 32, 68, }, // PORTRAIT_LARGE
{ 131, 26, 56, }, // LANDSCAPE
{ 262, 52, 112, }, // LANDSCAPE_LARGE
};
kLayouts[layout_][ICON]即kLayouts[0][PROGRESS]、kLayouts[0][TEXT]、kLayouts[0][ICON]
当取kLayouts[0][PROGRESS]位置的时候问题就出现了kLayouts[0][0] = 194,太大了,kLayouts的从上到下布局是如许的:
------------------------------屏幕顶部------------
隔断 巨细可变
ICON 详细多大就多大
隔断 巨细为68
TEXT 详细多大就多大,图片资源是读出来38高
隔断 巨细为32
PROGRESS 详细多大就多个,图片资源是7高
隔断 巨细194
------------------------------屏幕底部------------
所以240-194-7是39,是进度条的y坐标,
但是39-32-38就是负数了,图片笔墨就显示不出来了,所以必要把194改小。
static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
{ 40, 32, 25, }, // PORTRAIT
{ 340, 32, 68, }, // PORTRAIT_LARGE
{ 131, 26, 56, }, // LANDSCAPE
{ 262, 52, 112, }, // LANDSCAPE_LARGE
};
显示正常。
===============================
版本号修改:
whl@whl-Dell:~/work/msm8909w_law_android$ git diff build/core/Makefile
diff --git a/build/core/Makefile b/build/core/Makefile
index 7a4ad71..6615b69 100755
--- a/build/core/Makefile
+++ b/build/core/Makefile
@@ -183,7 +183,7 @@ endif
#Add by MSM8909W手表 version show Build.DISPLAY
ifeq ($(TARGET_PRODUCT),MSM8909W)
- BUILD_DISPLAY_ID := "V1.0.2"
+ BUILD_DISPLAY_ID := "V1.0.3"
PRODUCT_MODEL := "MSM8909W_D9"
BUILD_VERSION_TAGS := "watch"
endif
====================================
规复出厂卡在“正在清空”,串口log:
[ 3.756669] -- Wiping data...
[ 3.756687] ===erase_volume===
[ 3.756705] Formatting /data...
[ 3.756744] Creating filesystem with parameters:
[ 3.756766] Size: 1542418432
[ 3.756785] Block size: 4096
[ 3.756804] Blocks per group: 32768
[ 3.756823] Inodes per group: 7856
[ 3.756841] Inode size: 256
[ 3.756859] Journal blocks: 5883
[ 3.756878] Label:
[ 3.756896] Blocks: 376567
[ 3.756914] Block groups: 12
[ 3.756932] Reserved block group size: 95
[ 3.756951] Created filesystem with 11/94272 inodes and 12384/376567 blocks
[ 5.104390] ===erase_volume===
[ 5.126327] Formatting /cache...
[ 12.577306] EXT4-fs (mmcblk0p23): warning: maximal mount count reached, running e2fsck is recommended
[ 12.578602] EXT4-fs (mmcblk0p23): recovery complete
[ 12.579598] EXT4-fs (mmcblk0p23): mounted filesystem with ordered data mode. Opts: barrier=1,data=ordered
[ 5.281999] Creating filesystem with parameters:
[ 5.282080] Size: 67108864
[ 5.282103] Block size: 4096
[ 5.282123] Blocks per group: 32768
[ 5.282142] Inodes per group: 4096
[ 5.282162] Inode size: 256
[ 5.282180] Journal blocks: 1024
[ 5.282199] Label:
[ 5.282222] Blocks: 16384
[ 5.282241] Block groups: 1
[ 5.282260] Reserved block group size: 7
[ 5.282808] Created filesystem with 11/4096 inodes and 1294/16384 blocks
[ 12.971016] EXT4-fs (mmcblk0p23): mounted filesystem with ordered data mode. Opts: barrier=1,data=ordered
[ 37.459557] random: nonblocking pool is initialized
[ 99.801145] recovery (287) used greatest stack depth: 6064 bytes left
缘故原由还没查,下次开机也卡在这。后来把recovery模式下的串口打印关闭就正常了,能够正常规复出厂,不会卡住。大概是打印串口打印泯灭了太多栈内存了。
====================================
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |