Nordic SoftDevice蓝牙主机操作流程

Nordic SoftDevice蓝牙主机操作流程


之前学习nordic的nus client 主机例程时做了些笔记,现在有空重新整理了一下发出来。
在这里插入图片描述

NRF_SDH_BLE_OBSERVER 宏介绍

  • 这个宏可以设置多个BLE事件的回调函数,并按设置的优先级依次执行。这么一来,就可以将扫描,广播,连接,服务发现,读写等蓝牙事件的处理分到多个函数中去处理。
  • 比如,在mian.c里会调用NRF_BLE_SCAN_DEF(m_scan)来使能扫描功能,实际上用的是NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, NRF_BLE_SCAN_OBSERVER_PRIO,nrf_ble_scan_on_ble_evt, &_name),也就是之后所有的ble事件都会来到nrf_ble_scan_on_ble_evt函数,这个函数里面只针对扫描相关的事件进行处理,然后再调用用户在scan_init时注册的回调函数来做所需要的逻辑。
  • 也就是说,ble事件的发生其实会调用很多回调:
    1.ble事件 —> 系统定义好的扫描事件回调 —> 针对特定ble事件,调用用户在mian.c编写的回调实现逻辑
    2.ble事件 —> 系统定义好的扫描服务发现回调 —> 针对特定ble事件,调用用户在mian.c编写的回调实现逻辑
    3.ble事件 —> nus服务里定义好的回调 —> 针对特定ble事件,转为nus事件,再调用用户在mian.c编写的回调实现逻辑
    4.ble事件 —> 由于main.c的stack_init函数里也有一句NRF_SDH_BLE_OBSERVER,所以ble事件也会来到main.c的ble_evt_handler
  • 在nus的例程中,有4个具体的实例,都在mian.c开头都进行了DEF的宏操作,也就是注册了一个默认的回调,ble事件是先到默认回调,再到用户在各种init函数中设置的回调函数的。
  • 使用这种叫做观测者模式的方法,可以将众多ble事件分发到具体的回调函数中去处理,而且回调函数可以分散写在多个文件当中,减少了耦合程度。

nus服务实例

  • nus实例:m_ble_nus_c
  • nus初始化:void nus_c_init(void),里面设置了nus服务的用户回调函数(写在mian.c的那个)。实际上,在nus的服务文件里面调用了NRF_SDH_BLE_OBSERVER宏进行观察者注册,发生ble事件时,首先由观察者分发到nus服务回调,里面将ble事件转换了成nus事件,再调用mian.c的用户服务回调。通过这种方式,可以很方便的复用nus这个模块,并且用户只需要对转换后的nus事件进行处理即可,不再需要对ble的读和写和通知事件进行区分。
  • nus服务的用户回调函数:ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt);

scan实例

  • 扫描实例:m_scan
  • 扫描初始化,scan_init(void),设置扫描参数,使能滤波器,找到就连接,这里还设置了扫描的用户回调函数
  • 开始扫描,scan_start(void);
  • 扫描的用户回调函数:scan_evt_handler(scan_evt_t const * p_scan_evt);

    NRF_BLE_SCAN_EVT_CONNECTING_ERROR:报错

    NRF_BLE_SCAN_EVT_CONNECTED:打印连接MAC地址

    NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:重新扫描

gatt实例

  • gatt实例:m_gatt
  • gatt队列:m_ble_gatt_queue
  • gatt初始化:设置MTU,设置gatt层的用户回调:gatt_init(void)
  • gatt层的用户回调:gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)

    NRF_BLE_GATT_EVT_ATT_MTU_UPDATED:调整MTU

服务搜索实例

  • 搜索实例:m_db_disc
  • db_discovery_init(void),这个函数设置了服务发现的用户回调函数,当连接成功后会调用ble_db_discovery_start进行服务发现,服务发现完成后调用用户回调函数
  • 服务发现用户回调函数:db_disc_handler(ble_db_discovery_evt_t * p_evt);这里面就的调用了ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt),这个是具体服务的函数,里面会去判断当前设备有无这个服务,然后调用用户的服务回调。

协议栈初始化

  • 协议栈初始化,ble_stack_init(void); 主要是时钟配置、使能协议栈。这个函数会打印出使用的RAM空间,需要在keil进行相应的配置。最后,调用了NRF_SDH_BLE_OBSERVER宏进行注册观察者,有ble事件发生时调用相应的回调函数。
  • 蓝牙事件回调函数,各种事件的处理:ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    BLE_GAP_EVT_CONNECTED:连接事件,调用ble_db_discovery_start函数,开始搜索服务
    BLE_GAP_EVT_DISCONNECTED:断开连接事件,打印LOG
    BLE_GAP_EVT_TIMEOUT:打印超时LOG
    BLE_GAP_EVT_SEC_PARAMS_REQUEST:
    BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:连接参数更新应答
    BLE_GAP_EVT_PHY_UPDATE_REQUEST:PHY更新应答
    BLE_GATTC_EVT_TIMEOUT:客户端超时,主动断开连接
    BLE_GATTS_EVT_TIMEOUT:服务端超时,主动断开连接

