4.3.2. APP - Bluetooth Multi connections

4.3.2.1. 2.13.1概述

  • 支持蓝牙双模透传传输数传,支持蓝牙LE多连接功能。CLASSIC蓝牙使用标准串口SPP profile协议,支持可发现搜索连接功能。蓝牙LE目前支持GAP 1主1从,或者2主的角色等应用。

  • 支持的板级: br25、br23、bd19、br34

  • 支持的芯片: AC636N、AC635N、AC632N、AC638N

Note

注意不同芯片可以使用RAM的空间有差异,有可能会影响性能。

4.3.2.2. 工程配置

  • 代码工程:apps/spp_and_le/board/br30/AC637N_spp_and_le.cbp

  • app配置,在工程代码中找到对应的文件(apps/hid/include/app_config.h)进行APP选择,本案例中选择翻页器,其结果如下图所示:

*//app case 选择,只能选1个,要配置对应的board_config.h*
#define CONFIG_APP_MULTI 0 //蓝牙LE多连 + spp
  • 配置多机个数和加密

*//蓝牙BLE配置*
#define CONFIG_BT_GATT_COMMON_ENABLE       1 \ *//配置使用gatt公共模块*
#define CONFIG_BT_SM_SUPPORT_ENABLE        0 \ *//配置是否支持加密*
#define CONFIG_BT_GATT_CLIENT_NUM          1 \ *//配置主机client个数 (app not support)*
#define CONFIG_BT_GATT_SERVER_NUM          1 \ *//配置从机server个数*
#define CONFIG_BT_GATT_CONNECTION_NUM      (CONFIG_BT_GATT_SERVER_NUM + CONFIG_BT_GATT_CLIENT_NUM) \ *//配置连接个数*
  • 板级选择,接着在文件(apps/hid/board/bd30/board_config.h)下进行对应的板级选择如下:

*/\
 *  板级配置选择
 */
#define CONFIG_BOARD_AC637N_DEMO
*// #define CONFIG_BOARD_AC6373B_DEMO*
*// #define CONFIG_BOARD_AC6376F_DEMO*
*// #define CONFIG_BOARD_AC6379B_DEMO*

#include "board_ac637n_demo_cfg.h"
#include "board_ac6373b_demo_cfg.h"
#include "board_ac6376f_demo_cfg.h"
#include "board_ac6379b_demo_cfg.h"
#endif
  • 对应的板级头文件,配置是否打开 edr 和ble模块

#define TCFG_USER_BLE_ENABLE                      1   //BLE功能使能
#define TCFG_USER_EDR_ENABLE                      0   //EDR功能使能

4.3.2.3. 数据发送模块

  • 在(ble_multi_central.c)中打开MULTI_TEST_WRITE_SEND_DATA使能(数据发送使能):

#define  MULTI_TEST_WRITE_SEND_DATA      1   \ *//测试发数
  • 代码会在连接从机之后打开发送测试、在断开连接关闭发送测试,下图为测试发送接口:

//测试write数据操作
static void multi_client_test_write(void)
{
#if MULTI_TEST_WRITE_SEND_DATA
    static u32 count = 0;
    int i, ret = 0;
    u16 tmp_handle;

    count++;
    for (i = 0; i < SUPPORT_MAX_GATT_CLIENT; i++) {
        tmp_handle = ble_comm_dev_get_handle(i, GATT_ROLE_CLIENT);
        if (tmp_handle && multi_ble_client_write_handle) {
            ret = ble_comm_att_send_data(tmp_handle, multi_ble_client_write_handle, &count, 16, ATT_OP_WRITE_WITHOUT_RESPOND);
            log_info("test_write:%04x,%d", tmp_handle, ret);
        }
    }
#endif
}
  • 通过一个定时器每间隔500ms发送一包数据给从机

#if MULTI_TEST_WRITE_SEND_DATA
    sys_timer_add(0, multi_client_test_write, 500);
#endif

4.3.2.4. 主要代码说明

主任务处理文件apps/hid/app_multi_conn.c

  • APP注册处理(函数位于apps/hid/app_multi_conn.c)

在系统进行初始化的过程中,根据以下信息进行APP注册。执行的大致流程为:REGISTER_APPLICATION—>state_machine—>app_start()—>sys_key_event_enable();这条流程主要进行设备的初始化设置以及一些功能使能。REGISTER_APPLICATION—>event_handler—>app_key_event_handler()— >app_key_deal_test();这条流程在event_handler之下有多个case,上述选择按键事件的处理流程进行代码流说明,主要展示按键事件发生时,程序的处理流程。

static const struct application_operation app_multi_ops = {
    .state_machine  = state_machine,
    .event_handler  = event_handler,
};
*/\
 * 注册AT Module模式
 */
REGISTER_APPLICATION(app_multi) = {
.name  = "multi_conn",
.action = ACTION_MULTI_MAIN,
.ops  = &app_multi_ops,
.state  = APP_STA_DESTROY,
};

*//-----------------------*
*//system check go sleep is ok*
static u8 app_state_idle_query(void)
{
return !is_app_active;
}

REGISTER_LP_TARGET(app_state_lp_target) = {
.name = "app_state_deal",
.is_idle = app_state_idle_query,
};
  • APP状态机

状态机有create,start,pause,resume,stop,destory状态,根据不同的状态执行对应的分支。APP注册后进行初始运行,进入APP_STA_START分支,开始APP运行。

static int state_machine(struct application *app, enum app_state state, struct intent *it)
{    switch (state) {
    case APP_STA_CREATE:
        break;
    case APP_STA_START:
        if (!it) {
            break;          }
        switch (it->action) {
        case ACTION_MULTI_MAIN:

                app_start();
  • 进入app_start()函数后进行对应的初始化,时钟初始化,模式选择,蓝牙初始,低功耗初始化,以及外部事件使能。

static void app_start()
{
    log_info("=======================================");
    log_info("-----------------------multi_conn demo-----------------------");
    log_info("=======================================");
  • APP事件处理机制

  • 事件的定义(代码位于Headersinclude_libsystemeven.h中)

struct sys_event {
    u16 type;
    u8 consumed;
    void *arg;
    union {
        struct key_event key;
        struct axis_event axis;
        struct codesw_event codesw;
  • 事件的产生(include_libsystemevent.h)

void sys_event_notify(struct sys_event *e);//事件通知函数,系统有事件发生时调用此函数。
  • 事件的处理(app_mutil.c):函数执行的大致流程为:evevt_handler()—>app_key_event_handler()—>app_key_deal_test().

static int event_handler(struct application *app, struct sys_event *event)

static void app_key_event_handler(struct sys_event *event)

static void app_key_deal_test(u8 key_type, u8 key_value)
  • LE公共处理ble_multi_conn.c,配置Gatt common模块初始化,蓝牙初始化等操作

  • LE的GATT server ( :GATT COMMON )实现ble_multi_peripheral.c,配置Gatt Server端的广播、连接、事件处理等

  • LE的GATT client ( :GATT COMMON )实现ble_multi_central.c,配置Gatt Cleint端的搜索、连接、事件处理等