藍芽4 0 BLE 資料傳輸 (二)

2021-09-01 16:05:41 字數 3568 閱讀 6672

在第一部分我們了解了幾個專業詞彙,接下來我們再了解一下資料的傳送

一、資料傳送

在ble協議棧中進行資料傳送分為兩個方面,乙個事gatt的client主動向service傳送資料,另乙個是gatt的service主動向client傳送資料

我們暫且簡單的分為主機向從機傳送資料,從機主動向主機傳送資料。

1、主機向從機傳送資料

傳送可以呼叫gatt_writecharvalue函式來實現,該函式會呼叫協議棧裡面與硬體相關的函式最終將資料通過天線傳送出去,這裡設計對射頻模組的操作,例如:開啟發射機,調整發射機的發射功率等內容,這些部分協議棧都已經實現了,使用者不需要自己寫**實現(這裡是廢話,可以忽略),只需掌握gatt_writecharvalue函式的使用方法即可。需要傳送的資料填充到value中,然後資料長度填充到len中,即:

首先我們得了解一下傳送包的結構體

typedef struct

uint16 handle;               //要寫入的屬性的控制代碼 (必須是第乙個字段)

uint8 len;                   //資料長度

uint8 value[att_mtu_size-3]; //存資料的陣列

uint8 sig;                   //身份驗證簽名狀態 (不包括 (0),有效的 (1),無效 (2))

uint8 cmd;                   //標記命令

} attwritereq_t;

我們再看下資料是怎麼傳送的:

gatt_writecharvalue有三個引數,第乙個為連線控制代碼,第二個引數就是我們要傳送的資料報,最後乙個引數為時間的taskid,只要滿足以上的傳送格式我們就可以把資料傳送出去了,是不是很簡單啊?

2、從機向主機傳送資料

從機向主機傳送資料,並不是用gatt_writecharvalue這個函式,而至用另外的一種形式----notification,因此,我們需要呼叫gatt_notification函式。在開發串列埠透傳等專案時,就需要在從機中主動向主機傳送資料,需要該函式來實現。主要**如下:

是不是感覺比write的形式 更簡單?當然這個只能適用於從機主動傳送給主機。

二、資料接收

資料接收和資料傳送一樣,同樣分為兩個方面,即從機接收主機發來的資料和主機接收來自從機的資料。

1、主機接收來自從機的資料

typedef struct

uint16 handle; //要讀取的屬性的控制代碼 (必須是第乙個字段)

} attreadreq_t;

具體例項如下:

attreadreq_t req;

req.handle = ******blecharhdl;

status = gatt_readcharvalue( ******bleconnhandle, &req, ******bletaskid );

gatt應答了這個請求,返回值success(0x00),向下告知ble有生意了,該幹活了。於是ble協議棧在下次建立連線時,傳送獲取資料指令個service,於是就把資料傳給了client,當client接收到資料時,ble就會把資料打包成乙個訊息(osal message), 通過出納gatt返回給了應用程式。訊息內包含gatt_msg_event和修改了的att_read_rsp。應用程式接收到了從osal來的sys_event_msg事件,就知道資料接收到了,應用程式接收訊息,拆包檢查,就可以取走訊息裡面的資料了,最後應用程式把包裝好的訊息給銷毀,這就是整數據傳送過程。

**分析:

if ( events & sys_event_msg ) //觸發sys_event_msg事件

uint8 *pmsg;

if ( (pmsg = osal_msg_receive( ******bletaskid )) != null )

******blecentral_processosalmsg( (osal_event_hdr_t *)pmsg );//用於處理訊息

// release the osal message

void osal_msg_deallocate( pmsg );//銷毀訊息資料

進入******blecentral_processosalmsg函式就會執行下面一句

case gatt_msg_event:  

******blecentralprocessgattmsg( (gattmsgevent_t *) pmsg );//接收從機資料

break;

進入******blecentralprocessgattmsg函式進行拆包分析資料

獲取從機訊息我們主要看下面幾句話

if ( ******blestate != ble_state_connected )   //以防gatt的訊息來了之後的連線已斷開,如果斷開連線就忽略該訊息

return; 

if ( ( pmsg->method == att_read_rsp ) ||

( ( pmsg->method == att_error_rsp ) &&

( pmsg->msg.errorrsp.reqopcode == att_read_req ) ) )   //判斷是不是讀資料

if ( pmsg->method == att_error_rsp )//獲取錯誤資訊

uint8 status = pmsg->msg.errorrsp.errcode;

lcd_write_string_value( "read error", status, 10, hal_lcd_line_1 );

else

// after a successful read, display the read value

uint8 valueread = pmsg->msg.readrsp.value[0]; //取出訊息包中從機傳送過來的資料

lcd_write_string_value( "read rsp:", valueread, 10, hal_lcd_line_1 );

2、從機接收主機發來的資料

當從機接收來自主機發來的資料後,從機會產生乙個gatt profile callback呼叫,我們在這個callback中接收主機傳送的資料。這個callback在從機初始化時向profile註冊。

到此為止,我們至少得理清這條線索:主機通過ble提供的資料傳送介面傳送資料後,從機的協議棧接收到資料後,做相應處理,取得自己需要的資料即可。其他工作,都由ble協議棧自動完成。

並且在這裡我們得清楚,用write和read來傳送和獲取特徵值的方式方式只適用於主機,只主機主動發起的。而從機若想主動傳送資料給主機那麼我們就只能用notification的方式傳送。我們的主機一半作為gatt層的client,而從機一半作為service。

今天就到這裡,尼瑪部落格真難寫,真浪費時間,真的真的真的。。。。

藍芽4 0 BLE 資料傳輸 (二)

在第一部分我們了解了幾個專業詞彙,接下來我們再了解一下資料的傳送 一 資料傳送 在ble協議棧中進行資料傳送分為兩個方面,乙個事gatt的client主動向service傳送資料,另乙個是gatt的service主動向client傳送資料 我們暫且簡單的分為主機向從機傳送資料,從機主動向主機傳送資料...

藍芽4 0 BLE 資料傳輸 (一)

一 簡介 本文主要講解藍芽資料傳輸一。二 實驗平台 協議棧版本 ble cc254x 1.4.0 編譯軟體 iar 8.20.2 硬體平台 smart rf 主晶元cc2541 三 博主 si zhou qun 84342712 495527583 qq.com 開源四軸群 84342712 開源四...

藍芽4 0 BLE 資料傳輸(四)

今天我們做乙個簡單的資料傳輸實驗,就是用ti提供的lightblue 來點亮控制led 這個很簡單,我沒有用協議棧裡面的hal led,因為我看了,這個很麻煩,明明兩句話的事情非搞得那麼複雜,廢話不說直接來分析。開啟cc2540協議棧中的例子 bleperipheral.eww。首先我們得把hal ...