ZJ-RT-Thread-NIMBLE-NORDICZJ-BLE基于国产开源RT-Thread操作系统和开源BLE5.0(mynewt-nimble)协议栈在nordic(nrf52832/nrf52840)平台上的应用彻底开源的BLE5.0协议栈源码ZJ-BLE介绍ZJ-BLE源码使用mynewt-nimble开源BLE协议栈 https://github.com/apache/mynewt-nimbleRT-Thread官方的出的nimble的见白大神的GitHub nrf52832-bspZJ-BLE源码使用的RT-Thread V4.0内核 https://github.com/RT-Thread/rt-threadZJ-BLE源码使用的NORDIC官方SDK15.0的nrfx驱动 http://developer.nordicsemi.com/nRF5_SDK/ZJ-BLE源码支持nrf52832和nrf52840蓝牙芯片ZJ-BLE源码支持KEIL集成开发环境开发SDK支持的IDEMDK Keil https://www.keil.com/download/product/硬件平台NORDIC nrf52832/nrf52840

这个是上篇中修改白大神的代码得到的,就可以安安心心的分析ble协议栈了,再结合那个葵花宝典《BLE4.0低功耗蓝牙协议完全解析》(公众号回复 协议文档 会有下载地址,或者在https://github.com/ZJ-TEK/ZJ-SDK-RT-Thread-NORDIC这里也有文档)应该就会慢慢的对BLE了解了。
目前工程中还只有一个工程,这个工程只保留了RT-Thread的内核代码+nimble+nordic的RTC作为RT-Thread的时钟源码代码,目的是做一个最基础的工程,可以方便的分析BLE,这个代码目前还没有做好低功耗,这个我也在查资料解决,和白大神沟通了,他也在处理中。
下面简单看看nimble_hrm的工程:

看看广播源码结构
struct ble_hs_adv_fields { /*** 0x01 - Flags. */ uint8_t flags; /*** 0x02,0x03 - 16-bit service class UUIDs. */ ble_uuid16_t *uuids16; uint8_t num_uuids16; unsigned uuids16_is_complete:1; /*** 0x04,0x05 - 32-bit service class UUIDs. */ ble_uuid32_t *uuids32; uint8_t num_uuids32; unsigned uuids32_is_complete:1; /*** 0x06,0x07 - 128-bit service class UUIDs. */ ble_uuid128_t *uuids128; uint8_t num_uuids128; unsigned uuids128_is_complete:1; /*** 0x08,0x09 - Local name. */ uint8_t *name; uint8_t name_len; unsigned name_is_complete:1; /*** 0x0a - Tx power level. */ int8_t tx_pwr_lvl; unsigned tx_pwr_lvl_is_present:1; /*** 0x0d - Slave connection interval range. */ uint8_t *slave_itvl_range; /*** 0x16 - Service data - 16-bit UUID. */ uint8_t *svc_data_uuid16; uint8_t svc_data_uuid16_len; /*** 0x17 - Public target address. */ uint8_t *public_tgt_addr; uint8_t num_public_tgt_addrs; /*** 0x19 - Appearance. */ uint16_t appearance; unsigned appearance_is_present:1; /*** 0x1a - Advertising interval. */ uint16_t adv_itvl; unsigned adv_itvl_is_present:1; /*** 0x20 - Service data - 32-bit UUID. */ uint8_t *svc_data_uuid32; uint8_t svc_data_uuid32_len; /*** 0x21 - Service data - 128-bit UUID. */ uint8_t *svc_data_uuid128; uint8_t svc_data_uuid128_len; /*** 0x24 - URI. */ uint8_t *uri; uint8_t uri_len; /*** 0xff - Manufacturer specific data. */ uint8_t *mfg_data; uint8_t mfg_data_len; };
有没有一种一目了然的感觉,可以看之前的文章《这次一定搞定广播的62字节》
表1-1广播类型定义AD Type
AD Type | Value | 描述 |
Flags | 0x01 | 广播出自己蓝牙某些特性 |
Service UUIDs | 0x02~0x07 | 广播出自己服务的UUID |
Local Name | 0x08/0x09 | 广播出自己的蓝牙名字 |
TX Power Level | 0x0A | 广播出自己的射频发射功率 |
Simple Pairing Option OOB Tags | 0x0D~0x0F | 广播出安全管理带外标签(本文忽略) |
Security Manager TK Value | 0x10 | 广播出带外方式配对绑定时的TK(本文忽略) |
Security Manager OOB Flags | 0x11 | 广播出带外特性标志(本文忽略) |
Slave Connection Interval Range | 0x12 | 广播出自己希望的连接参数范围 |
Service Solicitation | 0x14/0x15 | 广播出自己希望来接自己的主机有特定的服务 |
Service Data | 0x16 | 服务数据 |
Manufacturer Specific Data | 0xFF | 广播出厂商信息(用户可以放自定义数据) |
看看广播数据怎么设置
static voidblehr_advertise(void){ struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; int rc; /* * Set the advertisement data included in our advertisements: * o Flags (indicates advertisement type and other general info) * o Advertising tx power * o Device name */ memset(&fields, 0, sizeof(fields)); /* * Advertise two flags: * o Discoverability in forthcoming advertisement (general) * o BLE-only (BR/EDR unsupported) */ fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; /* * Indicate that the TX power level field should be included; have the * stack fill this value automatically. This is done by assigning the * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. */ fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; fields.name = (uint8_t *)device_name; fields.name_len = strlen(device_name); fields.name_is_complete = 1; /*** 0x02,0x03 - 16-bit service class UUIDs. */ fields.num_uuids16 = 1; fields.uuids16 = m_adv_uuids; fields.uuids16_is_complete = 1; rc = ble_gap_adv_set_fields(&fields); if (rc != 0) { MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc); return; } /*** 0xff - Manufacturer specific data. */ memset(&fields, 0, sizeof(fields)); fields.mfg_data = (uint8_t*)"GZH:Bluetooth-BLE,177341833"; fields.mfg_data_len = 27; rc = ble_gap_adv_rsp_set_fields(&fields); if (rc != 0) { MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc); return; } /* Begin advertising */ memset(&adv_params, 0, sizeof(adv_params)); adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; rc = ble_gap_adv_start(blehr_addr_type, NULL, BLE_HS_FOREVER, &adv_params, blehr_gap_event, NULL); if (rc != 0) { MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc); return; }}
各位大佬,有没有感觉这个源码非常非常的吊啊!反正我是感觉很吊很吊了!
演示效果
不抽B了,看看演示效果吧!编译nRF52840的工程,下载到nRF52840
广播hrm_adv 注意广播内容中无处不在的广告!

设备信息hrm_dev_info 注意设备信息中无处不在的广告!

心率显示hrm 1s 4个心率值

好了,差不多了,今天就到这儿了,下一次发文章也不知道是什么时候了,但是我自己会研究这个代码学习BLE 以及MESH的,当然这个代码我也会不停的增加工程的,例如加入finsh和控制台便于调试,同时也会关注HCI接口,看能否将52840的USB用上,然后电脑上面写一个HCI的HOST,这样就能更方便的调试了。