上一篇 讲到检测线程得到单击、双击等事件。这篇接着看:事件怎样进入应用,最后找到对应业务。
本项目的 MCU 处理路径如下:
%%{init: {"flowchart": {"htmlLabels": true, "wrappingWidth": 1000, "rankSpacing": 30}, "themeVariables": {"lineColor": "#71829a"}}}%%
flowchart TB
subgraph R0["① 检测线程:调用接收函数"]
direction LR
R0N0["得到检测事件<br/>status.event"]
R0N1["转换为应用按键事件<br/>app_capsensor_click_event()"]
R0N2["放入应用邮箱<br/>capsensor_key_event_process()"]
R0N0 --> R0N1 --> R0N2
end
class R0N0,R0N1,R0N2 blue;
style R0 fill:#f1f6fd,stroke:#b8cfe8,color:#23456b
subgraph R1["② 应用线程:取消息并分发"]
direction LR
R1N0["还原按键消息<br/>app_key_handle_process()"]
R1N1["进入产品处理<br/>app_ibrt_user_key()"]
R1N2["按产品状态、左右耳和事件类型<br/>分发到对应业务函数"]
R1N0 --> R1N1 --> R1N2
end
class R1N0,R1N1,R1N2 green;
style R1 fill:#f0f8f3,stroke:#b9d7c4,color:#24563a
R0 -..->|"通过邮箱交给应用线程"| R1
classDef blue fill:#e8f2ff,stroke:#7ba4d8,color:#23456b,stroke-width:1.5px;
classDef green fill:#e7f4ec,stroke:#78aa8b,color:#24563a,stroke-width:1.5px;
classDef amber fill:#fff3df,stroke:#d5a25b,color:#72501e,stroke-width:1.5px;一、初始化时,登记事件接收函数
app_mcu_core_capsensor_init() 中有一行:
register_capsensor_click_event_callback(app_capsensor_click_event);
它告诉检测模块:“有操作事件时,交给 app_capsensor_click_event 处理。”函数内部通过 capsensor_click_event_cb = p 保存这个函数的地址。登记时不执行它,等事件产生后再调用,这种方式叫作回调。

二、检测到事件,进入应用接收函数
检测线程确认 status.event 不是 CAP_KEY_EVENT_NONE,且已经登记接收函数后,执行:
capsensor_click_event_cb(status.event);
由于保存的是 app_capsensor_click_event,这里便进入该函数,传入本次识别结果。这一步仍在检测线程中执行。
这里看 MCU 对应的分支。

以双击为例,接收函数把检测模块的 CAP_KEY_EVENT_DOUBLECLICK 转成按键模块使用的 APP_KEY_EVENT_DOUBLECLICK。这只是对应事件表示,具体功能由后续业务决定。

三、通过邮箱,交给应用线程
转换完成后,调用:
capsensor_key_event_process(status.code, status.event);
两个参数分别是按键编号和操作类型。接收函数将它们打包成 APP_MODULE_KEY 消息,放入应用邮箱,等待应用线程处理。
调用应用接收函数与切换到应用线程,是两件事。 前面直接调用接收函数;这里通过邮箱交接,后续按键业务才由应用线程处理。

四、应用线程找到对应业务
应用线程按 APP_MODULE_KEY 分发消息,进入 app_key_handle_process()。它还原按键编号和事件,再调用 app_ibrt_user_key(),进入产品处理流程。

后续还要检查产品状态,并可能把事件转给对耳。以“本机继续处理的右耳双击”为例:
%%{init: {"flowchart": {"htmlLabels": true, "wrappingWidth": 1000, "rankSpacing": 30}, "themeVariables": {"lineColor": "#71829a"}}}%%
flowchart TB
subgraph R0["① 本机继续处理"]
direction LR
R0N0["产品处理入口<br/>app_ibrt_user_key()"]
R0N1["区分左右耳<br/>app_wgr_ui_handle_key()"]
R0N0 --> R0N1
end
class R0N0,R0N1 blue;
style R0 fill:#f1f6fd,stroke:#b8cfe8,color:#23456b
subgraph R1["② 右耳双击分支"]
direction LR
R1N0["区分单击、双击等事件<br/>app_wgr_ui_handle_right_key()"]
R1N1["结合状态执行功能<br/>bt_key_handle_func_doubleclick_right()"]
R1N0 -->|"双击"| R1N1
end
class R1N0,R1N1 green;
style R1 fill:#f0f8f3,stroke:#b9d7c4,color:#24563a
R0 -->|"右耳"| R1
classDef blue fill:#e8f2ff,stroke:#7ba4d8,color:#23456b,stroke-width:1.5px;
classDef green fill:#e7f4ec,stroke:#78aa8b,color:#24563a,stroke-width:1.5px;
classDef amber fill:#fff3df,stroke:#d5a25b,color:#72501e,stroke-width:1.5px;
右耳双击业务会查看通话状态:无通话时读取双击功能配置,有来电时可以执行接听。因此,要修改“双击做什么”,应继续找业务配置和处理函数。
具体业务分支可回看《系统总览(03):事件如何触发业务处理》 。

应用层调试时,可以依次观察:检测事件是否到达接收函数、消息是否进入按键模块、是否进入预期的左右耳和操作分支、当前业务条件是否满足。
上一篇:外设适配(01):触摸输入从采样到事件 。