MTK虚拟sensor梳理
一 虚拟sensor注册
以倾斜检查虚拟sensor为例,梳理虚拟sensor的控制流和数据流
倾斜虚拟sensor驱动在SCP virt_driver里tilt_detector.c,MTK SCP侧的虚拟sensor都是存放在这个目录下。
wakeup------抬起唤醒
liftDetector----拾起察觉
liftPdDetector—拾起察觉(带防误触检查)
stepRecognition —虚拟计步器
tiltDetectorStart()
{
mTask.taskID = taskId:
mtask.handle = sensorRegister(&mSi, &mSops,NULL,true);//注册操作接口
osEventSubscribe(taskId,EVT_APP_START);//加入实际并执行,在tiltDetectorHandleEvent中该事件仅打印了log “TILT EVT_APP_START”后就删除了该事件的监听
}
二 虚拟sensor控制流程
HAL层:tilt是归属于Situation.cpp管理,该类还管理pickup_gesture motion_detect wake_gesture等虚拟sensor,但计步器有自己独立的HAL驱动stepCounter.cpp
使能:
Int SituatiionSensor::enale(int32_t handlle, int en) //抬腕sensor handle = 21
{
Open() //打开kernel的驱动节点situactive
Write() //写1
}
对节点situactive执行write操作就是执行对应的store函数
static ssize_t situation_store_active()
{
Index = handle_to_index(handle);//通过handle找到要操作的sensor
Situation_enable_and_batch(index); //使能该函数主要调用 cxt->ctl_context[index].situation_ctl.open_report_data(1)
}
cxt->ctl_context[index].situation_ctl具体的实例化是在situation_register_control_patch()中,这对应这具体驱动的注册,不难发展在tiltdetecthub.c驱动的tiltdetecthub_local_init()初始化时会提供接口:
ctl.open_report_data = tilt_detect_open_report_data:
static int tilt_detect_open_report_data(int open)
{
Sensor_enable_to_hub(ID_TILT_DETECTOR,open);//去SCP侧开启sensor
}
AP到SCP大致流程:sensor_enable_to_hub()函数会打包一个cmd(sensor type、rate、enable信息)通过中断的形式发给SCP,SCP接收处理将在hostIntfHandleEvent()进行
hostIntfHandleEvent()
{
①将mtkType转换未SCP侧的chreType
Cmd->sensType = mtkTypeToChreType(cmd->sensType)
②通过 chreType寻找sensorHandle
sensorFind()
③开启sensor
SensorRequest() //会掉用该驱动sensorPower函数
}
IC驱动Power on:
TiltDetectorPower( bool on ,void * cookie)
{
If(on){
configAccel(true,NORMAL_ACC_WINDOW)
{
sensorFind(SENS_TYPE_ACCEL,I,&mTask.acclHandle) //寻找ACC sensor
sensorRequest(mTask.taskId,mTask.accelHandle,ACCEL_MIN_RATE,ACCEL_LATENCY) //开启ACC
osEventSubscribe(mTask.taskId,EVT_SENSOR_ACCEL) //该驱动监听ACCEL事件
}
configAnyMotion(true)
configNomotion(true)
}
}
三sensor的监听流程
在tiltDetectionHandleEvent(){
//监听了4个事件
Case EVT_APP_START: //仅驱动加载时打印log
//下面2个事件通过虚拟sensor motin_adaptor.c判断手机状态,修改ACC的采样频率
Case EVT_SENSOR_ANY_MOTTION:
Case EVT SENSOR_NO_MOTION:
//这个才是真真办事情的,当检查ACC有数据变化,分析数据,上报状态
Case EVT_SENSOR_ACC:
{
TiltDetectorAlgo->
run_tilt_algorithm->
osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_TLT),sample.vpte,NULL)
}
}
四 数据上报
驱动掉用osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_TLT),sample.vpte,NULL)
依旧是hostIntfHandleEvent()进行处理
hostIntfHandleEvent()
{
copyTripleSample(sensor,evtData)//数据保存
simpleQueueEnqueue()-SensorQueueEnqueue()->hostIntfTransferData()->contextHubFormateData()->contextHubTransferOnChangeSensor()->contextHubSramFIfoWrite()//将数据写入FIFO
}
在驱动tiltdetecthub.c中会读取这个FIFO
Tilt_detect_recv_data()
{
Situation_data_report()//数据上报到HAL层
}
结论:
虚拟sensor同样适用android的架构控制 HAL—KERNEL—SCP。如倾斜检查sensor:
HAL层的situation.cpp文件。
kernel的situation.c和tiltdetecthub.c。
SCP的/VIR_driver/tilt_detector.c。
控制流和数据流依旧和常规sensor一致。值得注意的是在contexthub中会对sensor type 进行相应的转换,从而AP和SCP的sensor type值不一定相等。如倾斜在AP sensor type = 22
而在SCP却是25,转换函数chreTypeToMtkType() 、MtkTypeToChreType() 。
部分手机开启抬起唤醒功能,其实会打开 SENSOR_TYPE_WAKE_GESTURE .对应SCP的就是wakeup.c驱动,而wakeup的功能是依赖与liftDetect.c驱动的.所以可以开启的wakeup、liftDetect 2个虚拟sensor。
部分手机开启抬起唤醒功能,其实会打开 SENSOR_TYPE_TILT_DETECTOR .对应SCP的就是liftpbDetect.c驱动或tilt_detect.c驱动.
liftpbDetect.c和tilt_detect.c驱动注册的类型都是 SENS_TYPE_TILT 他们的区别在于liftpbDetect.c不光监听ACC还会监听PROX.使用liftpbDetect的时候,靠近状态倾斜手机是不会上报数据的.
对于一项功能,可能会有几种sensor都可以实现.具体使用的那种需要注意上层调用的handle.再对具体的sensor具体分析.