当前位置: 首页 > 文档资料 > YoC 编程基础 >

蓝牙驱动移植

优质
小牛编辑
121浏览
2023-12-01

1.1 目的

本文介绍平头哥YoC平台蓝牙HCI驱动框架接口的使用和如何适配新的蓝牙驱动。

1.2 蓝牙驱动框架介绍

蓝牙HCI驱动框架代码位于 hci.h 内,主要包换如下接口:

#define hci_open(name) device_open(name)

#define hci_close(dev) device_close(dev)

/**
  \brief       set hci event
  \param[in]   dev      Pointer to device object.
  \param[in]   event    data read event callback.
  \param[in]   priv     event callback userdata arg.
  \return      0 on success, else on fail.
*/
int hci_set_event(aos_dev_t *dev, hci_event_cb_t event, void *priv);

/**
  \brief       send hci format data
  \param[in]   dev      Pointer to device object.
  \param[in]   data     data address to send.
  \param[in]   size     data length expected to read.
  \return      send data len.
*/
int hci_send(aos_dev_t *dev, void *data, uint32_t size);

/**
  \brief       recv hci format data
  \param[in]   dev      Pointer to device object.
  \param[in]   data     data address to read.
  \param[in]   size     data length expected to read.
  \return      read data len.
*/
int hci_recv(aos_dev_t *dev, void* data, uint32_t size);

/**
  \brief       start hci driver
  \param[in]   dev      Pointer to device object.
  \param[out]  send_cmd sned hci command callback.
  \return      0 on success, else on fail.
*/
int hci_start(aos_dev_t *dev, hci_driver_send_cmd_t send_cmd);

其中包括了驱动接口:

- 打开驱动
- 关闭驱动
- 发送hci数据
- 接收hci数据
- 设置接收数据回调
- 启动hci驱动

新的蓝牙HCI驱动需要移植 hci_impl.h 中的结构体:

typedef struct hci_driver {
    driver_t drv;
    int (*set_event)(aos_dev_t *dev, hci_event_cb_t event, void *priv);
    int (*start)(aos_dev_t *dev, hci_driver_send_cmd_t send_cmd);
    int (*send)(aos_dev_t *dev, uint8_t *data, uint32_t size);
    int (*recv)(aos_dev_t *dev, uint8_t *data, uint32_t size);
} hci_driver_t;

如第一章中所述,蓝牙HCI驱动提供了适配层结构体hci_driver_t需要新的蓝牙驱动对接时实现。下面对适配的数据结构和函数逐一进行介绍。

2.1 设置事件回调

  • 函数原型
    int (*set_event)(aos_dev_t *dev, hci_event_cb_t event, void *priv);
    
  • 功能描述 设置事件回调,现在用于接收数据的事件回调

  • 参数描述

IN/OUTNAMEDESC
INdev蓝牙HCI模块的设备句柄
INevent事件回调函数
INpriv事件回调函数形参

其中 event 函数声明如下:

typedef enum {
  HCI_EVENT_READ,
} hci_event_t;

typedef void (*hci_event_cb_t)(hci_event_t event, uint32_t size, void *priv);
  • 返回值
RETURNDESC
0成功
其余失败

2.2 启动HCI驱动

  • 函数原型
    int (*start)(aos_dev_t *dev, hci_driver_send_cmd_t send_cmd);
    
  • 功能描述 启动HCI驱动

  • 参数描述

IN/OUTNAMEDESC
INdev蓝牙HCI模块的设备句柄
INsend_cmd发送HCI Command回调

其中 send_cmd 的声明如下:

typedef int (*hci_driver_send_cmd_t)(uint16_t opcode, uint8_t* send_data, uint32_t send_len, uint8_t* resp_data, uint32_t *resp_len);

该函数为同步函数,将发送 hci command send_data 数据,并将 收到的 hci event 回复 写入 resp_data 中。 其中:

  • send_data 不包含 opcode 和len,只需要hci command的 parameter。
  • resp_data 只包含 hci event return parameters, 调用时 resp_len 必须为 resp_data buffer的大小,函数返回时,resp_len会 赋值成实际的 resp_data 长度。
  • 返回值
RETURNDESC
0成功
其余失败

2.3 发送 HCI 数据

  • 函数原型
    int (*send)(aos_dev_t *dev, uint8_t *data, uint32_t size);
    
  • 功能描述 发送 HCI 数据,需要符合H4或者H5协议个数,具体发送哪种协议格式,可以在协议栈中配置

  • 参数描述

IN/OUTNAMEDESC
INdev蓝牙HCI模块的设备句柄
INdata需要发送的HCI数据
INsize发送的数据长度
  • 返回值
RETURNDESC
大于 0实际发送数据的长度
小于等于0发送失败

2.4 接收 HCI 数据

  • 函数原型
      int (*recv)(aos_dev_t *dev, uint8_t *data, uint32_t size);
    
  • 功能描述 接收 HCI 数据,该数据为流的形式,不需要对应HCI数据的帧,数据的解包动作在协议栈完成

  • 参数描述

IN/OUTNAMEDESC
INdev蓝牙HCI模块的设备句柄
INdata用于接收的buffer
INsize接收的buffer大小
  • 返回值
RETURNDESC
大于等于 0实际接收数据的长度
小于0接收失败