当前位置: 首页 > wzjs >正文

郑州建设网站定制惠州人才市场最新招聘信息网

郑州建设网站定制,惠州人才市场最新招聘信息网,电子商务就业前景和就业方向,嘉定网站建设电脑培训目录 概述 1 系统架构 2 代码结构详解 2.1 初始化代码结构 2.2 主循环函数 2.3 错误处理函数 3 代码介绍 3.1 初始化参数代码 3.2 BT_CONN_CB_DEFINE函数 3.2.1 remote_info_available_cb函数 3.2.2 connected_cb函数 3.2.3 disconnected_cb函数 3.3 bt_le_ext_ad…

目录

概述

1 系统架构

2 代码结构详解

2.1 初始化代码结构

2.2  主循环函数

 2.3 错误处理函数

3 代码介绍

3.1 初始化参数代码

 3.2 BT_CONN_CB_DEFINE函数

3.2.1  remote_info_available_cb函数

3.2.2  connected_cb函数

3.2.3 disconnected_cb函数

3.3 bt_le_ext_adv_create函数

 

3.3.1 request_cb()函数

3.3.2 response_cb()函数

 3.4 bt_le_scan_start()函数

3.4 bt_gatt_discover函数

3.5 bt_gatt_write函数

3.7 错误处理功能

4 源代码文件

5 系统测试


概述

本文介绍了基于Zephyr RTOS的蓝牙周期性广播系统架构与实现。系统采用三部分设计:初始化部分完成蓝牙连接接口、广播参数设置及启动功能;主循环实现设备发现、数据传输和GATT操作;错误处理模块管理连接状态。关键技术包括:通过bt_le_ext_adv_create创建广播接口,使用bt_le_per_adv_start启动周期性广播,利用信号量机制(sem_connected/sem_disconnected)监控连接状态,并实现GATT数据写入(bt_gatt_write)和特征发现(bt_gatt_discover)功能。系统通过request_cb和response_cb回调函数处理广播数据请求与响应,支持多子事件和响应时隙配置,适用于需要低功耗周期性数据传输的物联网场景。

1 系统架构

系统分的软件设计分为3个部分:

-1)Initial(): 蓝牙连接接口函数,广播相关函数初始化,启动广播功能

-2) while(1){}: 主循环函数,实现发现BLE设备,设置传输的信息,GATT功能

-3)错误处理部分

2 代码结构详解

2.1 初始化代码结构

1) BT_CONN_CB_DEFINE,定义蓝牙连接相关的回调函数

2) init_bufs, 初始化发送的数据

3)bt_le_ext_adv_create(), 创建广播接口

4)bt_le_per_adv_set_param(),设置广播参数

5)bt_le_per_adv_start(),启动周期广播函数

6)bt_le_ext_adv_start(), 使能扩展广播功能

2.2  主循环函数

1)bt_le_scan_start(),开启连续扫描功能

2)k_sem_take(&sem_connected, K_FOREVER),监测蓝牙连接状态

3)bt_le_per_adv_set_info_transfer(),设置广播数据传输

4)bt_gatt_discover(),发现GATT设备

5) k_sem_take(&sem_discovered, K_SECONDS(10)), 监测设备连接的信号量

6)bt_gatt_write(),GATT方式写数据

7)k_sem_take(&sem_written, K_SECONDS(10));监测写数据是否完成 

 2.3 错误处理函数

1)bt_conn_disconnect(), 断开蓝牙连接

2) k_sem_take(&sem_disconnected, K_FOREVER); 监测断开蓝牙设备连接的信号量

3 代码介绍

3.1 初始化参数代码

代码13~16行:定义基本参数

代码18~21行: 定义系统中使用的信号量

代码23行:定义系统的UUID参数

 代码28~37行: 定义广播的参数

 3.2 BT_CONN_CB_DEFINE函数

3.2.1  remote_info_available_cb函数

代码第130行:发送BLE连接的信号量

3.2.2  connected_cb函数

3.2.3 disconnected_cb函数

3.3 bt_le_ext_adv_create函数

