第11節-BLE協議HCI層的硬件接口


本篇博客由韋東山視頻整理所得

如何控制鏈路層讓其發出廣播包、數據包?
通過HCI層向它發出命令,也可以通過ATT層、L2CAP層向LL層發出數據。

學習資料:

藍牙協議core_v5.0.pdf 《Vol 4: Host Controller Interface [Transport Layer]》

BTStack源碼

回顧一下《開源藍牙協議棧BTStack框架代碼閱讀》。

BLE協議在硬件上分為上下兩部件:主機(Host,PC、單片機、Linux板)、控制器(藍牙模塊),如下圖所示:

Host和Controller之間,通過HCI(Host Controller Interface)相連。HCI實現硬件之間的數據傳輸,HCI的一部分位於Host,另一部分位於Controller(圖中的紅色區域)。

HCI有多種,一般有USB口、3線串口(TxD/RxD/Gnd)、5線串口(TxD/RxD/Gnd/CTS/RTS),如下圖:

Host和Controller之間的數據有命令(Command)、事件(Event)、ACL數據等等,如下圖:

在硬件線路上,怎么分辨這些不同的數據?

在《開源藍牙協議棧BTStack框架代碼閱讀》里,我們知道BTStack對每一種硬件接口都抽象出了一個hci_transport_t結構體,里面有send_packet函數,分析這個函數就可以知道在硬件線路上,怎么分辨、傳輸不同類型的數據。

參考文件:

btstack-master\src\hci_transport_h4.c  // 5線串口

btstack-master\src\hci_transport_h5c   // 3線串口

btstack-master\platform\windows\hci_transport_h2_winusb.c   // usb

send_packet函數原型為:

int    (*send_packet)(uint8_t packet_type, uint8_t *packet, int size);

其中的packet_type有4種取值,代表4種類型的數據(在BLE中只有3種,不支持SCO),這些值在頭文件btstack-master\src\bluetooth.h中定義:

一、最簡單的5線串口:

參考文件:

btstack-master\src\hci_transport_h4.c  // 5線串口

在數據之前加上1字節的頭部,然后把頭部連同數據一起發送。

這個頭部就用來表示數據類型:

1字節頭部

表示的數據類型

0x01

Command (Host發給Controller)

0x02

ACL Data

0x04

Event  (Controller發給Host)

 

數據在TxD、RxD線路上傳輸,其中的RTS/CTS只是用來進行流量控制。它們的作用簡單介紹一下:

RTS (Require ToSend,發送請求)為輸出信號,用於指示本設備准備好可接收數據,低電平有效,低電平說明本設備可以接收數據。

CTS (Clear ToSend,發送允許)為輸入信號,用於判斷是否可以向對方發送數據,低電平有效,低電平說明本設備可以向對方發送數據。

可以參考btstack-master\src\hci_transport_h4.c的hci_transport_h4_send_packet函數:

//packet所指的內存區域為要發送的數據,packet_type為數據的類型。如何將類型和數據一起發送出去的呢?

看代碼,如下:

static int hci_transport_h4_send_packet(uint8_t packet_type, uint8_t * packet, int size){

    // store packet type before actual data and increase size

    size++;

    packet--;  //packet指向一個buffer的首地址,即存放數據的起始地址。然后packet--

*packet = packet_type;這個地方就將數據類型放在了數據的前面去了。

……

二、3線串口:

考文件:

btstack-master\src\hci_transport_h5c   // 3線串口

在實際產品中,使用3線串口的藍牙控制器比較少,所以我們不深入分析它。

3線串口沒有硬件流量控制的功能,它使用SLIP協議傳輸數據,流程如下:

(參考hci_transport_link_send_queued_packet函數)

① 構建頭部:

uint8_t header[4];
hci_transport_link_calc_header(header, link_seq_nr, link_ack_nr, link_peer_supports_data_integrity_check, 1, hci_packet_type, hci_packet_size);

構建4字節的頭部,里面含有packet_type等信息。

② 使用SLIP協議發送頭部、數據本身:

③ SLIP協議:

有興趣的人,可以參考以下文章。

SLIP協議最好文章:

SLIP—串行線路上傳輸數據報的非標准協議

https://blog.csdn.net/pushilong/article/details/80358485

https://wenku.baidu.com/view/809a8a8e8bd63186bcebbcae.html

三、USB:

參考文件:

btstack-master\platform\windows\hci_transport_h2_winusb.c   // usb

(1) 補充一些USB知識:

一個USB硬件,稱之為“設備”(Device);

一個Device內部,有1種或多種“配置”(Configuration)。比如MP3可以用作U盤,也可以用作播放器,這就是2種配置。同一時間,只能有一個配置起作用。

一個配置內部,有1個或多個接口(Interface)。比如USB聲卡有輸出、輸入2接口。一配置下的多個接口,可以同時使用。

一個接口內部,有1個或多個端點(Endpoint)。端點是數據傳輸的實體。

當我們說“給USB設備發數據”時,實際上是給某個Device的某個Interface的某個Endpoint發數據。

 

Endpint有4種:控制端點、BULK端點(批量傳輸端點)、中斷端點、實時端點。

每個Endpoint用一個數值表示,控制端點永遠是0,其他端點值由硬件決定。Endpoint值的bit7表示方向:1表示輸入(usb device傳給主機),0表示輸出(主機傳給usb device)。輸出和輸入是對於host來說的。

 

a. 控制端點可以雙向傳輸數據,其他端點都是單向的。

b. BULK端點:用於傳輸非實時數據

c. 中斷端點:用於傳輸時效性高的數據,比如鼠標、鍵盤數據

d. 實時端點:用於傳輸實時數據,比如視頻傳輸。

 

主機跟Endpoint之間傳輸數據時,對應數據通道就稱為Pipe。

(2) BLE數據在USB接口上的傳輸:

不同類型的數據,使用不同的Endpoint傳輸數據。

數據類型

Endpoint

command

控制端點

event

中斷端點

ACL Data (in, controller傳給host)

BULK輸入端點

ACL Data (out, host傳給controller)

BULK輸出端點

SCO Data(in, controller傳給host)

實時輸入端點  (BLE不支持)

SCO Data (out, host傳給controller)

實時輸出端點  (BLE不支持)

(3) 參考代碼:btstack-master\platform\windows\hci_transport_h2_winusb.c

① 端點掃描:

usb_scan_for_bluetooth_endpoints函數

② 數據發送:packet_type只是用來調用不同的函數,不會作為數據的一部分發送。

 總結:

HCI層描述了Host和Controller之間通過什么接口來連接,可以通過串口、usb口等進行連接。

當通過串口進行傳輸數據時,可以在數據的前面加上一個字節的頭部,用來分辨這個數據是command、event還是acl data。
對於usb口,在usb硬件里面有多個endpoint,command可以發送給某個端點,event可以從某個端點發給Host,不同的數據使用不同的端點。在硬件上傳輸這些數據時,就不需要加上頭部,只需發送數據本身就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM