开始实现蓝牙,先新建工程,使用 Zephyr 自带的 peripheral 示例模板

之后编译,调试报错了

MCXW71 是一个三核心平台,集成了 Cortex-M33 应用核心 (CM33)、专用的 Cortex-M3 射频核心以及一个隔离的 EdgeLock 安全区域。该射频核心也被称为窄带单元 (NBU),其特点是带有一个专用闪存的低功耗蓝牙 (LE) 单元。NBU 中集成的存储器包含蓝牙 LE 控制器协议栈和射频驱动程序。在 MCXW71 上,只有启动 ROM 能够访问 NBU 闪存。ROM 引导加载程序提供了一种在系统编程 (ISP) 工具,该工具通过微控制器单元 (MCU) 上的串行连接运行。
原文:FRDM-MCXW71: Hands On 1: NBU and User Firmware Update Using ISP
我们的程序在CM33,目前缺失NBU固件,所以CM33 核心无法与 NBU 核心通信,蓝牙协议栈初始化失败,触发了系统断言,现在需要下载NBU固件。
1,先找到固件文件(.sb3)
开始在Zephyr的仓库里面找,没有找到,然后就去MCUXpresso SDK 找,之前使用IDE下载的SDK压缩包继续派上用场,路径为:D:\nxp\SDK\SDK_25_12_00_FRDM-MCXW71.zip\middleware\wireless\ble_controller\bin

mcxw71_nbu_ble_hosted.sb3 标准 BLE 5.3 控制器固件,支持常规 BLE 功能。适合大多数普通蓝牙应用。
mcxw71_nbu_ble_hadm_hosted.sb3 包含对通道探测 (Channel Sounding) 功能的支持。
mcxw71_nbu_ble_xp_hosted.sb3 包含 DBAF 和 ACS 等实验性功能。
对于当前的 peripheral 示例和一般的蓝牙开发,选择 mcxw71_nbu_ble_hosted.sb3 即可。
2,下载固件,借鉴了灰灰灰123 的帖子- 【e起DIY】【过程帖】低功耗蓝牙温湿度计 - Zephyr蓝牙透传数据-电子产品世界论坛
官网也有指导教程,只是使用 SPSDK 。 Updating NBU for Wireless Examples — MCUXpresso SDK Documentation
先让开发板进入 ISP 模式 即 断开开发板的 USB 线(完全断电),然后按住 SW3 (ISP) 按键不放,同时重新连接 USB 线,等待 2-3 秒后,松开 SW3。如果没有进入这个模式下载,报错

正常如下

下载固件成功之后,再debug,然后使用手机蓝牙低功耗调试app,连接该蓝牙,蓝牙名字可以在prj.conf中修改


