当前文档版本为 v1.0.1,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

NDK 快速入门指南

1 概述

本文是 PAN108x NDK 开发的快速入门指引,旨在帮助使用者快速入门 PAN1080 NDK 的相关开发。

2 PAN108x EVB 介绍

PAN108x EVB (EValuation Board) 是 Panchip 提供给 PAN108x 芯片用户的一系列开发板的总称,目前包括 7 种 EVB 核心板,1 种 EVB 底板,以及 1 种 Mesh Dongle 板:

开发板名称

SoC 型号

封装

Flash 大小

PAN1080UB1A EVB 核心板

PAN1080UB1A

QFN32 (5x5)

1 MB

PAN1080UA3C EVB 核心板

PAN1080UA3C

QFN48

512 KB

PAN1080LB5A EVB 核心板

PAN1080LB5A

LQFP64

1 MB

PAN1081UB1A EVB 核心板

PAN1081UB1A

QFN32 (5x5)

1 MB

PAN1082UA1C EVB 核心板

PAN1082UA1C

QFN32 (5x5)

512 KB

PAN1083UA1C EVB 核心板

PAN1083UA1C

QFN32 (4x4)

512 KB

PAN3730 EVB 核心板

PAN3730UB5A

QFN64

1 MB

PAN108x EVB 底板

-

-

-

PAN108 Mesh Dongle

PAN1080UB1A

QFN32 (5x5)

1 MB

关于 PAN108x EVB 开发板硬件的详细介绍,请参考 PAN108x EVB 硬件资源介绍

3 PAN1080 NDK 开发环境确认

3.1 PC 环境检查

请确认KEIL(推荐5.25版本以上), PAN108x下载依赖的flm文件,Jlink设备等准备就绪。

3.2 快速编译运行一个简单的例程

