目录
代码逻辑分析
如何切换默认按键个数
如何实现三击操作
打开ButtonParseXML.py文件,定位到如下位置
上面两个接口就是先从x_buttons.buttonxml中读取配置,并把这些配置生成一对应的.c与.h文件,这里拿1_button举例分析。
首先我们打开1_buttons.buttonxml与生成的1_button.c
如上图,在1_buttons.buttonxml文件中包含了两个消息组"media_message_group"和"voice_assistant_message_group",对应的在.c文件中也有两个静态数组。
每个消息组下面有很多的消息实体,.c文件中消息实体都是根据xml文件中的内容转化而来,相关的结构体在input_event_manager.h与input_event_manager_private.h中定义。
我们来分析第一个消息,
if(bits == (input & mask)//input是实际的io状态
所以我们可以看出,如果不加mask,该消息成立的条件是1按下,所以当我1,2同时按下时,也是满足1按下的条件的,但是实际需求是当单独按1时才执行我的逻辑,所以为了使当1,2同时按下时不响应,引入了mask过滤1,2同时按下这种情况。可以参考音量加减按键使用的情况进行理解。
现在我们回过头来看ButtonParseXML文件,在generate_source函数中OutputButtonTable的接口,该接口的主要作用就是将massage标签转化为一个InputActionMessage_t实体。
从上面可以看出,生成c文件中的消息结构体,首先会匹配action,如果找不到就跳过,由于默认只有6种动作,所以我们要加新动作的话,比如“TRIPLE_CLICK”需要在这里新增一个类型,否则无法parse出来,并在input_event_manager.h的InputEventAction_t枚举定义中添加定义。
//硬件初始化,注册处理函数
PioMonitorInit(pioHandler)
//input_event_manager模块初始化,注册消息处理函数
InputEventManagerInit(iemHandler)
//关联结构体数组,按键消息最终会根据消息id去map的处理函数
earbud_ui_config_table
//当io口状态发生改变的时候,发MESSAGE_PIO_CHANGED到monitor层
pioHandler
//封装io消息,并转发给与之关联的各个app task,这里只关注input_event_manager模块(app)
handleMessagePioChangedClients(state,mpc)
iemHandler
MESSAGE_PIO_CHANGED
handleMessagePioChangedEvents
//遍历x_button.c中消息表内的消息,匹配io与动作,执行对应的操作
inputEventsChanged
ENTER
//io是否为高电平,是则发出ENTER按键事件
enterAction(state, input_action, input_event_bits);
RELEASE
//io是否为低电平,且之前为高电平,是则发出RELEASE按键事件
releaseAction(state, input_action, input_event_bits);
SINGLE_CLICK
//如果之前为高,现在为低,则满足单击的条件;
singleClickAction(state, input_action, input_event_bits);
//如果是长按抬起,则清除单击的长短按标志位,否则执行下面操作
//如果是首次抬起,等待500ms,发送IEM_INTERNAL_SINGLE_CLICK_TIMER,以确保不是双击的第一次按下
singleClickFirstReleaseAction
//如果是第二次抬起动作,考虑是多击事情,取消所有关于单击的消息
singleClickSecondReleaseAction
DOUBLE_CLICK
//如果之前为高,现在为低,则有可能是双击事件的条件;
doubleClickAction(state, input_action, input_event_bits);
//如果是长按抬起,则清除单击与双击的标志位,否则执行下面操作
//如果是首次抬起,等待500ms,发送IEM_INTERNAL_DOUBLE_CLICK_TIMER,去清除短按标志位,这个时候如果第二击还没有到来,则双击无法触发了
doubleClickSecondReleaseAction
//如果是第二次抬起动作,且第一次点击存在,发送双击消息给到app处理,取消所有关于单击的消息
doubleClickFirstReleaseAction
HELD
heldAction(state, input_action, input_event_bits);
//io是否为高电平,延时指定时间之后发送IEM_INTERNAL_HELD_TIMER消息
//同时当执行IEM_INTERNAL_HELD_TIMER消息时,也会将单击与双击的长按标志位置位,防止进入单双击的逻辑
heldActionButtonDownAction
//io是否为高电平,且之前为低电平,取消IEM_INTERNAL_HELD_TIMER与IEM_INTERNAL_REPEAT_TIMER消息
heldActionButtonReleaseAction
HELD_RELEASE
heldReleaseAction(state, input_action, input_event_bits)
//io是否为高电平,是延时指定时间之后发送IEM_INTERNAL_HELD_RELEASE_TIMER消息,消息处理将按键抬起原因held_release设置指定为目标值,比如我是希望3s抬起,那将3s抬起对应的action赋值给held_release,那么假如是4s抬起,就不满足held_release,所以就不会触发3s抬起将要执行的事件逻辑。
//同时当执行IEM_INTERNAL_HELD_RELEASE_TIMER消息时,也会将单击与双击的长按标志位置位,防止进入单双击的逻辑
heldReleaseButtonDownAction
//io是否为低电平,且之前为高电平,且当前的action=held_release,去执行3s抬起对应的处理逻辑
heldReleaseButtonReleaseAction
等初始化完
PIO_MONITOR_ENABLE_CFM
waitForEnableConfirmation
上面只对接口做了简单分析,接口实现请参考实际的代码逻辑
Qcc304x adk默认是使用9个button的,并提供了1,2,4,6,7,9共6种按键模型,如果我们要切换模型,按以下步骤(现以切换1button为例):
选择工程属性,在宏定义一栏,修改按键宏,注意当个数大于1时,BUTTON后要加‘S’(HAVE_x_BUTTONS)
回到编辑,检查上述位置是否为你想要的按键个数对应的xml,不是就重新从ADK中加入,修改好之后,rebuild earbud即可。
请查看附件中的参考代码,例程的可扩展性不是特别好,仅供参考!重要的还是看懂逻辑,懂了之后就可以随便改!
相关的工具资料等,请到我的博客