Zephyr nRF52840开发

1. 开发环境和硬件平台

开发环境:

​ Ubuntu 18.04 + Zephyr‘s SDK and Tools

硬件平台:

​ PCA10056 DK (nRF52840)

2. 运行 Project

2.1 打开终端,运行 zephyr-env.sh

cd ~/git/zephyr/
source ./zephyr-env.sh

有时候会打开多个终端,每个终端都需要 source zephyr-env.sh , 这样比较繁琐。我们把该命令加入到 zshrc 或者 bashrc 中即可。

2.2 创建 build 文件夹

cd sample/bluetooth/peripheral
mkdir -p build/nrf52 && cd build/nrf52                # 创建文件夹

2.3 生成构建系统

cmake -GNinja -DBOARD=nrf52840_pca10056 ../..         # 利用 cmake 自动生成 build 系统。 依赖 CMakeLists.txt ,最后路径是当前目录与 CMakeLists.txt 的相对路径

如果出问题,请在检查:

  1. 在当前终端运行 source zephyr-env.sh
  2. 检查路径 ../.. 是否对

2.4 构建Build

ninja                                                 # ninja 或者 make             
ninja flash                                           # 烧录代码

2.5 验证

使用 nRF connect (Android) 可以观察到

设备名 Zephyr Peripheral Sample Long

复位重启硬件会发现MAC地址在变更。第一次: 44:3A:6B:C6:30:9A ; 第二次: 5C:0A:1D:CE:2D:38

3. Zephyr BLE 主流程

  1. bt_enable(bt_ready) 当初始化完成,调用bt_ready,在bt_ready中进行 service初始化,开启广播。

  2. bt_conn_cb_register 注册连接和断连的回调函数,我们可以在回调函数中处理相关事件。

    conn_callbacks = { .connected = connected, .disconnected = disconnected};

    static void connected(struct bt_conn *conn, u8_t err){ printk("Connected\n");}
    static void disconnected(struct bt_conn *conn, u8_t reason){ printk("Disconnected\n");}
    
  3. bt_conn_auth_cb_register(&auth_cb_display)

Created with Raphaël 2.2.0 开始 bt_enable(bt_ready) bt_conn_cb_register(&conn_callbacks) bt_conn_auth_cb_register(&auth_cb_display) End

4. bt_ready() 处理任务

在 bt_ready 函数里,可以初始化所需要的 service, 例如 BASDIS 或者自定义 service

Created with Raphaël 2.2.0 开始 bas_init() dis_int(CONFIG_SOC,"Manufacturer") 其他 gatt service 注册 End

5. 修改设备名

在 prj.conf 中修改设备名

CONFIG_BT_DEVICE_NAME="BLE_Zephyr"  # 设置设备名
# CONFIG_BT_DEVICE_NAME_DYNAMIC=y     # 注释掉该配置信息,取消动态设备名

6. 固定设备MAC

在 prj.conf 中修改

# CONFIG_BT_PRIVACY=y                  # 注释掉该配置信息,取消动态 MAC 地址

7. 广播参数修改

广播间隔,可否连接,显示设备名。

默认设备名是放在扫描响应包里。

// 在 bt_ready() 函数上方定义广播参数
#define BT_GAP_ADV_FAST_INT_MIN_3   0x00f0
#define BT_GAP_ADV_FAST_INT_MAX_3   0x00f0
#define BT_LE_ADV_CONN_NAME1  BT_LE_ADV_PARAM( BT_LE_OPT_CONNECTABLE  | \
                              BT_LE_ADV_OPT_USE_NAME,  \
                              BT_GAP_ADV_FAST_INT_MIN_2, \ //0x00a0=160 160*0.625=100ms
                              BT_GAP_ADV_FAST_INT_MAX_2)   //0x00f0=240 240*0.625=150ms
// 在 bt_ready() 函数中修改参数
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME1, ad, ARRAY_SIZE(ad), NULL, 0);
// ad   advertising data
// sd   scan response data

编译 & 烧录

ninja 
ninja flash

可以验证广播连接间隔变成了 150ms 左右。

8. Service 修改

8.1 gatt_attr 结构体赋值

static struct bt_gatt_attr vnd_attrs[] = {
    BT_GATT_PRIMARY_SERVICE(&vnd_uuid),
    BT_GATT_CHARACTERISTIC(&vnd_uuid.uuid,
    			BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
    			BT_GATT_CHRC_INDICATE,
    			BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
    			read_vnd, write_vnd, vnd_value),
    BT_GATT_CCC(vnd_ccc_cfg, vnd_ccc_cfg_changed),
}

8.2 gatt_service 结构体赋值

static struct bt_gatt_service vnd_svc = BT_GATT_SERVICE(vnd_attrs);

8.3 在 bt_ready 中注册 service

bt_gatt_service_register(&vnd_svc);

8.4 gatt_attr 结构体内容详解

8.4.1 Primary Service UUID

必须有该项

/* Custom Service Variables */
static struct bt_uuid_128 vnd_uuid = BT_UUID_INIT_128(
        0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
        0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);
BT_GATT_PRIMARY_SERVICE(&vnd_uuid)

8.4.2 Characteristic UUID

如果有多个特性,需要多个UUID

static struct bt_uuid_128 vnd_enc_uuid = BT_UUID_INIT_128(
        0xf1, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
        0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);

8.4.3 Notification or Indication characteristic

ccc 启动。

static struct bt_gatt_ccc_cfg blvl_ccc_cfg[BT_GATT_CCC_MAX] = {};
static void blvl_ccc_cfg_chaged(const struct bt_gatt_attr *attr, u16_t value){
    simulate_blvl = (value == BT_GATT_CCC_NOTIFY) ? 1 : 0;
}
BT_GATT_CCC(blvl_ccc_cfg, blvl_ccc_cfg_changed);


// process
void bas_nofity()
{
    if (!simulate_blvl) {
        return;
    }
    
    battery--;
    if (!battery) {
        battery = 0;
    }
    // attrs[0] = primary service
    bt_gatt_notify(NULL, &attrs[1], &battery, sizeof(battery));
}

9. 配对

iOS 配对有问题,暂时不使用

你可能感兴趣的:(Zephyr,BLE)