硬件接线准备,请确认您已经将 PAN108x EVB 板的:

  1. SWD(P46:SWD_CLK,P47:SWD_DAT,GND:SWD_GND)接口通过 JLink 连接至 PC

  2. UART0接口通过 USB 转串口模块连接至 PC

    • 对于 32-pin 和 64-pin 封装的 EVB 核心板(Board 名称:pan108xxa1_evb / pan108xxb1_evb / pan108xxb5_evb),程序默认引脚配置为:UART0-Tx:P00,UART0-Rx:P01

    • 对于 48-pin 封装的 EVB 核心板(Board 名称:pan108xxa3_evb),现在demo中与 32-pin 和 64-pin一样,请根据使用进行调整。推荐使用:UART0-Tx:P30,UART0-Rx:P31

  3. 打开一个sample工程,例如01_SDK\nimble\samples\bleprph_enc下的keil目录下的工程文件bleprph_enc.uvprojx

  4. 点击Build编译按钮,然后点击Download按钮进行下载(如果缺少FLM文件,KEIL会弹出提示框进行提示)。

  5. 下载完成后会通过串口观察log输出(串口波特率:921600

[16:27:02.651]ÊÕ¡û¡ôBT controller memory pool used: 400 bytes, remain bytes: 10600, total:11000
BT controller memory pool used: 792 bytes, remain bytes: 10208, total:11000
BT controller memory pool used: 3812 bytes, remain bytes: 7188, total:11000
BT controller memory pool used: 4868 bytes, remain bytes: 6132, total:11000
BT controller memory pool used: 5192 bytes, remain bytes: 5808, total:11000
BT controller memory pool used: 6492 bytes, remain bytes: 4508, total:11000
BT controller memory pool used: 9264 bytes, remain bytes: 1736, total:11000
BT controller memory pool used: 9616 bytes, remain bytes: 1384, total:11000
BT controller memory pool used: 9952 bytes, remain bytes: 1048, total:11000
ble_store_config_num_our_secs:0
ble_store_config_num_peer_secs:0
ble_store_config_num_cccds:0
registered service 0x1800 with handle=1
registering characteristic 0x2a00 with def_handle=2 val_handle=3
registering characteristic 0x2a01 with def_handle=4 val_handle=5
registered service 0x1801 with handle=6
registering characteristic 0x2a05 with def_handle=7 val_handle=8
registered service 0x1811 with handle=10
registering characteristic 0x2a47 with def_handle=11 val_handle=12
registering characteristic 0x2a46 with def_handle=13 val_handle=14
registering characteristic 0x2a48 with def_handle=16 val_handle=17
registering characteristic 0x2a45 with def_handle=18 val_handle=19
registering characteristic 0x2a44 with def_handle=21 val_handle=22
registered service 59462f12-9543-9999-12c8-58b459a2712d with handle=23
registering characteristic 33333333-2222-2222-1111-111100000000 with def_handle=24 val_handle=25
registering descriptor 34343434-2323-2323-1212-121201010101 with handle=27

[16:27:02.745]ÊÕ¡û¡ôDevice Address: 01 02 03 04 05 06

此时通过nrf connect可以观察到nimble-bleprph蓝牙设备。

4 PAN1080 NDK 工程介绍

4.1 Nimble工程结构介绍

见下图:

image

Nimble工程结构介绍

4.2 切换工程为Spark Controller

我们可以通过切换工程配置直接切换为Spark Controller,该Controller为优化版本,该版本为精简和优化版本,速度更快功耗更低,但是目前主要实现BLE 4.2+版本feature,其他5.0+feature功能后续迭代升级。

切换后Controller整体结构基本与之前的相同,差异点请见后续章节。

4.3 更改蓝牙广播public地址

在main.c中app_main函数:

void app_main(void)
{
     int rc;

    /** set public address*/
    uint8_t pub_mac[6]={1,2,3,4,5,6};
    db_set_bd_address(pub_mac);

4.4 更改蓝牙广播设备名称

  • 代码主动设置设备名称

    /* Set the default device name. */
    rc = ble_svc_gap_device_name_set("nimble-bleprph");
  • 如果没有主动设备设备名称,则使用默认设备名称

nimble_syscfg.h中使用默认宏指定的设备名称

#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME
#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("nimble")
#endif

4.5 App配置文件介绍[重要]

App配置文件涉及系统主频,外设分频,蓝牙相关的参数等等,所以比较重要。

此处因为keil的限制,无法将.h显式禁用标志,所以此处两种controller的config.h文件同时显示了。

4.5.1 app_config.h(Origin controller配置文件)

当且且仅当工程配置为bleprph_enc配置有效,其他项目可以参考。

image

​ 基于Origin Controller的App config配置

4.5.2 app_spark_config.h(spark controller配置文件)

当且且仅当工程配置为bleprph_enc_spark配置有效,其他项目可以参考。

image

基于Spark Controller的App config配置

后续SDK功能迭代后可能配置上可能有些许差异,差异点会在该文中详细描述。

4.5.3 Config配置详解

App and MCU Config

  • System Clock: 系统主频

  • Periph Divide: 外设时钟分频系数

  • Log Enable :日志使能开关

BLE Stack Config

  • Low-Speed Clock: 低功耗32K时钟源,默认支持XTL,RCL,ACT32K(ACT32K为系统主频分出来的32K,但是不能在低功耗场景使用)

  • BT_CTLR_MAX_NUM_OF_STATES: controller支持的状态数,可能会影响到多连接个数

  • TX Power: 发射功率

  • Force Calib RCL: RCL是否初始化时进行校准

  • Low Power Enable: 低功耗使能开关

  • BT controller Memory Pool usage print:打印Controller所需要的内存时数据,host可以根据需求进行分配,分配好后可关闭该开关。(例如调整BT_CTLR_MAX_NUM_OF_STATES后需要重新适配,该内存由于是从host进行分配的,所以需要host进行定义)

  • BT AGC init Mode:蓝牙射频配置

  • BT Debug Pin Init: 蓝牙调试信号

4.6 Nimble Host配置

Nimble Host协议栈也可以根据配置文件进行功能的裁剪,其所依赖的配置文件为nimble_syscfg.h

nimble中该文件原名syscfg.h,此处为了显式的指名该配置文件意义,故重命名为nimble_syscfg.h

image

Nimble Host配置

另外需要注意的是nimble中使用特定的宏来处理nimble_syscfg.h的宏

例如正常使用 MYNEWT_VAL_BLE_WHITELIST时如下:

#if MYNEWT_VAL_BLE_WHITELIST
...
#endif

但是在nimble中用法如下:

#define MYNEWT_VAL(_name)                       MYNEWT_VAL_ ## _name

#if MYNEWT_VAL(BLE_WHITELIST)
....
#end

对一些不需要使用role的可以通过相应配置进行裁剪,例如:

#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (0)
#endif

#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL
#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1)
#endif

#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER
#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1)
#endif

#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL
#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (0)
#endif

4.7 FreeRTOS配置文件

image

FreeRTOS配置

详情参考FreeRTOS官方网站,当前FreeRTOS基于FreeRTOS Kernel V10.5.1版本移植。

目前Nimble低功耗已经基于FreeRTOS适配完成,CONFIG_PM_ENABLE为1时即表示低功耗开关使能。

需要注意的是如下的宏(建议堆全局使用FreeRTOS的pvPortMalloc进行管理):

#define configTOTAL_HEAP_SIZE                 ((size_t)16 * 1024) /*全局堆使用*/

#define portSTACK_TYPE    uint32_t 			/*栈的单位为4字节大小*/
typedef portSTACK_TYPE   StackType_t;

4.8 bleprph_enc示例中的蓝牙初始化介绍

void app_main(void)
{
     int rc;

    /*1.设置public地址*/
    /** set public address*/
    uint8_t pub_mac[6]={1,2,3,4,5,6};
    db_set_bd_address(pub_mac);

    /*2.初始化话配置全局变量(重要),该配置注册的相关回调函数,会在蓝牙初始化完成后的不同阶段进行回调*/
    /* Initialize the NimBLE host configuration. */
    ble_hs_cfg.reset_cb = bleprph_on_reset; /*复位回调*/
    ble_hs_cfg.sync_cb = bleprph_on_sync;/*协议栈初始化完成回调【重要】,例如初始化协议栈完成后需要广播时,可以在此注册回调函数*/
    ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;/*服务注册回调函数,可以在此注册回调函数,用于打印出特别关注从特性的handle*/
    ble_hs_cfg.store_status_cb = ble_store_util_status_rr;/*存储事件回调,例如存储溢出时可以做一些轮转实现*/

    ble_hs_cfg.sm_io_cap = CONFIG_EXAMPLE_IO_TYPE; /*SMP IO capablity*/
#ifdef CONFIG_EXAMPLE_BONDING
    ble_hs_cfg.sm_bonding = 1;
    /* Enable the appropriate bit masks to make sure the keys
     * that are needed are exchanged
     */
    ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
    ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
#endif
#ifdef CONFIG_EXAMPLE_MITM
    ble_hs_cfg.sm_mitm = 1;
#endif
#ifdef CONFIG_EXAMPLE_USE_SC
    ble_hs_cfg.sm_sc = 1;
#else
    ble_hs_cfg.sm_sc = 0;
#endif
#ifdef CONFIG_EXAMPLE_RESOLVE_PEER_ADDR
    /* Stores the IRK */
    ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
    ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
#endif

    rc = gatt_svr_init(); /*3.GATT服务初始化,例如GAP,GATT, ANS服务(应用层服务)等等在此初始化*/
    assert(rc == 0);

    /* Set the default device name. */
    rc = ble_svc_gap_device_name_set("nimble-bleprph"); /*4.设置蓝牙设备名称*/
    assert(rc == 0);

    /* XXX Need to have template for store */
    ble_store_config_init();/*5.加载NVS数据到ram中,例如配对数据*/

	hs_thread_init();	/*6.蓝牙host协议栈初始化,创建host线程,初始化完成后会调用ble_hs_cfg中的相关回调函数*/
}