標籤:
原文網址:http://www.deyisupport.com/question_answer/wireless_connectivity/bluetooth/f/103/t/61462.aspx
看了下問題,發現不太會回答了,很久沒弄,全忘記了,只好貼出之前的一些東西,協助初學者入下門吧:
一、初識BLE
通過這兩天對《CC2540 BLE Software Developer Guider V1.2.pdf 》的學習對CC2540以及藍芽4.0有了一個整體上的認識: 1、藍芽4.0協議:BR/EDR(標準藍芽)+ BLE 目前CC2540硬體只支援BLE這種單模無線標準,不能夠與4.0以前的版本通訊。 2、針對CC2540 BLE-Stack 重點學習了該協議棧的結構,TI的藍芽平台支援兩種協議棧/應用配置:單一裝置配置、網路處理器配置(application/profile在另外的處理器或者PC上的應用)。 3、重點學習了協議棧最頂層的兩個通用profile:GAP(通用接入規範)、GATT(通用屬性規範)。 4、GAP主要負責處理裝置的接入方式以及接入的過程:裝置發現、鏈路建立、鏈路終止、啟動安全功能、裝置配置(主要是串連參數的配置)。 5、GATT主要完成伺服器和用戶端之間通訊的相關子過程。 6、BLE支援40個通道的跳頻機制,其中3個通道用於advertise,剩下的用於資料通訊;而BR的通道數在80,相比而言BLE的機制更加節電。兩者的跳頻位移分別為2MHz、1MHz。 7、OS抽象層相關過程學習,如何配置一個新的任務、任務優先順序、事件觸發、訊息傳遞等。 8、存在的問題:搞不清楚BLE協議內部的GAP、GATT profile與application profile的聯絡與區別,是否BLE能夠在app上添加:A2DP(藍芽立體聲音訊傳輸協議)、HID(人機介面規範)等這些規範。
二、開始瞭解stack
進一步學習GAP,主要扮演四種角色:broadcaster(廣播者)、obseerver(觀察者)、peripheral(外圍)、central(中央)。 1、BLE-Stack中有每一種角色的Sample程式,且正對不同的樣本程式對應的lib也不相同,eg:CC2540_ble_single_chip_peri.lib 、CC2540_ble_network_processor_all.lib 等。 2、對於應用程式的profile需要按照規範自己編寫,目前ti提供幾個醫學上使用的profile,對於檔案傳輸、音頻傳輸等profile,我的理解是BLE不適用於這些場合(參考wiki網上一些話題討論、BLE_TechDay_2011.pdf、 BLE_CC2540_DeepDive_Training_2011.pdf 來源於wiki網)。 我理解的classic就是傳統的那種藍芽應用,BLE的應用主要是用於第一幅圖。BLE目前一個資料包支援的最大位元組數為20Byte,基本上都是幾個位元組的應用,ti常式。 3、在wiki網上找到一個相關的例子:Serial App 通過串口實現兩台PC之間的資料轉送,打算從這個例子入手,在轉向USB的,初步看了一下這個Serial App,在該頁上能夠下載一個HCI Tester的指令碼測試載入器,並不是直接通過兩個串口實現資料轉送,需要上層的profile和HCI Command。 附上地址:http://processors.wiki.ti.com/index.php/LPRF_BLE_SerialApp 4、Btool工具通過串連usb dongle看了一下軟體的選項,嘗試串連兩個usb dongle,在wiki上看到有人說能夠建立串連,實測無法搜尋到裝置。 5、初步計劃先移植keyfob的程式到dongle上,實現兩個裝置之間建立串連,keyfob通過一個按鈕觸發30s的dicoverable狀態,這時候啟動dongle進行scan等一系列操作。
三、摸著石頭過河 1、移植KeyFob常式到USB dongle上面,修改按鍵等宏,刪除了加速度、蜂鳴器程式,該Sample與HostTestApp之間可以建立連結並通訊,參考wiki地址如下: http://processors.wiki.ti.com/index.php/Category:KeyFobDemo 存在的問題: 1)KeyFob常式使用按鍵啟動30秒的advertising,此後由Btool通過USB dongle向KeyFob(另外一個dongle類比的)發送請求連結的命令。按鍵使用輪詢的方式能夠正常進入相應事件,使用IO中斷的方式無法進入,檢查了很多遍未找到原因所在。 2)建立連結之前USB dongle需要Scan裝置,這是在KeyFob發送advertising之後,會存在無法尋找到裝置,猜測是由於使用了輪詢按鍵的方式導致的。 2、CC2540的接收發送緩衝都為128Byte: 再去看了下之前wiki上看到的關於發送位元組不超過20Byte的說法,是限制在10ms以內的。 3、Btool建立串連的狀態: [25]中表明GAP_EstablishLink Success,在Read/Write選項中通過操作關鍵字、描述符來實現通訊中資料的互動,參考1中網址。 eg:通過USB dongle讀取KeyFob電池的電量等,實際讀取錯誤,無效的資料(我想是否需要購買一個keyFob加快開發) 4、想要實現兩台PC之間的通訊: 1)如果採用HostTestApp的方式,上位機需要與Btool類似,產生HCI Command讀寫資料也需要相關命令和操作序列。 2)採用單晶片方式(區別於網路處理器模式,HostTestApp模式),不直接和外界PC或者MCU互動。 最終如何選擇,還需要花時間進一步學習BLE-stack。
四、站的高一點點
1、基本上搞清楚一個應用程式由哪些部分組成,需要做哪些初始化,App函數的位置,以及各種事件的回應程式式。 2、關於CC2540 RF寄存器的問題: 1)User Guide上面未詳細介紹寄存器的各個位,只有簡單的寄存器說明,查閱E2E確定TI未開放,所以無法編寫RF部分的驅動。 2)TI建議的方式:Note, that OSAL and HAL source is avail, a free sniffer is avail, and RF studio can access RF directly. 3)開啟RF Studio CC2540介面,好好看看有哪些部分,對於測試等等有很大用處的。 原則上能夠進行資料包的收發測試。 3、查閱相關TI Bluetooth的器件,簡單對比如下:
五、開始搞起了 通過對TI_BLE_Vendor_Specific_HCI_Guide.pdf 和e2e上相關討論的學習,總結如下; 1、可以通過HIC Command對CC2540進行相關操作,總體描述見。 2、關於CC2540 Production Test Mode參考網址: http://processors.wiki.ti.com/index.php/PTM 3、建立CC2540測試工程檔案,主要是刪除協議部分的和某些無關的OSAL初始化程式。 uint16 UserApp_ProcessEvent( uint8 task_id, uint16 events ){ if ( events & USER_START_DEVICE_EVT ) { HCI_EXT_SetTxPowerCmd (HCI_EXT_TX_POWER_4_DBM); HCI_EXT_ModemTestTxCmd (HCI_EXT_TX_MODULATED_CARRIER,37); //HCI_EXT_ModemHopTestTxCmd (); //HCI_EXT_ModemTestRxCmd (37) ; //HCI_EXT_EndModemTestCmd (); return ( events ^ USER_START_DEVICE_EVT ); } return 0;} 主要涉及的函數: HCI_EXT_SetTxPowerCmd 設定發射功率HCI_EXT_ModemTestTxCmd 開始連續的發送測試,需要指定通道和是否調製 HCI_EXT_ModemHopTestTxCmd 開始連續的發送測試,發送37Byte 資料包(偽隨機數),且通道從0-39遞增HCI_EXT_ModemTestRxCmd 開始接收測試,需要指定通道HCI_EXT_EndModemTestCmd 停止Modem測試
六、簡單分析
1、以Central、Peripheral之間通訊為例,學習BLE-stack裝置之間的資料通訊: 1)Peripheral 通過GATT_Notification函數實現資料發送,這種情況下外圍裝置扮演Seriver(注1)。2)Central 通過GATT_MSG_EVENT事件觸發任讀取 gattMsgEvent_t 結構體中的 msg對應的 Indication and Notification messages(參考程式中相關結構體)實現資料接收,這種情況下中央裝置扮演Client(注2)。
注1: static attHandleValueNoti_t *pReport= NULL; if ( GATT_Notification( 0, pRepor, FALSE )==SUCCESS) { //使用者可在這裡進行發送成功後的相關操作,pRepor為待發送的Notification } /** * Handle Value Notification format. */ typedef struct { uint16 handle; //!< Handle of the attribute that has been changed (must be first field) uint8 len; //!< Length of value uint8 value[ATT_MTU_SIZE-3]; //!< New value of the attribute } attHandleValueNoti_t;
注2: if ( pMsg->method == ATT_HANDLE_VALUE_NOTI ||pMsg->method == ATT_HANDLE_VALUE_IND ) { attHandleValueNoti_t noti; dataCount = dataCount+ 1; LCD_WRITE_STRING_VALUE( "Data Cnt: ", dataCount, 10, HAL_LCD_LINE_1 ); noti.handle = pMsg->msg.handleValueNoti.handle; noti.len = pMsg->msg.handleValueNoti.len; osal_memcpy(¬i.value, &pMsg->msg.handleValueNoti.value,noti.len); //使用者可在這裡操作¬i,通過串口發送或者USB發送出去等等 }
2、建立串連的某些細節函數還未搞清楚,發送資料所能夠被使用者看到的最底層函數如1中描述。
3、進一步計劃: 1)通過Central、Peripheral之間通訊為基本模板先實現裝置之間建立串連,然後使用1中方式實現資料交換。2)在1)的基礎上加入串口通訊實現串口之間的通訊,並能夠通過串口控制裝置建立串連的過程等。3)使用Dongle實現USB功能,主要是將HostTestApp中的CDC類USB程式提取出來,實現Dongle與PC間資料通訊,不涉及BLE-stack協議棧相關只是一個USB程式。4)由於CDC類的USB相對而言要簡單一些,上位機編程可以使用串口,在3)的基礎上再去實現HID,具體關於這一部分USB驅動和上位機等還沒有很清晰的思路。
4、需要做的事情: 1)使用購買的CC2540驗證鏈結接建立資料互動的功能。2)實現CC2540的UART與PC通訊的功能。3)使用Dongle實現CDC類USB與PC通訊的功能。4)使用Dongle實現HID類USB與PC通訊的功能。 附件: GATT_Notification、GATT_Indication函數的說明,不能夠獨立運行需要在建立串連的基礎上。
七、換個硬體看看
1、使用購買的CC2540模組實驗,修改了Debug介面,能夠採用TI的CCDebug下載光碟片內建的程式測試正常。 光碟片常式使用BLE-Stack 1.1修改,分別下載KebFob和HostAppTest。
2、下載BLE-Stack 1.21中常式KebFob和HostAppTest測試連接過程也正常。 圖1:測試UUID讀取關鍵字成功,KeyFob的電量(百分比) 圖2:測試Adv.Commands 讀取RSSI值
3、使用BLE-Stack 1.1常式中的虛擬鍵盤,測試連接失敗(光碟片和協議棧原始常式都測試了),用HostAppTest測試搜尋到的裝置地址與待綁定的地址是匹配的。 待做的事情: 1)搞清楚3串連過程中出現的問題。2)花時間去熟悉API函數以及相關的結構體。
八、開始做硬體了
1、參考《CC2540EM_discrete_schematic.pdf 》繪製CC2540無線模組原理圖。 1)引出P0(8pin)、P1(8pin)、P2(3pin)、電源(2pin)、USB(2pin)、RESET(1pin)共計24pin。2)不知引腳排列是否合理,目前的排列有利於模組布線。 見附件:CC2540_BLE_RF.pdf
2、參考《CC2540_MiniDK_SCHEMATIC.pdf 》和購買套件的底板原理圖繪製CC2540底板原理圖。 1)添加低功耗加速度感應器CMA3000(用於計步等,可預設不焊接)。2)添加CP2102用於USB轉串口,通過UART列印字元便於調試等。3)可選USB供電、CCdebug供電、CR2032紐扣電池供電。4)設計中多處採用0R電阻,便於二次修改。 見附件:CC2540 Board.pdf
3、閱讀BLE的宣傳資料,覺得不適合在底板上添加傳統的感應器,不知道是否需要添加感應器? 見附件:TI BLE @ CES.pdf
九、閑置階段,隨便玩玩
1、原理圖修改、檢查:1)添加PCB天線和外置天線。2)添加OLED顯示、電源指示燈、添加撥碼開關。
2、OLED選擇了一款內建升壓電路的型號與之前的像素一致:1)選取內建升壓的OLED省去了升壓電路的設計。2)實際經過調研科選擇TPS61040作為升壓晶片,滿足需求(考慮到電感、續流二極體等物料不好採購的問題)。
3、確定底板上物料在ERP中的型號,主要的器件目前都已經確定、包括接外掛程式。
4、調試CC2540的UART,調試OK能夠列印資訊:1)發現在Advertising過程中會出錯(測試了多種發送情況,確認是Advertising時RF引起的)。2)使用DMA、ISR都是同樣的情況。
十、開始玩弄她吧
1、CC2540通訊建立過程調試:1)找到UART在advertising過程中發送資料亂碼的問題,使能低功耗(PWRMGR_BATTERY)會伴隨主時鐘的切換,導致傳輸速率不穩定照成的,關閉低功耗資料正常,有待進步一學習,暫時不做深入研究。2)在調通串口的基礎上實現基本的通訊建立過程調試,主要是通過peripheral、central的例子,實現了PC通過串口向peripheral裝置發送資料通過無線被central裝置接收再通過串口傳輸至另一台PC。 Peripheral(Send): 01 82 fe 07 00 05 11 11 11 11 1101 82 fe 07 00 05 22 22 22 22 22 Central(Receive): 04 FF 0D 1B 05 00 01 00 07 07 00 11 11 11 11 11 04 FF 0D 1B 05 00 01 00 07 07 00 22 22 22 22 22 以上參考:附件一、附件二。
2、Blood Pressure常式測試:1)在新版本BLE-Stack1.21中未提供BP的Collector,只有一個BP Sensor,所以還需要花點時間建立Collector的工程。2)在TI Wiki上找到了關於BLE-Stack1.1關於BP示範的說明,需要一個BleHealthDemo(C#開發)上位機的配合,Collector是工作在Network Process模式下。 測試效果參考:附件三。
3、開會提出的問題小結:1)為什麼要有Proflie?A:Profile由藍芽SIG發布,描述了不同裝置使用藍芽協議棧時的差異性和統一性。比如一個血壓計,大家都按照這個BP Profile、BP Service來進行規範定義,那麼一個BP收集器就能夠收集不同廠家生產的BP Sensor測量的血壓值等。如果沒有Profile關有協議那麼大家都只能閉門造車,我生產的手機帶藍芽功能,那麼你使用的藍芽耳機就必須是我生產的,因為那些資料格式、裝置描述等只有我知道,所以才有音頻Profile(A2DP)之後大家按照這個規範去嚴格定義自己的裝置就可以了。 2)BT流行版本的Profile比較:我所理解的在BT2.0、BT2.1、BT3.0這些版本能夠使用傳統Profile,而4.0之後會多出一部分GATT-Basic規範Profile。
這裡我們需要理解的是:BT2.0 = Core Version2.0 +EDRBT2.1 = Core Version2.1 +EDRBT3.0 = Core Version3.0 +HSBT4.0 = Core Version4.0 +BLE = BR/EDR + BLE(這裡和以往不同,V4.0有兩個核心,CC2540隻有BLE)
對於血壓計: V4.0 版本使用BP Profile(Blood Pressure Profile)+ BP ServiceV4.0 之前版本使用HD Profile(Human Device Profile) HD Profile(健康規範)包括 BP Profile(血壓規範) + HT Profile(溫度規範)+ …… 這些規範可以從官方網站查看:https://www.bluetooth.org/Technical/Specifications/adopted.htm 以上參考:附件四、附件五。
3、附件: 附件一 附件二 附件三 附件四 附件五
十一、血壓計分析
1、Blood Pressure樣本程式佔用資源(256K Flash + 8K RAM):
2、Blood Pressure Profile規定的資料格式:
3、Profile 定義了資料格式、過程、服務的UUID等: 以上這些會在協議屬性工作表中體現,而這個屬性工作表會通過相關API將他作為參數傳給協議棧。 static gattAttribute_t bloodPressureAttrTbl[] = { // BloodPressure Service { { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */ GATT_PERMIT_READ, /* permissions */ 0, /* handle */ (uint8 *)&bloodPressureService /* pValue */ }, // 1. Characteristic Declaration { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &bloodPressureTempProps }, // 2. Characteristic Value { { ATT_BT_UUID_SIZE, bloodPressureTempUUID }, 0, //return READ_NOT_PERMITTED 0, &bloodPressureTemp }, // 3.Characteristic Configuration { { ATT_BT_UUID_SIZE, clientCharCfgUUID }, GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, (uint8 *)&bloodPressureMeasConfig }, // 4.Presentation Format { { ATT_BT_UUID_SIZE, charFormatUUID }, GATT_PERMIT_READ, 0, (uint8 *)&bloodPressureTempFormat }, ////////////////////////////////////////////// // IMMEDIATE MEASUREMENT ////////////////////////////////////////////// // 5.Characteristic Declaration { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &bloodPressureImeasProps }, // 6.Characteristic Value { { ATT_BT_UUID_SIZE, bloodPressureImeasUUID }, 0, //return READ_NOT_PERMITTED 0, &bloodPressureImeas }, // 7.Characteristic Configuration { { ATT_BT_UUID_SIZE, clientCharCfgUUID }, GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, (uint8 *)&bloodPressureIMeasConfig }, ////////////////////////////////////////////// // FEATURE ////////////////////////////////////////////// // 8.Characteristic Declaration { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &bpFeatureProps }, // 9.Characteristic Value { { ATT_BT_UUID_SIZE, bpFeatureUUID }, GATT_PERMIT_READ, 0, (uint8 *)&bpFeature }, };
好吧,第一章分享到這裡結束了,只是簡簡單單的協助初學者入門,權當玩玩,專業開發人員請忽略。不排除自己理解和排版造成的問題,請自行判斷,謝謝。
後續會上傳代碼和相關文檔,並繼續開貼說第二章
哈,希望ti能給個包包硬碟啥的,鼓勵一下。
【轉】BLE_CC2540_初學者入門指導