该函数主要调用request_cb和response_cb函数

3.3.1 request_cb()函数

代码56~65函数:填充数据参数

代码67行:设置广播的数据

3.3.2 response_cb()函数

代码96行: 解析收到的广播数据

 3.4 bt_le_scan_start()函数

 代码271函数:在bt_le_scan_start函数中调用device_found

device_found函数的内容:

代码173行: 调用data_cb解析数据

代码179行: 停止BLE

代码183行:重新创建连接

data_cb函数的内容

3.4 bt_gatt_discover函数

代码321行:注册discover_func函数

代码325行: 调用bt_gatt_discover函数,执行数据处理

 discover_func函数的内容

3.5 bt_gatt_write函数

代码351行:调用bt_gatt_write,执行写数据功能

代码361行:等待写数据完成

3.7 错误处理功能

代码378行: 断开蓝牙连接功能

代码383行: 获取BT断开的信号量 

4 源代码文件

/** Copyright (c) 2023 Nordic Semiconductor ASA** SPDX-License-Identifier: Apache-2.0*/#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>#define NUM_RSP_SLOTS 5
#define NUM_SUBEVENTS 5
#define PACKET_SIZE   5
#define NAME_LEN      30static K_SEM_DEFINE(sem_connected, 0, 1);
static K_SEM_DEFINE(sem_discovered, 0, 1);
static K_SEM_DEFINE(sem_written, 0, 1);
static K_SEM_DEFINE(sem_disconnected, 0, 1);static struct bt_uuid_128 pawr_char_uuid =BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1));static uint16_t pawr_attr_handle;static const struct bt_le_per_adv_param per_adv_params = {.interval_min = 0xFF,.interval_max = 0xFF,.options = 0,.num_subevents = NUM_SUBEVENTS,.subevent_interval = 0x30,.response_slot_delay = 0x5,.response_slot_spacing = 0x50,.num_response_slots = NUM_RSP_SLOTS,
};static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS];
static struct net_buf_simple bufs[NUM_SUBEVENTS];
static uint8_t backing_store[NUM_SUBEVENTS][PACKET_SIZE];BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params));
BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params));static uint8_t counter;static void request_cb(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_data_request *request)
{int err;uint8_t to_send;struct net_buf_simple *buf;to_send = MIN(request->count, ARRAY_SIZE(subevent_data_params));for (size_t i = 0; i < to_send; i++) {buf = &bufs[i];buf->data[buf->len - 1] = counter++;subevent_data_params[i].subevent =(request->start + i) % per_adv_params.num_subevents;subevent_data_params[i].response_slot_start = 0;subevent_data_params[i].response_slot_count = NUM_RSP_SLOTS;subevent_data_params[i].data = buf;}err = bt_le_per_adv_set_subevent_data(adv, to_send, subevent_data_params);if (err) {printk("Failed to set subevent data (err %d)\n", err);} else {printk("Subevent data set %d\n", counter);}
}static bool print_ad_field(struct bt_data *data, void *user_data)
{ARG_UNUSED(user_data);printk("    0x%02X: ", data->type);for (size_t i = 0; i < data->data_len; i++) {printk("%02X", data->data[i]);}printk("\n");return true;
}static struct bt_conn *default_conn;static void response_cb(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info,struct net_buf_simple *buf)
{if (buf) {printk("Response: subevent %d, slot %d\n", info->subevent, info->response_slot);bt_data_parse(buf, print_ad_field, NULL);}
}static const struct bt_le_ext_adv_cb adv_cb = {.pawr_data_request = request_cb,.pawr_response = response_cb,
};void connected_cb(struct bt_conn *conn, uint8_t err)
{printk("Connected (err 0x%02X)\n", err);__ASSERT(conn == default_conn, "Unexpected connected callback");if (err) {bt_conn_unref(default_conn);default_conn = NULL;}
}void disconnected_cb(struct bt_conn *conn, uint8_t reason)
{printk("Disconnected, reason 0x%02X %s\n", reason, bt_hci_err_to_str(reason));bt_conn_unref(default_conn);default_conn = NULL;k_sem_give(&sem_disconnected);
}void remote_info_available_cb(struct bt_conn *conn, struct bt_conn_remote_info *remote_info)
{/* Need to wait for remote info before initiating PAST */k_sem_give(&sem_connected);
}BT_CONN_CB_DEFINE(conn_cb) = {.connected = connected_cb,.disconnected = disconnected_cb,.remote_info_available = remote_info_available_cb,
};static bool data_cb(struct bt_data *data, void *user_data)
{char *name = user_data;uint8_t len;switch (data->type) {case BT_DATA_NAME_SHORTENED:case BT_DATA_NAME_COMPLETE:len = MIN(data->data_len, NAME_LEN - 1);memcpy(name, data->data, len);name[len] = '\0';return false;default:return true;}
}static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,struct net_buf_simple *ad)
{char addr_str[BT_ADDR_LE_STR_LEN];char name[NAME_LEN];int err;if (default_conn) {return;}/* We're only interested in connectable events */if (type != BT_GAP_ADV_TYPE_ADV_IND && type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {return;}(void)memset(name, 0, sizeof(name));bt_data_parse(ad, data_cb, name);if (strcmp(name, "PAwR sync sample")) {return;}if (bt_le_scan_stop()) {return;}err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT,&default_conn);if (err) {printk("Create conn to %s failed (%u)\n", addr_str, err);}
}static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params)
{struct bt_gatt_chrc *chrc;char str[BT_UUID_STR_LEN];printk("Discovery: attr %p\n", attr);if (!attr) {return BT_GATT_ITER_STOP;}chrc = (struct bt_gatt_chrc *)attr->user_data;bt_uuid_to_str(chrc->uuid, str, sizeof(str));printk("UUID %s\n", str);if (!bt_uuid_cmp(chrc->uuid, &pawr_char_uuid.uuid)) {pawr_attr_handle = chrc->value_handle;printk("Characteristic handle: %d\n", pawr_attr_handle);k_sem_give(&sem_discovered);}return BT_GATT_ITER_STOP;
}static void write_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params)
{if (err) {printk("Write failed (err %d)\n", err);return;}k_sem_give(&sem_written);
}void init_bufs(void)
{for (size_t i = 0; i < ARRAY_SIZE(backing_store); i++) {backing_store[i][0] = ARRAY_SIZE(backing_store[i]) - 1;backing_store[i][1] = BT_DATA_MANUFACTURER_DATA;backing_store[i][2] = 0x59; /* Nordic */backing_store[i][3] = 0x00;net_buf_simple_init_with_data(&bufs[i], &backing_store[i],ARRAY_SIZE(backing_store[i]));}
}#define MAX_SYNCS (NUM_SUBEVENTS * NUM_RSP_SLOTS)
struct pawr_timing {uint8_t subevent;uint8_t response_slot;
} __packed;static uint8_t num_synced;int main(void)
{int err;struct bt_le_ext_adv *pawr_adv;struct bt_gatt_discover_params discover_params;struct bt_gatt_write_params write_params;struct pawr_timing sync_config;init_bufs();printk("Starting Periodic Advertising Demo\n");/* Initialize the Bluetooth Subsystem */err = bt_enable(NULL);if (err) {printk("Bluetooth init failed (err %d)\n", err);return 0;}/* Create a non-connectable advertising set */err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, &adv_cb, &pawr_adv);if (err) {printk("Failed to create advertising set (err %d)\n", err);return 0;}/* Set periodic advertising parameters */err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params);if (err) {printk("Failed to set periodic advertising parameters (err %d)\n", err);return 0;}/* Enable Periodic Advertising */printk("Start Periodic Advertising\n");err = bt_le_per_adv_start(pawr_adv);if (err) {printk("Failed to enable periodic advertising (err %d)\n", err);return 0;}printk("Start Extended Advertising\n");err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT);if (err) {printk("Failed to start extended advertising (err %d)\n", err);return 0;}while (num_synced < MAX_SYNCS) {/* Enable continuous scanning */err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_CONTINUOUS, device_found);if (err) {printk("Scanning failed to start (err %d)\n", err);return 0;}printk("Scanning successfully started\n");k_sem_take(&sem_connected, K_FOREVER);err = bt_le_per_adv_set_info_transfer(pawr_adv, default_conn, 0);if (err) {printk("Failed to send PAST (err %d)\n", err);goto disconnect;}printk("PAST sent\n");discover_params.uuid = &pawr_char_uuid.uuid;discover_params.func = discover_func;discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;err = bt_gatt_discover(default_conn, &discover_params);if (err) {printk("Discovery failed (err %d)\n", err);goto disconnect;}printk("Discovery started\n");err = k_sem_take(&sem_discovered, K_SECONDS(10));if (err) {printk("Timed out during GATT discovery\n");goto disconnect;}sync_config.subevent = num_synced % NUM_SUBEVENTS;sync_config.response_slot = num_synced / NUM_RSP_SLOTS;num_synced++;write_params.func = write_func;write_params.handle = pawr_attr_handle;write_params.offset = 0;write_params.data = &sync_config;write_params.length = sizeof(sync_config);err = bt_gatt_write(default_conn, &write_params);if (err) {printk("Write failed (err %d)\n", err);num_synced--;goto disconnect;}printk("Write started\n");err = k_sem_take(&sem_written, K_SECONDS(10));if (err) {printk("Timed out during GATT write\n");num_synced--;goto disconnect;}printk("PAwR config written to sync %d, disconnecting\n", num_synced - 1);disconnect:/* Adding delay (2ms * interval value, using 2ms intead of the 1.25ms* used by controller) to ensure sync is established before* disconnection.*/k_sleep(K_MSEC(per_adv_params.interval_max * 2));err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);if (err) {return 0;}k_sem_take(&sem_disconnected, K_FOREVER);}printk("Maximum numnber of syncs onboarded\n");while (true) {k_sleep(K_SECONDS(1));}return 0;
}

