当前位置: 技术问答>linux和unix
请问一个关于Linux的Input子系统的丢失发送数据的问题
来源: 互联网 发布时间:2017-03-21
本文导语: 这几天被老板弄来搞Android下的I2C设备驱动,读取的坐标数据需要用Input子系统上报应用。但是代码写好以后测试中发现上报的三个坐标值经常会丢失1-2个,有时连input_sync都没发。我的代码: 相关代码: ...
这几天被老板弄来搞Android下的I2C设备驱动,读取的坐标数据需要用Input子系统上报应用。但是代码写好以后测试中发现上报的三个坐标值经常会丢失1-2个,有时连input_sync都没发。我的代码:
相关代码:
input子系统注册:
bma->input_dev = input_allocate_device();
if (!bma->input_dev)
{
err = -ENOMEM;
printk(KERN_DEBUG "Input Request Error.n");
goto probe_err_reg;
}
printk(KERN_DEBUG "Input Request Successful.n");
bma->input_dev->open = input_open;
bma->input_dev->close = input_release;
bma->input_dev->name = SXA_I2C_NAME;
bma->input_dev->phys = "sxa/input0";
bma->input_dev->id.bustype = BUS_I2C;
bma->input_dev->id.vendor = SXA_VENDOR;
bma->input_dev->id.product = 1;
bma->input_dev->id.version = 1;
__set_bit(EV_ABS, bma->input_dev->evbit);
__set_bit(ABS_X, bma->input_dev->absbit);
__set_bit(ABS_Y, bma->input_dev->absbit);
__set_bit(ABS_Z, bma->input_dev->absbit);
__set_bit(ABS_MISC, bma->input_dev->absbit);
err = input_register_device(bma->input_dev);
工作队列内发送坐标数据:
input_report_abs(dd->input_dev, ABS_X, x);
input_report_abs(dd->input_dev, ABS_Y, y);
input_report_abs(dd->input_dev, ABS_Z, z);
input_sync(dd->input_dev);
在工作队列内发送数据时,上层报告数据丢失。采用evbug.ko调试发现数据确定丢失,以下是报告:
[ 3224.267441] Enter irq.
[ 3224.267484] dd has get.
[ 3224.267529] work scheduled.
[ 3224.267589] work_q Entered.
[ 3224.268473] X Regs: -3.
[ 3224.268504] Y Regs: 31.
[ 3224.268519] Z Regs: 2.
[ 3224.268534] TILT Regs: 96.
[ 3224.268551] *******************************
[ 3224.268669] evbug.c: Event. Dev: input3, Type: 3, Code: 0, Value: -3
[ 3224.270979] evbug.c: Event. Dev: input3, Type: 3, Code: 2, Value: 2
[ 3224.272001] evbug.c: Event. Dev: input3, Type: 0, Code: 0, Value: 0
应该有3个数据,-3、31、2,结果31丢失
另外,发现同事正常应用的触摸屏上报的坐标数据也是有丢失的,不过似乎没影响正常使用……迷惑中……
还望高手们能指点迷津,谢谢!
相关代码:
input子系统注册:
bma->input_dev = input_allocate_device();
if (!bma->input_dev)
{
err = -ENOMEM;
printk(KERN_DEBUG "Input Request Error.n");
goto probe_err_reg;
}
printk(KERN_DEBUG "Input Request Successful.n");
bma->input_dev->open = input_open;
bma->input_dev->close = input_release;
bma->input_dev->name = SXA_I2C_NAME;
bma->input_dev->phys = "sxa/input0";
bma->input_dev->id.bustype = BUS_I2C;
bma->input_dev->id.vendor = SXA_VENDOR;
bma->input_dev->id.product = 1;
bma->input_dev->id.version = 1;
__set_bit(EV_ABS, bma->input_dev->evbit);
__set_bit(ABS_X, bma->input_dev->absbit);
__set_bit(ABS_Y, bma->input_dev->absbit);
__set_bit(ABS_Z, bma->input_dev->absbit);
__set_bit(ABS_MISC, bma->input_dev->absbit);
err = input_register_device(bma->input_dev);
工作队列内发送坐标数据:
input_report_abs(dd->input_dev, ABS_X, x);
input_report_abs(dd->input_dev, ABS_Y, y);
input_report_abs(dd->input_dev, ABS_Z, z);
input_sync(dd->input_dev);
在工作队列内发送数据时,上层报告数据丢失。采用evbug.ko调试发现数据确定丢失,以下是报告:
[ 3224.267441] Enter irq.
[ 3224.267484] dd has get.
[ 3224.267529] work scheduled.
[ 3224.267589] work_q Entered.
[ 3224.268473] X Regs: -3.
[ 3224.268504] Y Regs: 31.
[ 3224.268519] Z Regs: 2.
[ 3224.268534] TILT Regs: 96.
[ 3224.268551] *******************************
[ 3224.268669] evbug.c: Event. Dev: input3, Type: 3, Code: 0, Value: -3
[ 3224.270979] evbug.c: Event. Dev: input3, Type: 3, Code: 2, Value: 2
[ 3224.272001] evbug.c: Event. Dev: input3, Type: 0, Code: 0, Value: 0
应该有3个数据,-3、31、2,结果31丢失
另外,发现同事正常应用的触摸屏上报的坐标数据也是有丢失的,不过似乎没影响正常使用……迷惑中……
还望高手们能指点迷津,谢谢!
|
采用EV_ABS方式传送,input机制会过滤掉相同的值,所以会出现丢值的现象。如果采用EV_REL方式就可以解决这个问题了。
|
你每秒上报的次数降下来。默认好像是80,改成40
应该是上报速度太快,中间件处理不过来,所以丢失
应该是上报速度太快,中间件处理不过来,所以丢失
|
楼上正解,相同的值就不会往上传了,可以看一下linux的input设备的实现代码
|
我记得采用EV_ABS类型进行传送,好像有个范围值,你要查查范围值,使用EV_ABS类型进行report的时候细节必须要谨慎,不然会出现很难查的BUG。如果用EV_REL还会出现丢失的情况,这个时候你就要跟踪下,你__set_bit和调用report进行数据传送的时候是否类型一致。一般正确使用EV_REL方式,不会出现丢数据的情况的。