藍牙基本概念
Piconet
在藍牙設備沒有跟其他藍牙設備連線的時候,它自己屬於一個piconet。當有連線后,piconet里有兩種角色:master 和 slave。發起連線的一方是master,被連接的一方是slave。slave會以master的時鍾為參照,以625us為時間單位,與master進行數據收發。每一個piconet里,一個master最多有7個slave。
PHY Mode
LE:LE采用頻分多址(FDMA)和時分多址(TDMA),在FDMA中使用了40個(40)物理信道,相隔2 MHz。37,38,39用作主要廣播,而另外37個通道用作數據渠道或者次要廣播通道。
Basic Rate: 最基本的一種模式,采用GFSK,傳輸速率是 1Mb/s。
Enhanced Data rate: 增強模式,傳輸速率是 2Mb/s (π/4-DQPSK)或 3Mb/s(8DPSK),這種模式有兩種編碼。
BT clock
Clock是藍牙通信最最基礎的一個概念,clock定義了通信的時空范圍,定義了這個Piconet時空的坐標系,只有在同一個坐標系里,網絡內的各個角色才能相互了解對方的時間線,才知道什么時候發包,什么時候收包。BT clock是個28bit的計數器,每tick一次是312.5us,所以總共有 (2^28 -1)個tick,算一下大約是(2^28-1)*312.5us/10^6/3600 = 23.3個小時后clock會翻轉。
針對Clock有幾個重要概念:
CLK0, 312.5us,是一個tickCLK1, 625us, 是一個slotCLK2, 1.25ms, 是一個frame(做一次TX 和 RX)CLK12, 1.28s.Clock的精確度要求為 +/-250ppm 和 +/-20ppm
藍牙tx,rx會按時隙為節拍通信,數據以625us一個時隙作為最小單元,有些數據包會超過一個時隙,最多可持續5個時隙。
對於一個連接中的兩個設備中,對於主設備,slave_offset應為零,因為CLK與其自身的本地時鍾CLKN相同。每個從機應在其CLKN上添加一個適當的slave_offset,以使CLK對應於主機的CLKN,使得主從時鍾保持同步盡管設備中的所有CLKN均以相同的標稱速率運行,但相互漂移會導致CLK不准確。因此,必須定期更新從機中的偏移,以使CLK大約等於主機的CLKN
Physical Channel(信道)
Spec總共有定義如下5種channel
Basic piconet physical channel
Adapted piconet physical channel
Page scan physical channel
Inquiry scan physical channel
Synchronization scan physical channel
以Basic piconet physical channel為例,在建立連線后,Slave會以Mater的clock為准。Master和Slave以一個slot為單位進行Tx和Rx,Master在clock為偶數時發包,Slave在clock為偶數時收包,如下圖所示
藍牙核心框架
核心架構
藍牙核心框架信息量非常大,把藍牙的構架和數據傳輸方向描述的非常清楚,綠色框圖部分是Radio, 藍牙射頻,基帶和鏈路管理放在該部分完成,紅色部分稱為Host端,俗稱藍牙協議。
Radio分為經典藍牙,低功耗藍牙和AMP。我們主要看LE Controller,順帶提一下BR/EDR。
Controller和Host直接的數據傳輸有幾種方式:C/E,SCO,ACL,ISO。
• Synchronous Connection-Oriented (SCO) logical transport
• Extended Synchronous Connection-Oriented (eSCO) logical transport
• Asynchronous Connection-Oriented (ACL) logical transport
• Active Slave Broadcast (ASB) logical transport
• Connectionless Slave Broadcast (CSB) logical transport.
簡單來說,C/E是HOST和Controller通信方式,Command用於下發指令,Event是Host用於接收controller上報指令,SCO和eSCO是經典藍牙下用於音頻傳輸,ACL為異步數據傳輸(沒有嚴格同步時間要求的數據傳輸方式),ISO是藍牙5.2的最新規范的大數據傳輸通道,分為基於連接的數據流傳輸和基於廣播的數據流傳輸。上圖中灰色的箭頭表示控制指令的傳輸路徑,黑體箭頭表示數據流向。
Synchronous Connection Oriented (SCO)
Circuit switched typically used for voice
Symmetric, synchronous service
Slot reservation at fixed intervals
Point-to-point
Asynchronous Connectionless Link (ACL)
Packet switched
Symmetric or asymmetric, asynchronous servicePolling mechanism between master and slave(s)
Point-to-point and point-to-multipoint
以設置LE設備廣播為例,LE 設備上電后,host發送reset command重啟藍牙設備,發送廣播參數command,配置廣播內容,使能廣播command,完成藍牙設備的廣播設置command。
(```)
########################################################
## Legacy Adv Command
########################################################
#reset
Send_HCI_Reset
Wait_HCI_Command_Complete_Reset_Event 5000, any, HCI_Reset, 0x00
# set Adv parameter
Send_HCI_LE_Set_Advertising_Parameters 800, 800, 0x00, 0x00, 0x00, "01:02:03:04:05:06", "0x07", "0x00"
Wait_HCI_Command_Complete_LE_Set_Advertising_Parameters_Event 5000, any, HCI_LE_Set_Advertising_Parameters,
# set Adv data Payload
Send_HCI_LE_Set_Advertising_Data 0x10, "00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F"
Wait_HCI_Command_Complete_LE_Set_Advertising_Data_Event 5000, any, HCI_LE_Set_Advertising_Data,
# set Scan rsp data Payload
Send_HCI_LE_Set_Scan_Response_Data 0x10, "00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F"
Wait_HCI_Command_Complete_LE_Set_Scan_Response_Data_Event 5000, any, HCI_LE_Set_Scan_Response_Data,
# enable adv
Send_HCI_LE_Set_Advertise_Enable 0x01
Wait_HCI_Command_Complete_LE_Set_Advertise_Enable_Event 5000, any, HCI_LE_Set_Advertise_Enable,
(```)
藍牙Host和controller層通過HCI Command/Event交互數據,在早期的BR/EDR藍牙中,controller和host會分開兩顆芯片,在藍牙4.x以后,芯片原廠已經把兩顆芯片集成到一顆soc中,hci層只有在藍牙測試時候會單獨用到,工程中,往往已經看不到hci層(已經打包在lib里),這一章有了一個層級間數據傳輸的感性認識,下面了解藍牙協議的全貌。
藍牙協議架構
從OSI(Open System Interconnection)模型的角度看,藍牙是一個比較簡單的協議,它僅僅提供了物理層(Physical Layer)和數據鏈路層(Data Link Layer )兩個OSI層次,細化可分為如圖所示的物理層(Physical Layer)、邏輯層(Logical Layer)、L2CAP Layer。
物理層,負責提供數據傳輸的物理通道(通常稱為信道)。通常情況下,一個通信系統中存在幾種不同類型的信道,如控制信道、數據信道、語音信道等等。
邏輯層,在物理層的基礎上,提供兩個或多個設備之間、和物理無關的邏輯傳輸通道(也稱作邏輯鏈路)。
L2CAP層,L2CAP是邏輯鏈路控制和適配協議(Logical Link Control and Adaptation Protocol)的縮寫,負責管理邏輯層提供的邏輯鏈路。基於該協議,不同Application可共享同一個邏輯鏈路。類似TCP/IP中端口(port)的概念。
在l2cap之上還可以有profile層,理解藍牙協議的profile,基於L2CAP提供的channel,實現各種各樣的應用功能。Profile是藍牙協議的特有概念,為了實現不同平台下的不同設備的互聯互通,藍牙協議不止規定了核心規范(稱作Bluetooth core),也為各種不同的應用場景,定義了各種Application規范。
數據和指令的傳輸通過C/E,SCO,ACL,ISO幾個通道穿梭在不同層協議,既保證了藍牙協議層級間的獨立,又完成了藍牙數據的交互。
藍牙層級間的數據交互
藍牙協議層級間的指令數據傳輸需要靠通道相互連接,操作系統消息傳遞機制以及callback函承擔了實現層級間的數據通信和交互的橋梁。
我們以TI CC2541(真的很老了)的軟件架構來講述數據傳輸方式,工程內有多個線程同時工作:LL,HAL,HCI,L2CAP,GAP,SM,GATT,GAPROLE,GAPBondMgr,GATTServApp,SimpleBLEPeripheral。線程之間采用send/callback方式交互數據。
(```)
void osalInitTasks( void )
{
uint8 taskID = 0;
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
/* LL Task */
LL_Init( taskID++ );
/* Hal Task */
Hal_Init( taskID++ );
/* HCI Task */
HCI_Init( taskID++ );
#if defined ( OSAL_CBTIMER_NUM_TASKS )
/* Callback Timer Tasks */
osal_CbTimerInit( taskID );
taskID += OSAL_CBTIMER_NUM_TASKS;
#endif
/* L2CAP Task */
L2CAP_Init( taskID++ );
/* GAP Task */
GAP_Init( taskID++ );
/* SM Task */
SM_Init( taskID++ );
/* GATT Task */
GATT_Init( taskID++ );
/* Profiles */
GAPRole_Init( taskID++ );
GAPBondMgr_Init( taskID++ );
GATTServApp_Init( taskID++ );
/* Application */
SimpleBLEPeripheral_Init( taskID );
}
(```)
HOST端層級之間數據交互通道
HCI下層和controller的部分邏輯和上層host一樣,只是在hci層做了一層數據傳輸的task,HCI_task作為host和controller的銜接,進行發送,解析指令,傳輸數據。
HCI command packet format: cmd
Packet Type + Command opcode + lengh + command payload
| 1 octet | 2 | 1 | n |
HCI data packet format: eco acl
Packet Type + Conn Handle + lengh + data payload
| 1 octet | 2 | 2 | n |
總結
弄清楚了基本概念,弄清楚了框架和數據流向和軟件實施方法,就基本對藍牙協議有了一個宏觀認識,對於理解軟件代碼有一定幫助。
轉載微信公眾號:無線技術聯盟