5 系统测试

编译代码下载至nRFDK-52832板卡中,运行结构如下:

 

http://www.dtcms.com/wzjs/811483.html

相关文章:

  • 东莞营销型高端网站建设网站如何申请微信支付功能
  • 网站服务器租用一年多少钱啊网络营销工具的作用
  • 网站绩效营销赣榆哪里有做网站的
  • 台州市临海建设局网站怎么把自己的网站推广
  • 电子商务网站规划与建设的论文企业信用
  • 怎样免费做彩票网站网站顶部公告代码
  • 网站域名选择的原则如何充实网站内容
  • 电商网站推广方法网站建设编程时注意事项
  • 数据分析对网站建设的重要性wordpress教程哪本好
  • 成都万商云集做网站怎么样ios应用程序开发
  • php宠物用品公司网站源码广州怎么做网站
  • 楼盘网站建设短视频seo公司
  • 艺术风格网站杭州亚运村建设指挥部网站
  • 淘宝网站做超链接吉林市做网站的公司哪家好
  • 网站设计制作什么时候好万峰科技.jsp网站开发四酷全书[m]
  • 中国响应式网站有哪些最新发布的最新
  • 网站左侧悬浮wordpress 中文网站
  • 网站的导航栏东宁做木耳招工人网站
  • 成都网站制作建设网站建设需求怎么提
  • 华强北手机网站建设seo软件安卓版
  • asp化妆品网站 后台网站轮播效果
  • 网站开发验收申请报告中国网络安全公司排名
  • 专业的网站开发建访网站建设与管理 ppt
  • 网站建设的投资必要性企业网站常见问题
  • 有哪些公司的网站设计的好做公司企业网站标准尺寸
  • 外贸产品网站建设放心营销网站开发
  • 中国那个公司的网站做的最好看做网站难还是app
  • 华为云网站定制影视app搭建教程
  • 温州集团网站建设正规网站建设空间
  • 鹿寨县住房和城乡建设局网站郑州网站建设预订