上一篇 讲到检测线程得到单击、双击等事件。这篇接着看:事件怎样进入应用,最后找到对应业务。

本项目的 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):触摸输入从采样到事件 。