在 Nordic SDK 的 BLE 应用中,多个文件(如 main.c、bsp_btn_ble.c、ble_conn_state.c、ble_conn_params.c)都定义了一个名为 ble_evt_handler 的函数。这并不是代码错误或重复,而是观察者模式的典型应用。

为什么会有四个"一样"的函数?
-
模块化设计:每个功能模块(应用逻辑、按键管理、连接状态跟踪、连接参数协商)需要独立响应 BLE 事件。若把所有事件处理写在一个函数里,会导致代码臃肿、难以维护。
-
各自注册:每个模块通过NRF_SDH_BLE_OBSERVER 宏将自己 ble_evt_handler 的地址注册到 SoftDevice 的事件分发表中。SoftDevice 产生任何 BLE 事件时,会按优先级依次调用所有注册的处理函数。
-
函数名相同但无冲突:因为每个 ble_evt_handler 都被声明为 static,作用域仅限于各自的
.c文件,链接器不会认为它们是重复符号。




优先级总结:

为什么可以共存而不冲突?
-
观察者模式 :SoftDevice 产生一个 BLE 事件后,会按优先级顺序依次调用所有注册的观察者(每个观察者是一个函数)。
-
各司其职 :每个观察者只处理自己关心的事件类型(通过
switch筛选),不关心的事件直接忽略。 -
无副作用干扰 :即使多个观察者处理同一个事件(例如
BLE_GAP_EVT_CONNECTED),它们修改的是不同的内部数据结构(ble_conn_state维护标志、main.c更新 LED、bsp_btn_ble配置按键),互不冲突。