串口打印

  • ble_nus_chars_received_uart_print(uint8_t * p_data, uint16_t data_len);
  • uart_event_handle(app_uart_evt_t * p_event);
  • void uart_init(void);

错误处理

  • assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name);
  • nus_error_handler(uint32_t nrf_error);

关闭电源

  • shutdown_handler(nrf_pwr_mgmt_evt_t event);

板子相关函数,主要是指示灯

  • 按键的中断函数:bsp_event_handler(bsp_event_t event)
  • 按键和指示灯初始化:buttons_leds_init(void)

以下函数略

  • 定时器初始化:timer_init(void)
  • 调试器打印初始化:log_init(void);
  • 能量管理器初始化:power_management_init(;void);
  • 这个不知道是啥:idle_state_handle(void);

流程整理,整体是事件驱动流转的

  • 初始化,开始扫描
  • 发现要连接的目标,触发BLE_GAP_EVT_ADV_REPORT事件,调用on_adv_report进行分析,如果是要连接的设备则进行连接。也可以通过设置相关的filter,一旦发现需要的目标则自动连接。
  • 如果连接成功,触发BLE_GAP_EVT_CONNECTED,调用ble_db_discovery_start寻找gatt层的服务。
  • 等待服务发现完成触发回调,进入到具体服务(比如nus)的处理过程,主要是判断有无相应的svc和char,然后转换成具体服务的一个事件,调用mian.c文件中写的具体服务的回调。
  • main.c中的用户服务回调进行订阅或者读写
  • 触发蓝牙读写事件,进入到具体服务的回调函数中进行初步处理,然后转为具体服务的事件,再调用mian.c文件中写的用户服务回调,如此往复。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/467412.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++生成高斯分布随机数

简单实现 在 C 中&#xff0c;可以使用 头文件中的功能来生成正态分布&#xff08;高斯分布&#xff09;随机数。以下是一个示例&#xff0c;展示如何使用 C11 及以上版本的标准库生成正态分布随机数。 #include <iostream> #include <random> #include <cmat…

SL6115降压恒流 60V降压恒流芯片,高精度1%,PWM模拟调光

一、核心参数与性能 工作电压范围&#xff1a;5.5V至60V&#xff0c;宽输入电压范围使其能够适应多种应用场景。 最大输出电流&#xff1a;根据公开发布的信息&#xff0c;SL6115的最大输出电流可达到1.2A至1.5A&#xff0c;具体取决于不同版本或制造商的规格说明。这一高输出…

lnmp:自己的“百度网盘”

一、项目简介 有人会问&#xff0c;什么是lnmp储存&#xff0c;相信大家都用过百度网盘&#xff0c;他的原理和lnmp的作用相同&#xff0c;都是将数据储存在私有云中。LNMP也是用来储存自己的数据&#xff0c;可以假象成这是一个属于自己的数据库。 二、详细概述 所谓LNMP便是…

「实战应用」如何用图表控件LightningChart .NET在WPF中制作表格?(一)

LightningChart .NET完全由GPU加速&#xff0c;并且性能经过优化&#xff0c;可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D&#xff0c;高级3D&#xff0c;Polar&#xff0c;Smith&#xff0c;3D饼/甜甜圈&#xff0c;地理地图和GIS图表以及适用于科…

鸿蒙进阶篇-网格布局 Grid/GridItem(二)

hello大家好&#xff0c;这里是鸿蒙开天组&#xff0c;今天让我们来继续学习鸿蒙进阶篇-网格布局 Grid/GridItem&#xff0c;上一篇博文我们已经学习了固定行列、合并行列和设置滚动&#xff0c;这一篇我们将继续学习Grid的用法&#xff0c;实现翻页滚动、自定义滚动条样式&…

SpringBoot框架:共享汽车管理的创新工具

5系统详细实现 5.1 管理员模块的实现 5.1.1 用户信息管理 共享汽车管理系统的系统管理员可以管理用户&#xff0c;可以对用户信息修改删除以及查询操作。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.1.2 投放地区管理 系统管理员可以对投放地区信息进行添加&#…

uniapp上拉刷新下拉加载

方法一&#xff1a; z-paging 的组件库&#xff1a; show-loading-more-no-more-view"false" 该属性控制是否显示 "加载更多" 或 "没有更多" 的提示。如果设为 false&#xff0c;则不会显示这些提示。如果设为 true&#xff0c;当数据加载完毕…

