目录
第一部分 QXDM debug
1.1. Download QXDM by Qualcom package manager
1.2. connect device
1.3. filter
第二部分 编译和烧写adsp代码
2.1 编译
2.1.1 编译配置文件:
2.1.2 编译wlan 设备:
2.1.3 编译wwan 设备:
2.2 烧写
2.2.1 烧写wlan
2.2.2 烧写wwan
第三部分 调试ADSP代码
3.1 检查编译
3.2 检查sensor驱动是否prob
3.3 抓取 sensor init log的方法 :
3.4 打印log
第四部分 调试 sensor HAL的代码
4.1 打开sensor HAL的log
4.2 调试sensor HAL 遇到了missing required fields的问题
click connect
配置 message filter
勾选需要读取的log
qcm4290-spf/build.xml
这个配置文件里面有所有需要编译的target。
ant clean adsp sda | tee build.txt
(PS, 不做clean的话,可能编译出来的bin文件还是老的代码。另外要记录编译的log,因为这个ant编译失败也不停止。最好是检查下build.txt是否有编译error)
ant clean adsp update-nonhlos | tee build.txt
adb reboot bootloader
fastboot flash modem SDA.bin
adb reboot bootloader
fastboot flash modem NON-HLOS.bin
检查sensor是否有register进入sns_static_sensor.c
示例代码:
sns_rc sns_wrist_to_wake_register(sns_register_cb const *register_api)
{
register_api->init_sensor(sizeof(sns_wrist_to_wake_sensor_state),
&sns_wrist_to_wake_api,
&sns_wrist_to_wake_sensor_instance_api);
return SNS_RC_SUCCESS;
}
使用ssc_drva_test 来测试sensor驱动是否有被prob成功。ssc_drva_test 的测试工具在qcom vendor下面:vendor/qcom/proprietary/sensors-see/test/ssc_drva_test. 具体的命令使用方法可以参考高通文档:
1. 测试命令:
1. adb root
2. adb shell ssc_drva_test -sensor=wrist_to_wake -duration=10
2. 运行的成功的log:
CT30P:/ # ssc_drva_test -sensor=wrist_to_wake -duration=10
4 ssc_drva_test version 1.13
4 ssc_drva_test -sensor=wrist_to_wake -duration=10
4 handle_event
4 event_cb attribute event for da_test
4 handle_event
4 event_cb attribute event for da_test
4 using da_test name=da_test, suid = [high addeaddeaddeadde, low addeaddeaddeadde
4 enter send_memory_log_req cookie: 4
4 exit send_memory_log_req
4 enter da_test runner
4 handle_event
4 received event: PASS
4 handle_event
4 -time_to_first_event=0
4 -time_to_last_event=-1950101027
4 -sample_ts=190928664161
4 -total_samples=0
4 -avg_delta=0z
4 -recvd_phy_config_sample_rate=0
4 -random_seed_used=1758057498
4 -num_request_sent=2
4 -first_sample_timestamp=0
4 enter send_memory_log_req cookie: 4
4 exit send_memory_log_req
4 PASS
这个log说明senor至少是prop成功了。
1. Find out which subsytem number is adsp
root@apq8084:/sys/bus/msm_subsys/devices # for i in `ls`; do echo $i:; cat ./$i/name; done;
2. Enable SSR (non-persistent; must do every boot - assumes subsys2 is adsp from above)
adb root
adb wait-for-device
adb remount
adb shell "echo related > /sys/bus/msm_subsys/devices/subsys2/restart_level"
adb shell sync
3. From QXDM send the command:
For ADSP Targets: "send_data 75 37 03 48"
4. adsp will restart you can see the init log in the qxdm
1. 使用SNS_PRINTF打印log,高通的hexgon 可能不支持%llu打印,建议打印timestamp用%u代替也是够用的。
2. adsp cdsp的timestamp都是subsystem 晶振的tick number。timestamp和ms的换算是 ms = timestamp/19200
adb root && adb remount
adb shell "echo persist.vendor.sensors.debug.hal=v >> /system/build.prop"
adb shell "echo persist.vendor.sensors.debug.stats=true >> /system/build.prop"
adb shell "echo setprop persist.vendor.sensors.no_audio=true >> /system/build.prop"
adb shell "echo persist.vendor.sensors.debug.ssc_latency=true >> /system/build.prop"
adb reboot
问题log如下:
E libprotobuf-native: [libprotobuf ERROR external/protobuf/src/google/protobuf/message_lite.cc:123] Can't parse message of type "sns_wrist_to_wake_event" because it is missing required fields: (cannot determine missing fields for lite message)
解决办法:
1. 查看Android端的proto 文件和adsp端的proto文件是否都存在,两边的proto 文件内容是否一致
android和adsp 端是否有编译出sns_xxxx.pb.h, snc_xxxx.ph.c
Android端的生成文件在out/soong/.intermediates/vendor/qcom/proprietary/sensors-see/ssc/libsnsapi-full-static/android_vendor.30_arm64_armv8-a_static_cfi/gen/proto
adsp端的生成文件在ADSP.VT.5.4.1/adsp_proc/ssc_api/build/sensor_img/qdsp6/kamorta.adsp.prod/pb
2. 查看proto中的message 定义的结构类型,是否和sensor驱动的发送的类型,数据结构是否一致。
我这边遇到这个missing required fields的问题原因就是数据类型不一致。
adsp端定义的payload是float型,并且使用发生float类型的payload方法pb_send_sensor_stream_event。
float wrist_to_wake_payload;
rc = pb_send_sensor_stream_event(this,
NULL,
resampler_event_in->timestamp,
SNS_WRIST_TO_WAKE_MSGID_SNS_WRIST_TO_WAKE_EVENT,
SNS_STD_SENSOR_SAMPLE_STATUS_ACCURACY_HIGH,
&wrist_to_wake_payload,
1,
inst_state->config.encoded_data_event_len);
proto 文件里面定义的却是enum,float和enum类型之间不一致,所以会导致Android端的libprotobuf 解析不了。比较奇怪的事,为什么在adsp端可以正常的encode,因为Android可以收到event信息。
enum sns_wrist_to_wake_event_state
{
option (nanopb_enumopt).long_names = false;
SNS_WRIST_TO_WAKE_EVENT_STATE_UNKNOWN = 0;
//Phone has just moved to a wrist to up phone gesture
//which is defined as screen on.
SNS_WRIST_TO_WAKE_EVENT_STATE_WAKE = 1;
//Phone has just moved to a wrist to down phone gesture,
//which is defined as screen off.
SNS_WRIST_TO_WAKE_EVENT_STATE_SLEEP = 2;
}
// Event Message
// Output data event generated by the wrist_to_wake sensor.
message sns_wrist_to_wake_event
{
// wrist_to_wake sensor state info
required sns_wrist_to_wake_event_state state = 1[default = SNS_WRIST_TO_WAKE_EVENT_STATE_UNKNOWN];
}
我在这里没有修改proto文件,而是修改adsp端的发送方法,使用pb_send_event,这个方法的payload类型不限制,解决了这个问题。
sns_wrist_to_wake_event wrist_to_wake_event;
wrist_to_wake_event.state = SNS_WRIST_TO_WAKE_EVENT_STATE_WAKE;
bool rv = pb_send_event(this,
sns_wrist_to_wake_event_fields,
&wrist_to_wake_event,
resampler_event_in->timestamp,
SNS_WRIST_TO_WAKE_MSGID_SNS_WRIST_TO_WAKE_EVENT,
inst_state->suid);
3. 可能是Android端和adsp端的编译器不匹配,导致的编译数据不一致,从而导致Android端的proto无法解析。需要想办法规避这个问题,寻找能过匹配的数据类型。
具体参考Google protobu官网,
https://developers.google.com/protocol-buffers/docs/techniques#union
https://groups.google.com/g/protobuf/c/kpZia0Rzsp8