本帖最后由 会飞的猪_2020 于 2024-10-30 10:47 编辑
测试用的开发板:某宝链接
测试的例程:
bl602_demo.tar.gz.rar
(19.35 MB, 下载次数: 0)
固件:
bl602_demo.bin
(347.19 KB, 下载次数: 0)
nordic教程:nordic蓝牙基础教程1
zephyr github仓库地址:zephyr/bluetooth
nordic connect sdk仓库地址:nordic/bluetooth
zephyr api:api

bl602的蓝牙sdk和zephyr的蓝牙sdk一模一样,就是可能版本有些老,部分功能,宏定义有缺失。
直接把nordic教程里的代码抄过来会发现有的函数没定义,然后查看nordic connect sdk把缺少的补全之就能实现教程里的效果了。
在教程里建立了一个公开的LED按钮服务(LED Button Service),可以通过智能手机去控制开发板上的小灯亮灭。
实验结果如下(我用串口打印表示小灯亮灭,没有实际接小灯):

这里的gatt serv注册方式有点复杂。一开始我没找到显示调用的地方。
后来在gatt初始化的源码里找到这样一个宏定义:
[C] 纯文本查看 复制代码 /*
* Itterator for structure instances gathered by Z_STRUCT_SECTION_ITERABLE().
* The linker must provide a _<struct_type>_list_start symbol and a
* _<struct_type>_list_end symbol to mark the start and the end of the
* list of struct objects to iterate over.
*/
#define Z_STRUCT_SECTION_FOREACH(struct_type, iterator) \
extern struct struct_type _CONCAT(_##struct_type, _list_start)[]; \
extern struct struct_type _CONCAT(_##struct_type, _list_end)[]; \
for (struct struct_type *iterator = \
_CONCAT(_##struct_type, _list_start); \
({ __ASSERT(iterator <= _CONCAT(_##struct_type, _list_end), \
"unexpected list end location"); \
iterator < _CONCAT(_##struct_type, _list_end); }); \
iterator++)
#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_ */
这种格式的代码看这个有点眼熟,于是在map里面搜索了下面这个变量。
[C] 纯文本查看 复制代码 _list_start
看到这里有恍然大悟了。在应用程序里定义了lbs_svc这个gatt的结构体之后,的确没有去调用它。
它是被放到._bt_gatt_service_static.static.这个section里面,而在这个段的前面是_bt_gatt_service_static_list_start,后面是_bt_gatt_service_static_list_end。
于是不需要显示的被调用,在gatt_init的时候,自己会通过Z_STRUCT_SECTION_FOREACH这个宏定义,去搜索并且自己调用它。

所以在应用程序里面只需要把这个service定义就行了:
[C] 纯文本查看 复制代码 BT_GATT_SERVICE_DEFINE(lbs_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_LBS),
#ifdef CONFIG_BT_LBS_POLL_BUTTON
BT_GATT_CHARACTERISTIC(BT_UUID_LBS_BUTTON,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ, read_button, NULL,
&button_state),
#else
BT_GATT_CHARACTERISTIC(BT_UUID_LBS_BUTTON,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ, NULL, NULL, NULL),
#endif
BT_GATT_CCC(lbslc_ccc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
BT_GATT_CHARACTERISTIC(BT_UUID_LBS_LED,
BT_GATT_CHRC_WRITE,
BT_GATT_PERM_WRITE,
NULL, write_led, NULL),
);
这些宏的含义,可以查看zephyr的API得知。
它就是构建了一个UUID为BT_UUID_LBS的服务(00001523-1212-efde-1523-785feabcd123)
这个服务下面有两个CHARACTERISTIC,一个是按钮的,一个是小灯的。
(我没有实现按钮,因为我的开发板上没有按钮)
如果你对蓝牙的service有了解的话,可以通过命名猜出这个宏里面的内容的含义。
关于这部分的基础概念,也可以通过阅读nordic的教程获取。
它的结构如下所示,一个profile有多个service,一个service可以有多个characteristic。
知道了这个之后,看BT_GATT_SERVICE_DEFINE这个宏的结构,就和图片里的表示类似了。

更多详细的内容就不加赘述了,可以自行参考nordic的教程以及翻阅代码去了解。
|