【Pikachu靶场:XSS系列】xss之过滤,xss之htmlspecialchars,xss之herf输出,xss之js输出通关啦

一、xss之过滤 <svg onloadalert("过关啦")> 二、xss之htmlspecialchars javascript:alert(123) 原理&#xff1a;输入测试文本为herf的属性值和内容值&#xff0c;所以转换思路直接变为js代码OK了 三、xss之href输出 JavaScript:alert(假客套) 原理&#x…

微分段如何防止勒索软件攻击

微分段通过隔离关键资产、限制网络横向移动、提供细粒度的最小特权访问、实现快速隔离、简化恢复、提高网络弹性以及减少爆炸半径来防止勒索软件攻击。 勒索软件攻击已成为各种规模的组织面临的越来越危险的威胁。 勒索软件利用横向移动技术来感染和加密尽可能多的端点和服务…

后端Node学习项目-项目基础搭建

前言 各位好&#xff0c;我是前端SkyRain。最近为了响应公司号召&#xff0c;开始对后端知识的学习&#xff0c;作为纯粹小白&#xff0c;记录下每一步的操作流程。 项目仓库&#xff1a;https://gitee.com/sky-rain-drht/drht-node 因为写了文档&#xff0c;代码里注释不是很…

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符&#xff0c;用于将一个表表达式&#xff08;如子查询、函数等&#xff09;与外部表进行连接。CROSS APPLY 类似于 INNER JOIN&#xff0c;但它允许你在一个查询中多次引用外部表的行&#xff0c;并且可以动态地生成结果集。 基本语法…

低空经济之星eVTOL研发技术详解

低空经济之星eVTOL&#xff08;Electric Vertical Take-off and Landing&#xff09;是一种采用储能电池、电机驱动以及螺旋桨推进方式&#xff0c;并具备垂直起降功能的新型航空器。以下是对eVTOL研发技术的详解&#xff1a; 一、技术特点 1. 分布式推进系统 结构简单性与轻…

算法每日双题精讲——双指针(快乐数,盛最多水的容器)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#xff01;&#x1f4aa;…

【c++ gtest】使用谷歌提供的gtest和抖音豆包提供的AI大模型来对代码中的函数进行测试

【c gtest】使用谷歌提供的gtest和抖音豆包提供的AI大模型来对代码中的函数进行测试 下载谷歌提供的c测试库在VsCode中安装抖音AI大模型找到c项目文件夹&#xff0c;使用VsCode和VS进行双开生成gtest代码进行c单例测试 下载谷歌提供的c测试库 在谷歌浏览器搜索github gtest, 第…

数据库SQLite的使用

SQLite是一个C语言库&#xff0c;实现了一个小型、快速、独立、高可靠性、功能齐全的SQL数据库引擎。SQLite文件格式稳定、跨平台且向后兼容。SQLite源代码属于公共领域(public-domain)&#xff0c;任何人都可以免费将其用于任何目的。源码地址&#xff1a;https://github.com/…

【大咖云集,院士出席 | ACM独立出版】第四届大数据、人工智能与风险管理国际学术会议 (ICBAR 2024,11月15-17日)--冬季主会场

第四届大数据、人工智能与风险管理国际学术会议 (ICBAR 2024)--冬季主会场 2024 4th International Conference on Big Data, Artificial Intelligence and Risk Management 官方信息 会议官网&#xff1a;www.icbar.net 2024 4th International Conference on Big Data, Art…

图像算法之 OCR 识别算法:原理与应用场景

一、引言 在当今数字化时代&#xff0c;图像信息的处理和识别变得越来越重要。光学字符识别&#xff08;Optical Character Recognition&#xff0c;OCR&#xff09;算法作为一种能够将图像中的文字转换为可编辑文本的技术&#xff0c;正广泛应用于各个领域。从文档数字化到自…

SQLite的BLOB数据类型与C++二进制存储学习记录

一、BLOB数据类型简介 Blob&#xff08;Binary Large Object&#xff09;是一种用于存储二进制数据的数据类型&#xff0c;在数据库中常用于存储图片、音频和视频等大型&#xff08;大数据量&#xff09;的二进制数据[1-2]。需要注意的是&#xff0c;SQLite中BLOB类型的单对象最…

python基础——05函数

一、函数 1.1 函数定义 函数定义&#xff1a;实现特定功能的代码块 函数的作用&#xff1a; 简化代码提高代码重用性便于维护和修改可提高代码的可拓展性 函数三要素&#xff1a;功能、参数、返回值 函数定义的语法格式&#xff1a; 函数分类&#xff1a; 从定义的角度—…

[Redis] Redis哨兵机制

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…