android-蓝牙A2dp-avrcp-hfp-opp-配对流程-ble-rfcomm源码流程
Android 蓝牙低功耗ble 广播、扫描、连接、数据读写源码流程分析大全 - 点击下载
一、背景描述
某键盘,Fn组合键,小概率无响应,普通Keyboard功能正常。
二、分析
HID写数据给Input子节点流程:键盘手柄->按键发送Keycode(HCI)->协议栈(bta_hh_le_input_rpt_notify()函数)->HID驱动()->Input子节点(getEvnet)<-安卓上层(游戏,输入法)监听实现
由于Kernel基本不会出问题,搭配的其他平台的键盘产品,也没有该问题,猜测是键盘问题,但不能确凿。于是开始各种加维测日志,追流程。(kernel/msm-4.19/drivers/hid)hid-core.c , hid-input.c ; uhid.c ;加维测log,定位到 hid_field *hid_register_field中的 report->maxfield = 0 时,会出现异常。
在此函数中,有一个内存申请函数kzalloc。
当出现异常时,我们打印出来usages的值,为8192, 对比其他键盘基本在20以下。由此确定是键盘的 report map 的值,传的太大,申请内存失败引起的。
三、结论
键值上报的 report map 中针对Fn组合键的maxmum值过大,导致连接时,需要申请较大的连续内存(256K级别),针对256K级别内存,系统无法保证每次都能申请成功,这就解释了为什么是小概率的出现。从而导致report->maxfield无法++,为0。键盘上报的键值,kernel在hid_report_raw_event 中,就不会执行hid_input_field,不会将键值写到input子节点中。Event拿不到键值,按键无响应。
对比其他键盘,上报的map中针对Fn组合键设置的maxmum较小,连接时,申请的内存较少,系统基本可以保证每次都能申请成功。
kernl流程:
uhid.c --------> uhid_dev_input()
|
hid-core.c------> hid_input_report()(This is data entry for lower layers.)
|
hid_report_raw_event() (当内存申请失败,report->maxfiled = 0 ,if条件不满足,hid_input_field()不能执行)
|
hid_input_field()
|
hid_process_event()
|
hidinput_hid_event()
|
input_event()
至此,UHID就将数据,发送到了input子系统。梳理下一个键值的发送,到安卓上层实现功能的流程:键盘:RF(发射后)主机端接收。主机:RF接收—>协议Controller—>HID驱动—>Input节点<—HwPhoneWindowManager(接收Keycode) <—根据不同的键值,实现不同的功能(游戏,输入法)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)