基于ESP32的nimble-host蓝牙协议栈移植分析

2023-05-16

ESP32蓝牙协议栈NIMBLE-HOST协议移植分析

目录

ESP32蓝牙协议栈NIMBLE-HOST协议移植分析

一、 nimble 蓝牙协议栈介绍

二 、关于esp32移植的内容分析

2.1 关于/porting 目录移植

2.2 /nimble 目录移植

三、 根据ESP32-NIMBLE-blehr的例子分析程序流程

3.1 main()函数分析

3.2 移植实现的esp_nimble_hci文件进行分析


一、 nimble 蓝牙协议栈介绍

1、 蓝牙协议栈目录


关于nimble目录介绍可以参考链接:nimble协议栈源码目录介绍

二 、关于esp32移植的内容分析

我们最需要关心的是 /nimble 目录和 /porting 目录

2.1 关于/porting 目录移植

/porting /npl目录,主要是真的移植操作系统相关

其中移植nimble_npl_os.h文件中的rtos主要接口,移植其他操作系统就需要重新实现。
“freertos/queue.h”     //事件队列
“freertos/semphr.h” //信号量 ,互斥信号量
“freertos/task.h”      //任务
“freertos/timers.h”  //软件定时器  

部分中断临界区进入退出接口

针对 esp32采用freertos所以基本已经算移植好了,主要对部分接口进行适配,以及头文件进行修改优化。这部分改动较小

例如:

/porting /nimble 这个目录 也是针对平台进行适配,改动较大,这里针对主要系统进行说明

2.2 /nimble 目录移植

host 部分移植:

 - a) 主要针对,porting之前移植freertos 任务部分,内存管理接口等部分,

- b) mesh 安全算法部分

 -c) esp32 还有一些自定义优化部分

具体ESP32移植目录如下:

三、 根据ESP32-NIMBLE-blehr的例子分析程序流程

3.1 main()函数分析

void blehr_host_task(void *param)
{
    ESP_LOGI(tag, "BLE Host Task Started");
    /* This function will return only when nimble_port_stop() is executed */
    nimble_port_run();

    nimble_port_freertos_deinit();
}


void app_main(void)
{
    int rc;

    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init());  //HCI传输层初始化

    nimble_port_init();  //协议栈HOST初始化
    /* Initialize the NimBLE host configuration */
    ble_hs_cfg.sync_cb = blehr_on_sync;
    ble_hs_cfg.reset_cb = blehr_on_reset;

    /* name, period/time,  auto reload, timer ID, callback */
    blehr_tx_timer = xTimerCreate("blehr_tx_timer", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, blehr_tx_hrate);

    rc = gatt_svr_init(); //系统服务初始化
    assert(rc == 0);

    /* Set the default device name */
    rc = ble_svc_gap_device_name_set(device_name);
    assert(rc == 0);

    /* Start the task */
    nimble_port_freertos_init(blehr_host_task); //启动host任务

}

​       esp_nimble_hci_and_controller_init()//就是之前esp-hci中移植时实现的。

​       nimble_port_init() //初始化HOST协议栈相关事情

​       blehr_host_task() ->> nimble_port_run() //运行协议栈HOST程序线程

​       nimble_port_freertos_init(blehr_host_task)//是操作系统移植时实现的



3.2 移植实现的esp_nimble_hci文件进行分析

/*
HOST ----HCI---------CONTROLLER

HOST--->>CONTROLLER  : HCI-CMD  //移植采用esp32的发送接口 esp_vhci_host_send_packet    

CONTROLLER--->>> HOST :  HCI-EVENT,HCI-ACL  //移植采用controller回调接口协议栈HCI处理接口
*/

int ble_hci_trans_hs_cmd_tx(uint8_t *cmd)
{
    uint16_t len;
    uint8_t rc = 0;

    assert(cmd != NULL);
    *cmd = BLE_HCI_UART_H4_CMD;
    len = BLE_HCI_CMD_HDR_LEN + cmd[3] + 1;
    if (!esp_vhci_host_check_send_available()) {
        ESP_LOGD(TAG, "Controller not ready to receive packets");
    }

    if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
        esp_vhci_host_send_packet(cmd, len);
    } else {
        rc = BLE_HS_ETIMEOUT_HCI;
    }

    ble_hci_trans_buf_free(cmd);
    return rc;
}




