高通平台的adsp子系统的打印需要通过QXDM来抓取,但开机初始化的那一段往往是抓取不到的,因为QXDM要开机一段时间后才能连接,但那时候sensor初始化已经过了,所以前期sensor初始化注册不成功定位起来比较麻烦。
(1)现有两种办法可以打印出初始化的打印,第一种是在初始化函数里面加延时,步骤如下:在ADSP.VT.5.3/adsp_proc/ssc/utils/osa/hexagon_user_pd_slpi/sns_user_pd_init.c
的sns_user_pd_init
函数里面添加延时,但需要注意的时,这个延时时间不能太长,太长会导致sensor都不注册不了,也不能过短,否则也会没初始化的打印。
const sns_time one_second_in_ticks = 19200000ULL;
for(int i = 30; i > 0; i--) // increase to 30s or more delay if can not get the init log
{
MSG_1(MSG_SSID_SNS, DBG_MED_PRIO, "init countdown %d ", i);
/* sns_busy_wait is implemented as a sleep() */
sns_busy_wait(one_second_in_ticks);
}
(2)第二种办法就是将打印都写入到一个文件里面,开机后直接读那个文件的内容。adsp打印会调用到sns_printf.h
文件中的SNS_PRINTF
或者SNS_INST_PRINTF
,可以修改该宏,从而使adsp的打印都写入文件中,如下所示,需要注意的是存储log的地方是否有权限。
#define ADSP_PRINTF_TO_LOG 1
#if ADSP_PRINTF_TO_LOG
#include
#define ADSP_LOG_PATH "/mnt/vendor/persist/sensors/registry/registry/adsp_log"
#define SELECT_NARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, N, ...) N
#define NARGS(...) SELECT_NARG(_0, ##__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define SNS_PRINTF(prio, sensor, fmt, ...) adsp_write_to_log(ADSP_LOG_PATH, NARGS(__VA_ARGS__), fmt, ##__VA_ARGS__)
#define SNS_INST_PRINTF(prio, inst, fmt, ...) adsp_write_to_log(ADSP_LOG_PATH, NARGS(__VA_ARGS__), fmt, ##__VA_ARGS__)
int adsp_write_to_log(char *path,unsigned int num, char *fmt, ...);
#else
#include "sns_printf.h"
#endif
int adsp_write_to_log(char *path,unsigned int num, char *fmt, ...)
{
FILE *fp;
va_list args;
char str[1024] = {0};
if (fmt == NULL)
return -1;
if (num > 0){
va_start(args,fmt);
vsprintf(str,fmt,args);
va_end(args);
}
fp = fopen(path , "at+");
if(fp == NULL) {
return -1;
}
if (num > 0){
fputs(str,fp);
fputs("\n",fp);
} else {
fputs(fmt,fp);
fputs("\n",fp);
}
fclose(fp);
return 0;
}
需要注意的是,adsp里面是不允许这样直接操作文件的,这里只是用来方便前期调试使用,后期需要将其去掉,不然会造成adsp各种crash。
mtk平台的sensor驱动代码在内核代码路径下kernel-4.4/drivers/misc/mediatek
,所以mtk的调试比高通的要简单很多,因为串口log里面查看内核打印就可以看到打印信息。一般情况下,sensor驱动还会提供几个接口供调试使用,例如:
/sys/bus/platform/drivers/als_ps $ ls
als_data bind disable_irq_flag lux ps_data reg transmittance unbind
als_rawdata cali_Light enable lux_threshold ps_rawdata status uevent
可以通过这些节点进行一下操作,例如读取寄存器的值、disable/enable sensor等等,这些接口都在sensor驱动里面定义好,也可以个性化定制,根据自己的需要定制。需要注意的是user版本下直接通过adb shell是打不开这些节点的,因为没有root权限,但可以通过应用打开,只要调用的应用有足够的权限。在android6.0以后的版本,google采用了SELinux的文件访问安全策略,相较以前,绝对提高了文件的安全,App需要获取SELinux自定义节点的访问权限。
MTK 配置目录 device/mediatek/sepolicy/
,注意的是里面一般有basic,bsp,full目录,其中basic目录所有的版本都会用到。
device/mediatek/mt6785/BoardConfig.mk
#SELinux Policy File Configuration
ifeq ($(strip $(MTK_BASIC_PACKAGE)), yes)
BOARD_SEPOLICY_DIRS += \
device/mediatek/mt6785/sepolicy/basic
endif
ifeq ($(strip $(MTK_BSP_PACKAGE)), yes)
BOARD_SEPOLICY_DIRS += \
device/mediatek/mt6785/sepolicy/basic \
device/mediatek/mt6785/sepolicy/bsp
endif
ifneq ($(strip $(MTK_BASIC_PACKAGE)), yes)
ifneq ($(strip $(MTK_BSP_PACKAGE)), yes)
BOARD_SEPOLICY_DIRS += \
device/mediatek/mt6785/sepolicy/basic \
device/mediatek/mt6785/sepolicy/bsp \
device/mediatek/mt6785/sepolicy/full
endif
endif
举个例子,MTK_BSP_PACKAGE为yes,那么系统将编译basic,bsp这2个目录,该定义在device/mediateksample/xxx/ProjectConfig.mk
文件里面,所以修改basic和bsp任意一个目录都可以,最终这2个目录下都会整合成一个te文件。
平时工作中,我们会自定义节点去做一些功能,例如:
创建节点: /sys/bus/platform/drivers/als_ps/disable_irq_flag
当你添加完需求之后,可能会遇到SELinux的错误
avc: denied { write } for name="disable_irq_flag" dev="sysfs" ino=9205
scontext=u:r:system_app:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
分析过程:
缺少什么权限: { write }权限,
谁缺少权限: scontext=u:r:system_app:s0
对哪个文件缺少权限:tcontext=u:object_r:sysfs:s0
什么类型的文件: tclass=file
解决方法:谁缺少权限,我们就改动{谁.te},这里改动system_app.te
(1)在device/mediatek/sepolicy/basic/non_plat/file.te
定义disable_irq_flag
SELinux type
type als_ps, fs_type,sysfs_type;//这里als_ps名字可以随意取,原则是方便理解
(2)在device/mediatek/sepolicy/basic/non_plat/file_contexts
绑定 disable_irq_flag
对应的label(如果节点在proc目录下,则文件在sepolicy/basic/non_plat/genfs_contexts
里面进行绑定)
/sys/bus/platform/drivers/als_ps/disable_irq_flag u:object_r:als_ps:s0
(3)在device/mediatek/sepolicy/basic/non_plat/system_app.te
中申请权限
allow system_app als_ps:file rw_file_perms;
这里的rw_file_perms是一个包含所有的读写权限
define(r_file_perms',{ getattr open read ioctl lock }')
define(w_file_perms',{ open append write }')
define(rw_file_perms',{ r_file_perms w_file_perms }')
(4)为其它的process申请相关的权限(如果需要)
device/mediatek/sepolicy/basic/non_plat/system_server.te
allow system_server als_ps:file rw_file_perms;
(5)在device/mediatek/mt6785/init.mt6785.rc
chmod 0666 /sys/bus/platform/drivers/als_ps/disable_irq_flag
chown system system /sys/bus/platform/drivers/als_ps/disable_irq_flag