输出log,MTU = 23 意味着:单次传输的有效数据最多 20 字节,因为23字节要减去3字节的ATT协议头。超出会分段接收,虽然可以修改MTU或者接收完再合并,但是后续的传输温湿度数据的协议也不超过20字节,所以不做优化了
*** Booting Zephyr OS build v4.4.0 *** [00:00:00.046,722] <inf> fs_nvs: 8 Sectors of 8192 bytes [00:00:00.046,722] <inf> fs_nvs: alloc wra: 0, 1f40 [00:00:00.046,752] <inf> fs_nvs: data wra: 0, 90 [00:00:00.070,281] <inf> bt_hci_core: No ID address. App must call settings_load() Bluetooth initialized Bluetooth initialized [00:00:00.070,495] <inf> bt_hci_core: HCI transport: BT NXP [00:00:00.070,556] <inf> bt_hci_core: Identity: 00:60:37:EA:3F:39 (public) [00:00:00.070,587] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x8300, manufacturer 0x0025 [00:00:00.070,587] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x1400 Advertising successfully started Indicate VND attr 0x1001c404 (UUID 12345678-1234-5678-1234-56789abcdef1) Updated MTU: TX: 23 RX: 23 bytes Connected Passkey for 60:EB:B9:93:43:43 (random): 829353
3,简化程序,一个自定义服务与一个支持读写的特征,把电池服务 (BAS) 及相关通知函数,心率服务 (HRS) 及相关模拟函数,当前时间服务 (CTS) 及相关回调,即时警报服务 (IAS) 及相关回调,认证/加密相关的特征和回调,长特征、写命令特征等额外特征,CCC描述符(不需要指示功能),GATT MTU更新回调都移除
#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/kernel.h>
#include <zephyr/settings/settings.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
// 自定义服务UUID (128-bit)
#define BT_UUID_CUSTOM_SERVICE_VAL \
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)
// 自定义特征UUID (128-bit)
#define BT_UUID_CUSTOM_CHAR_VAL \
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)
// 定义UUID结构体
static const struct bt_uuid_128 vnd_svc_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_SERVICE_VAL);
static const struct bt_uuid_128 vnd_char_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_CHAR_VAL);
// 特征值最大长度
#define VND_MAX_LEN 20
// 特征值存储
static uint8_t vnd_value[VND_MAX_LEN + 1] = {0};
// 读取特征值回调
static ssize_t read_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
{
const char *value = attr->user_data;
printk("Read request received\n");
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, strlen(value));
}
// 写入特征值回调
static ssize_t write_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags)
{
uint8_t *value = attr->user_data;
if (offset + len > VND_MAX_LEN)
{
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}
memcpy(value + offset, buf, len);
value[offset + len] = 0;
printk("Write request received, data: %s\n", value);
return len;
}
// 定义GATT服务(只包含一个读写特征)
BT_GATT_SERVICE_DEFINE(vnd_svc,
BT_GATT_PRIMARY_SERVICE(&vnd_svc_uuid.uuid),
BT_GATT_CHARACTERISTIC(&vnd_char_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
read_vnd, write_vnd, vnd_value),
);
// 广播数据
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_CUSTOM_SERVICE_VAL),
};
// 扫描响应数据
static const struct bt_data sd[] = {
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};
// 连接回调
static void connected(struct bt_conn *conn, uint8_t err)
{
if (err)
{
printk("Connection failed, err 0x%02x %s\n", err, bt_hci_err_to_str(err));
}
else
{
printk("Connected\n");
}
}
// 断开连接回调
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason));
}
// 注册连接回调
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
};
// 蓝牙初始化完成回调
static void bt_ready(void)
{
int err;
printk("Bluetooth initialized\n");
if (IS_ENABLED(CONFIG_SETTINGS))
{
settings_load();
}
// 启动广播
err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err)
{
printk("Advertising failed to start (err %d)\n", err);
return;
}
printk("Advertising successfully started\n");
}
int main(void)
{
int err = 0;
// 初始化蓝牙
err = bt_enable(NULL);
if (err != 0)
{
printk("Bluetooth init failed (err %d)\n", err);
return 0;
}
bt_ready();
// 初始化特征值
strcpy(vnd_value, "Hello");
while (1)
{
k_sleep(K_SECONDS(1));
}
return 0;
}
*** Booting Zephyr OS build v4.4.0 *** [00:00:00.046,325] <inf> fs_nvs: 8 Sectors of 8192 bytes [00:00:00.046,325] <inf> fs_nvs: alloc wra: 0, 1e10 [00:00:00.046,325] <inf> fs_nvs: data wra: 0, 210 [00:00:00.066,497] <inf> bt_hci_core: No ID address. App must call settings_load() Bluetooth initialized [00:00:00.067,169] <inf> bt_hci_core: HCI transport: BT NXP [00:00:00.067,199] <inf> bt_hci_core: Identity: 00:60:37:EA:3F:39 (public) [00:00:00.067,230] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x8300, manufacturer 0x0025 [00:00:00.067,260] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x1400 Advertising successfully started [00:00:07.025,054] <inf> bas: BAS Notifications enabled Connected Write request received, data: 225855668875558
我要赚赏金
