马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
假如你刚开始打仗 Nordic 的 nRF52 或 nRF53 系列芯片,你大概会发如今烧录步伐时,除了你自己的应用步伐(Application),通常还须要烧录一个名为 SoftDevice 的大文件。这不但是一个蓝牙协议栈库,它更像是一个霸道的“微内核”。它担当了芯片最核心的资源,以致把你(开辟者)的代码“赶”到了低特权级运行。**
为什么 Nordic 要计划这种看似复杂的布局?它又是怎样包管你的代码和协议栈宁静共处的?本日这篇博文,我们将揭开 SoftDevice 的秘密面纱。
1. 什么是 SoftDevice?不但仅是库文件
在传统的单片机开辟中,假如我们想利用一个功能(好比驱动屏幕或读取传感器),通常会包罗一个 .h 头文件,链接一个 .lib 库,然后直接调用内里的函数。
但 SoftDevice 差别。它是一个预编译好的、二进制格式的协议栈,位于芯片 Flash 的固定位置。你可以把它想象成操纵体系中的内核 (Kernel),而你的应用步伐则是运行在用户空间 (User Space) 的步伐:
- 特权级: SoftDevice 运行在更高的 CPU 特权级,它独占了射频 (Radio) 和核心定时器。
- 掩护性: 它掩护自己不被用户代码随意访问或粉碎。
- 实时性: 无论你的步伐在做什么,一旦蓝牙时序到来,SoftDevice 会强行打断你,优先处理惩罚蓝牙信号。
2. 它们怎样沟通?(SVC 调用机制与 SWI 软件克制)
以蓝牙广播为例,应用步伐怎样哀求 SoftDevice 开始蓝牙广播呢?答案是:SVC (Supervisor Call,管理调用)。
在 softdevice 提供的头文件内界说了一系列 SVC 的克制号:- enum BLE_GAP_SVCS
- {
- SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */
- ...
- SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */
- ...
- };
复制代码 想象 SoftDevice 是司理,你的 App 是员工。员工不能直接冲进司理办公室操纵电脑,必须提交一份“申请单”。
- 发起哀求: 当你在代码中调用 sd_ble_gap_adv_start() 时,你并不是直接实验广播代码,而是实验了 SVC 中克制。
sd_ble_gap_adv_start() 函数,把干系宏界说睁开后可以得到如下情势:
- _Pragma("GCC diagnostic push")
- _Pragma("GCC diagnostic ignored "-Wreturn-type"") // 由于是汇编函数,不包含return指令,需要防止编译器报错
- __attribute__((naked)) // 函数编译时都会自动生成push(入栈)出栈(操作)指令。naked关键字让编译器不要生成这些指令,由用户自己实现
- __attribute__((unused))
- static uint32_t sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)
- {
- __asm(
- "svc %0\n" // 将 SD_BLE_GAP_ADV_START 编号作为立即数放入 SVC 指令
- "bx r14"// 函数返回,将控制权交还给调用者
- : /* 输出操作数 */
- : /* 输入操作数 */ "I" (GCC_CAST_CPP SD_BLE_GAP_ADV_START) /* SVC 编号 */
- : "r0" /* 临时寄存器,表示 SoftDevice 会使用 R0 寄存器作为返回值 */
- );
- }
- _Pragma("GCC diagnostic pop")
复制代码
- 特权切换: SVC 指令会触发一个硬件非常(软克制)。CPU 瞬间停息你的步伐,从用户模式切换到特权模式,进入 SoftDevice 中的 SVC_Handler。
- 内核处理惩罚: 控制权移交给 SoftDevice 的克制处理惩罚步伐。它查抄你的哀求,确认参数无误后,操纵底层硬件开启广播。
- 返回结果: 处理惩罚完毕后,SoftDevice 将结果返回给你,CPU 切回用户模式,你的步伐继承向下实验。
这种机制包管了安全性:用户步伐永世无法直打仗碰底层硬件,必须通过“正规渠道”申请。
反过来,SoftDevice 怎样关照应用步伐呢?
- 产生事故并关照: 当蓝牙毗连创建时,SoftDevice 天生一个 BLE_GAP_EVT_CONNECTED 事故数据包,把它丢进一个共享的收件箱”(事故队列),然后产生一个软件克制 SD_EVT_IRQn 来关照应用步伐。
- // SoftDevice 内部(伪代码)
- void softdevice_internal_ble_event_handler(void)
- {
- // 1. BLE 事件发生(如连接、断开、数据接收)
- ble_evt_t evt;
- evt.header.evt_id = BLE_GAP_EVT_CONNECTED;
- // ... 填充事件数据
-
- // 2. 将事件放入 SoftDevice 内部队列
- sd_internal_event_queue_push(&evt);
-
- // 3. 触发软件中断通知应用程序
- NVIC_SetPendingIRQ(SD_EVT_IRQn); // 触发 SWI2 中断
- }
复制代码
- 提取处理惩罚: 你的应用步伐在主循环中醒来,调用 sd_ble_evt_get()(这也是一个 SVC 调用),从“收件箱”里取出信件,然后根据事故范例实验相应的逻辑(好比亮起 LED 灯)。
- // 简化的事件处理伪代码
- nrf_sdh_ble_evts_poll()
- {
- while (true) {
- // 获取事件
- sd_ble_evt_get(p_ble_evt);
-
- // 检查事件
- switch (p_ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED:
- // 处理连接
- break;
- case BLE_GAP_EVT_DISCONNECTED:
- // 处理断开
- break;
- }
- }
- }
复制代码 将上面的流程化成流程图如下:
sequenceDiagram autonumber participant App as 用户步伐 (Application)
Thread Mode / Low Priority participant SVC as SVC 接口
(Exception Boundary) participant SD as SoftDevice (内核)
Handler Mode / High Priority participant HW as 硬件 (Hardware)
Radio / Timer / NVIC %% 场景一:用户自动调用 (SVC Call) rect rgb(230, 245, 255) note over App, HW: 场景 1: 用户步伐哀求服务 (比方:开启广播) App->>SVC: 调用 sd_ble_gap_adv_start() activate SVC note right of App: 触发 SVC 克制
CPU 切入特权模式 SVC->>SD: 转达 SVC 编号 & 参数 activate SD SD->>HW: 设置 Radio 寄存器 SD-->>SVC: 返回实验结果 (NRF_SUCCESS) deactivate SD SVC-->>App: 返回函数调用 deactivate SVC note left of App: CPU 切回用户模式
步伐继承实验 end %% 场景二:事故关照 (Event) rect rgb(255, 240, 230) note over App, HW: 场景 2: SoftDevice 关照用户 (比方:创建毗连) HW->>SD: 硬件克制 (Radio IRQ) activate SD SD->>SD: 天生事故 (EVT_CONNECTED)
放入事故队列 SD->>App: 触发 SD_EVT_IRQn (SWI软件克制) 关照应用 deactivate SD note left of App: 应用被克制叫醒
进入事故处理惩罚函数 App->>SVC: 调用 sd_ble_evt_get() activate SVC SVC->>SD: 哀求获取队列中的事故 activate SD SD-->>SVC: 返回事故数据布局 deactivate SD SVC-->>App: 返回事故数据 deactivate SVC App->>App: switch (evt_id) { case CONNECTED... } end4. 为什么要这么贫困?
这种应用与协议栈分离的计划固然增长了学习资本,但带来了巨大的利益:
- 极致的稳固性: 无论你的应用步伐写得多么烂(死循环、野指针),SoftDevice 都有硬件掩护机制(MPU),大概率能包管蓝牙毗连不停开。
- 简化的认证: 由于底层的 RF 协议栈是预编译且不可修改的,Nordic 已经帮它过了许多法规认证。只要你不动射频参数,过 FCC/CE 认证会轻易得多。
- 零时序负担: 你不须要在大循环里盘算蓝牙跳频的时间,也不消担心处理惩罚传感器数据太慢导致蓝牙掉线。SoftDevice 会自动通过高优先级克制处理惩罚全部时序敏感的任务。
|