1 概述
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;
2 适配说明
如第一章中所述,蓝牙HCI驱动提供了适配层结构体hci_driver_t
需要新的蓝牙驱动对接时实现。下面对适配的数据结构和函数逐一进行介绍。
2.1 设置事件回调
- 函数原型
int (*set_event)(aos_dev_t *dev, hci_event_cb_t event, void *priv);
功能描述 设置事件回调,现在用于接收数据的事件回调
参数描述
IN/OUT | NAME | DESC |
---|---|---|
IN | dev | 蓝牙HCI模块的设备句柄 |
IN | event | 事件回调函数 |
IN | priv | 事件回调函数形参 |
其中 event 函数声明如下:
typedef enum {
HCI_EVENT_READ,
} hci_event_t;
typedef void (*hci_event_cb_t)(hci_event_t event, uint32_t size, void *priv);
- 返回值
RETURN | DESC |
---|---|
0 | 成功 |
其余 | 失败 |
2.2 启动HCI驱动
- 函数原型
int (*start)(aos_dev_t *dev, hci_driver_send_cmd_t send_cmd);
功能描述 启动HCI驱动
参数描述
IN/OUT | NAME | DESC |
---|---|---|
IN | dev | 蓝牙HCI模块的设备句柄 |
IN | send_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 长度。
- 返回值
RETURN | DESC |
---|---|
0 | 成功 |
其余 | 失败 |
2.3 发送 HCI 数据
- 函数原型
int (*send)(aos_dev_t *dev, uint8_t *data, uint32_t size);
功能描述 发送 HCI 数据,需要符合H4或者H5协议个数,具体发送哪种协议格式,可以在协议栈中配置
参数描述
IN/OUT | NAME | DESC |
---|---|---|
IN | dev | 蓝牙HCI模块的设备句柄 |
IN | data | 需要发送的HCI数据 |
IN | size | 发送的数据长度 |
- 返回值
RETURN | DESC |
---|---|
大于 0 | 实际发送数据的长度 |
小于等于0 | 发送失败 |
2.4 接收 HCI 数据
- 函数原型
int (*recv)(aos_dev_t *dev, uint8_t *data, uint32_t size);
功能描述 接收 HCI 数据,该数据为流的形式,不需要对应HCI数据的帧,数据的解包动作在协议栈完成
参数描述
IN/OUT | NAME | DESC |
---|---|---|
IN | dev | 蓝牙HCI模块的设备句柄 |
IN | data | 用于接收的buffer |
IN | size | 接收的buffer大小 |
- 返回值
RETURN | DESC |
---|---|
大于等于 0 | 实际接收数据的长度 |
小于0 | 接收失败 |