• 高通非adsp 架构下的sensor的bug调试


    问题现象:

    当休眠后,再次打开preesure sensor的时候,会出现隔一段时候后,APK才会出现数据;(数据有时候会很难出现)

    问题分析:

    从上面几节中,我们可以知道,framework到HAL是通过调用sensors.msm8909.so调用到函数PressureSensor::readEvents中取出的;

    int PressureSensor::readEvents(sensors_event_t* data, int count)
    {
    	int i = 0;
    	if (count < 1)
    		return -EINVAL;
    
    	if (mHasPendingEvent) {
    		mHasPendingEvent = false;
    		mPendingEvent.timestamp = getTimestamp();
    		*data = mPendingEvent;
    		return mEnabled ? 1 : 0;
    	}
    
    	if (mHasPendingMetadata) {	
    		mHasPendingMetadata--;
    		meta_data.timestamp = getTimestamp();
    		*data = meta_data;
    		return mEnabled ? 1 : 0;
    	}
    
    	ssize_t n = mInputReader.fill(data_fd);
    	if (n < 0)
    		return n;
    
    	int numEventReceived = 0;
    	input_event const* event;
    
    #if FETCH_FULL_EVENT_BEFORE_RETURN
    again:
    #endif
    	while (count && mInputReader.readEvent(&event)) {
    		int type = event->type;
    		if (type == EV_ABS) {
    			float value = event->value;
    			mPendingEvent.pressure = value * CONVERT_PRESSURE;
    			ALOGI("the pressure is %f
    ", mPendingEvent.pressure);
    		} else if (type == EV_SYN) {
    			switch (event->code) {
    				case SYN_TIME_SEC:
    					mUseAbsTimeStamp = true;
    					report_time = event->value*1000000000LL;
    					break;
    				case SYN_TIME_NSEC:
    					mUseAbsTimeStamp = true;
    					mPendingEvent.timestamp = report_time+event->value;
    					break;
    				case SYN_REPORT:
    					if(mUseAbsTimeStamp != true) {
    						mPendingEvent.timestamp = timevalToNano(event->time);
    					}
    					if (mEnabled) {
    //						ALOGI("timestamp = %ld mEnabledTime = %ld mUseAbsTimeStamp = %d enable here
    ", mPendingEvent.timestamp, mEnabledTime, mUseAbsTimeStamp);
    //						if (mPendingEvent.timestamp >= mEnabledTime)
    						{
    							*data = mPendingEvent;
    							ALOGI("data pressure is %f
    ", data->pressure);
    //							data++;
    							numEventReceived++;
    						}
    						count--;
    					}
    					break;
    			}
    		} else {
    			ALOGE("PressureSensor: unknown event (type=%d, code=%d)",
    					type, event->code);
    		}
    		
    		mInputReader.next();
    	}
    
    #if FETCH_FULL_EVENT_BEFORE_RETURN
    	/* if we didn't read a complete event, see if we can fill and
    	   try again instead of returning with nothing and redoing poll. */
    	if (numEventReceived == 0 && mEnabled == 1) {
    		n = mInputReader.fill(data_fd);
    		if (n)
    			goto again;
    	}
    #endif
    	ALOGI("end the data the pressure is %f
    ", mPendingEvent.pressure);
    
    	return numEventReceived;
    }
    

    增加if (mPendingEvent.timestamp >= mEnabledTime)判断是为了判断SYN_REPORT不延迟的情况;

    mPendingEvent.timestamp在这里被赋值:

    input_event const* event;
    
    //这个可以一直进来
    if(mUseAbsTimeStamp != true) {
    	mPendingEvent.timestamp = timevalToNano(event->time);
    }
    

    event->time代表了按键时间;可以用struct timeval获取系统时间。
    其中input_eventtimeval结构体如下:

    struct input_event {
    
    struct timeval time; //按键时间
    
    __u16 type; //类型,在下面有定义
    
    __u16 code; //要模拟成什么按键
    
    __s32 value;//是按下还是释放
    
    };
    
    struct timeval {
       __kernel_time_t		tv_sec;		/* seconds */
    	__kernel_suseconds_t	tv_usec;	/* microseconds */
    };
    
    //将时间转换为ns
    static int64_t timevalToNano(timeval const& t) {
    		return t.tv_sec*1000000000LL + t.tv_usec*1000;
    }
    

    通过打印可以知道问题出现的时候mPendingEvent.timestamp是小于mEnabledTime的,进不了判断,所以上层也就无法获取相应的数据;

    mEnabledTime是在int PressureSensor::enable(int32_t, int en)函数中实现:

    ....
    	mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;
    ....
    
    int64_t SensorBase::getTimestamp() {
        struct timespec t;
        t.tv_sec = t.tv_nsec = 0;
        clock_gettime(CLOCK_BOOTTIME, &t);
        return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec;
    }
    //不过CLOCK_BOOTTIME计算系统suspend的时间,也就是说,不论是running还是suspend(这些都算是启动时间),CLOCK_BOOTTIME都会累积计时,直到系统reset或者shutdown。
    

    所以在睡眠起来后mEnabledTime会大于mPendingEvent.timestamp,所以此时是没有上报数据的;将判断去掉即可;

    patch地址

    patch

  • 相关阅读:
    [SHOI2015]零件组装机
    [AH2017/HNOI2017]影魔
    空指针RE第一次公开赛-笔记
    i春秋2020新春公益赛WP
    博客园Markdown编辑器修改代码配色、添加代码行号
    buuctf Writeup
    关于Tarjan的一些问题
    NOIP2013D1T3货车运输 (生成树+树链剖分)
    1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)
    CodeForces 438D The Child and Sequence (线段树 暴力)
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/9483255.html
Copyright © 2020-2023  润新知