rtt+nimble揭秘系列——controller(7)

多角度学习controller,uml还不熟练,欢迎斧正。

前言

只学习slave部分,master可以根据slave的思路去看。

目录

1. 伪系统框图

笔者觉得正常的系统框图不能表现每个组件之间的关系,所以加上一些箭头来表示controller涉及到的组件,箭头指向被调用的组件

2. 用例图

用用例图简单描述系统的功能需求是一个不错的工具,controller的功能比图中的要多,但是我们只针对图中的几个重点功能展开学习,其他细枝末节有需要再看。

3. 类图

  • ble_ll_sched

芯片的射频收发器只有一个,但是ble支持多链路共存,就会存在不同链路竞争同一个射频收发器的情况,这时候就需要一个调度器来做仲裁者的角色,决定某个时刻的射频资源释放给哪个链路,这个就是“射频时间片调度器”。

  • ble_ll_conn和ble_ll_conn_sm

其中一种竞争射频收发器的链路就是“连接链路”;那么这些连接链路有什么异同呢?相同的地方就是这些链路收发数据的方法,断开连接的方法都是通用的,差异的地方就是每个链路的连接参数、跳频表、状态标示位等是不一样的。

所以把ble_ll_conn看成是ble_ll_conn_sm类的方法集合,而ble_ll_conn_sm就是包含不同属性的实例。

  • ble_ll_adv和ble_ll_adv_sm

另外一种竞争射频收发器的链路就是“广播链路”;同上,但是目前不讨论ble5.0的情况,所以不会同时存在两条广播链路,即只有一个ble_ll_adv_sm实例。

4. 状态图

ble4.1之后链路层支持多链路共存,每个链路都有可能处于上图5个状态中的1个,在协议栈刚初始化完成时,每个链路都处于默认状态,也就是STANDBY状态,通过下面的状态图来了解默认状态下的链路是如何转换成广播链路连接链路的。

作图工具是Quantum Leaps,LLC公司的产品——qm,有兴趣的可以看我github之前做的简介。

因为复杂,所以笔者根据个人理解做了一些简化,UML图中部分语法会与实际源码有所违背,但是整体框架是一样的,实际应以源码为准。

  • 广播链路

实际上广播链路还有很多细枝末节,但是这里只抓重点了解,所以通过上面的状态图可分析的有限场景如下:

  1. STANDBY状态下host通过hci调用ble_ll_adv_sm_start启动广播
  2. 广播状态下,收到无效包
  3. 广播状态下,收到扫描请求包,发送扫描响应包
  4. 广播状态下,收到连接请求包
  5. 在一个广播事件中,切换下一个广播通道
  6. 当前广播事件结束,切换下一个广播事件
  7. 在各个状态下host通过hci调用ble_ll_adv_sm_stop停止广播
  • 连接链路

实际上连接链路还有很多细枝末节,但是这里只抓重点了解,所以通过上面的状态图可分析的有限场景如下:

  1. 创建连接成功,但建立连接失败
  2. 应答和流控机制
  3. 无上层数据发送,即发送EMPTY PDU
  4. 有上层数据发送,即发送L2CAP message
  5. 收到peer有效数据包,发送到上层
  6. 在一个连接事件中,切换TX/RX
  7. 当前连接事件结束,切换下一个连接事件
  8. supervision超时断开

5. 时序图

推荐wnnwoo前辈的nimble相关文章,图本并茂分析的很好。

6. MISC

  • 关于从射频时间片调度器申请到的时间片

一个时间片用一个“广播事”或“连接事件”来表述,每个事件中可能包含一个或多个发送、接收射频数据的过程,比如:某个广播事件从调度器申请到t1-t2时刻的射频资源,那么在t1-t2期间既有发送广播包,也有接收扫描请求包和接收连接请求包的过程。

7. 总结

controller确实复杂,理解起来难免忽略了许多细节,但是无碍,这次学习nimble了解controller的实现细节目的达到了,以后工作中遇到什么问题,也应该知道怎么在源码中找到答案了。

关于host部分以后有时间再看吧,估计最近都不会花太多时间在nimble上了,毕竟又有了新的学习目标了哈哈哈。

“如果觉得还不错,请我喝杯咖啡吧~”