esp_err_t esp_nimble_hci_and_controller_init(void)
{
    esp_err_t ret;

    esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();

    if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
        return ret;
    }

    if ((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
        return ret;
    }
    return esp_nimble_hci_init();
}

esp_err_t esp_nimble_hci_init(void)
{
    esp_err_t ret;

    ret = ble_buf_alloc();
    if (ret != ESP_OK) {
        goto err;
    }
    if ((ret = esp_vhci_host_register_callback(&vhci_host_cb)) != ESP_OK) {
        goto err;
    }

    ble_hci_transport_init();

    vhci_send_sem = xSemaphoreCreateBinary();
    if (vhci_send_sem == NULL) {
        ret = ESP_ERR_NO_MEM;
        goto err;
    }

    xSemaphoreGive(vhci_send_sem);

    return ret;
err:
    ble_buf_free();
    return ret;

}
esp_vhci_host_register_callback --->>vhci_host_cb
                     --->>ble_hci_trans_ll_evt_tx  回调HOST接口返回HOST协议处理
                     --->>ble_hci_rx_acl               回调HOST接口返回HOST协议处理
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于ESP32的nimble-host蓝牙协议栈移植分析 的相关文章

  • 【STM32 x ESP8266】连接 MQTT 服务器(报文,附部分源码解析)

    MQTT 协议作为物联网非常重要的传输协议 如何使用它十分重要 如果有不理解的同学可以点击这里学习 这里只是简单介绍一下 同时这里附上MQTT 3 1 1协议中文版 pdf 的链接 对协议底层感兴趣的同学可以下载学习一下 同时下面的实现函数
  • 单片机开发---ESP32S3移植lvgl+触摸屏

    书接上文 单片机开发 ESP32 S3模块上手 本章内容 熟悉一下ESP32S3的开发 修改范例程序的lvgl 使之能够匹配现在的显示屏 具体工作大概为通过SPI接口连接一块SPI串口屏幕 并且适配lvgl 最后加上触摸屏作为输入 屏幕 用
  • ESP32的液晶中文显示

    上一篇简单说明了ESP32进行SSD1306的液晶显示 然后希望显示字符 使用前一篇的SSD1306是一个入门 但是不能显示中文 因此本篇主要演示显示中文 在arduino中有一个u8g2库 当时用UNO时使用过该库 但是用在ESP32上
  • SiliconLab GSDK 4.2.2 创建 Z3Gateway 工程

    如题 在SSv5的My Product选项下 需要添加Linux 32 Bit 否则在Example Projects Demos中无法查找到zigbeegateway相关的demo My Product 中的内容添加成功后 再次搜索Exa
  • ESP32-S2应用开发——USB通信(CDC类)

    ESP32S2应用开发 USB通信 CDC类 目录 ESP32S2应用开发 USB通信 CDC类 前言 1 硬件介绍 1 1 硬件连接 2 软件开发 2 1 安装开发板 2 2 安装库 2 3 运行示例代码 2 4 USB传输速度测试 结束
  • esp32 CMT130-V1.0 PS 240*240屏幕使用方法实验

    1 安装好Arduino 1 8 13 注意尽量不要大于1 8的版本 2 安装esp32驱动代码并且配置 3 esp32选择波特率 921600 4 选择频率 80MHZ 5 具体连线总结 6 需要在Arduino库管理中心下载TFT eS
  • ESP32 的esp_http_client详解

    说明 我使用的是esp idf V3 1 3 官方给我们封装好了 HTTP 使用起来还是很方便 一 wifi连接 在main函数里面主要是做了wifi连接的初始化和HTTP任务的创建 如下是main的全部内容 void app main e
  • esp32-S3专题二:内存1之RAM使用

    esp32 S3模块内部的存储分为ROM RAM SPRAM RTC内存 FLASH 种类很多 几乎可以不使用外接存储器的情况下 可以进行很多业务场景 十分有用 现在我们逐一讲解一下他们的作用和使用方法 一 ROM 384 KB 内部 RO
  • SimpleFOC无刷电机平衡小车

    前言 本科毕业于自动化 期间学习了各种电机运动控制原理 自动控制原理 但是只会考试而未究其理 最近接触到simplefoc这个基于arduino的开源无刷电机驱动库 想正好借此机会将本科学到的内容用于实际 于是就有了这个小项目 基于无刷电机
  • 最快方式 ESP-IDF 创建例子 教程

    需要条件 安装了 VSCODE 安装了插件 Espressif IDF工具 系统中安装了 ESP IDF 可使用离线包 或在线安装包 在插件中配置了 ESP IDF 可能需要在线更新一些东西 点击F1 输入 ESP 等待提示 出现提示后 选
  • cmake中的编译选项

    CMake是一个跨平台的构建系统 它可以根据简单的配置文件生成各种平台的构建工具 例如Makefile Visual Studio项目文件等 CMake使用CMakeLists txt文件来描述项目的构建规则和依赖关系 在这个文件中 可以设
  • 在远程Linux主机上执行本地脚本

    我有一个本地脚本 如果没有远程主机上的 root 权限 该脚本将无法运行 我已编辑并允许 sudoers 文件从主目录 home username script 运行脚本 该脚本使用结果创建一个 txt 文件 但我将输出重定向到终端 并将输
  • Android USB主机:异步中断传输

    我正在尝试连接 USB 设备 我自己构建 来与我的开发板 ODROID X 进行通信 不幸的是 就异步通信而言 例子很少 我在中断驱动的数据交换方面遇到了一些问题 如何使用异步中断模式建立连接 在一个方向上 传输是可能的 但在两个方向上都不
  • 签名的小程序可以与它们所源自的不同主机连接吗?

    我需要一个小程序来打开套接字并与侦听的服务器进行通信 小程序下载到的本地主机 最终用户计算机 与我读到的有关小程序安全性的内容相反 似乎甚至签名的小程序 无法打开到下载它们的不同主机的套接字 在同一台机器上它工作得很好 我已经使用 self
  • 【ESP32接入国产大模型之文心一言】

    1 怎样接入文心一言 随着人工智能技术的不断发展 自然语言处理领域也得到了广泛的关注和应用 在这个领域中 文心一言作为一款强大的自然语言处理工具 具有许多重要的应用价值 本文将重点介绍如何通过ESP32接入国产大模型之文心一言api 以及其
  • ADXL345 与 ESP32 I2C 垃圾值问题

    我已根据以下教程使用 I2C 接口将 ESP32 与 ADXL345 连接起来Tutorial http www esp32learning com code esp32 and adxl345 sensor example php 但是
  • 有没有办法在 python/opencv 中从单摄像头视频生成实时深度图?

    我试图将单个图像转换为其深度图 但我找不到任何有用的教程或文档 我想使用 opencv 但是如果您知道使用张量流等获取深度图的方法 我很高兴听到它 有很多关于立体视觉的教程 但我想让它更便宜 因为它是一个帮助盲人的项目 我目前正在使用 es
  • VSCode 上的 PlatformIO 未编译:collect2.exe:错误:ld 返回 1 退出状态

    我最近不得不擦拭我的计算机 在一切准备就绪并运行之后 是时候打开我之前正在处理的一些 ESP32 程序了 发现 VSCode 上的 Platform IO 将不再编译 运行编译器后 我收到以下错误 Compiling pio build e
  • Google iot MQTT - ESP32 首次连接,仅在 30m 后重新连接

    我正在使用 ESP32 与谷歌物联网云合作 我发送假值只是为了使用 MQTT 数据 PUB SUB 进行测试 显然我成功发布了值 有时 我无法重新连接到谷歌物联网 我不知道为什么它不断检查 wifi publishing 并且不检查 JWT
  • 在 VirtualBox 中将文件夹从主机 Mac OS 共享到来宾 Linux 系统 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何在 Virtual Box 中的主机 Mac 和来宾操作系统 Ubuntu 之间共享文件夹 您需要最新版本的 VirtualBox 4

随机推荐