日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蓝牙BLE(协议栈、OSAL、蓝牙APP工具)

發布時間:2023/12/10 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝牙BLE(协议栈、OSAL、蓝牙APP工具) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 藍牙配對和綁定
  • 藍牙4.0 BLE
  • 信道(RF Channel)
  • BLE協議棧分層
    • PHY層(Physical layer 物理層)
    • LL層(Link Layer 鏈路層)
    • HCI層(Host controller interface 主機控制接口層)
    • L2CAP層(Logic link control and adaptation protocol 邏輯鏈路控制和自適應協議)
    • SMP層(Secure manager protocol 安全管理協議)
    • GAP層(Generic access profile 通用訪問配置文件) —— 用于連接
      • GAP 狀態(待機、廣播、掃描、連接、主從)
      • BLE 連接請求參數(連接間隔、廣播間隔、從機潛伏、監督超時)
      • GAP Role Task(參數配置api、廣播內容、連接間隔、斷開藍牙、更新參數)
      • GAP Bond Manager(GAP Bond Mgr 連接安全初始化api)
    • ATT(Attribute protocol 屬性協議層)
    • GATT(Service/Characteristic的UUID主從機通信) —— 用于通信
    • 頂層profile配置文件
    • Lib 庫文件
    • 外設驅動
  • 藍牙主機和從機之間傳輸數據實現
  • 一款強大的芯片nRF52840及利用藍牙5.0實現數據遠程采集
  • BLE開發環境搭建
  • OSAL工作原理
    • TASK初始化(osal_start_system調用初始化函數osalInitTasks)
    • TASK與event 處理(osal_start_system調用運行函數osal_run_system)
  • OSAL函數api介紹
    • OSAL 添加事件函數
    • OSAL內存管理函數
    • OSAL消息通信函數
    • 其他的OSAL層API函數接口
  • OSAL UART實驗
  • OSAL 主從機通信實驗(添加特征值)
    • 實驗現象
    • 從機上電如何實現廣播
    • 主機自動掃描
    • 主機連接設備
    • 從機串口的數據處理
    • 從機藍牙讀屬性的數據處理
    • 主機串口數據處理
  • OSAL BLE獲得多個特征值句柄實驗
  • OSAL BLE自動重連設備實驗
  • OSAL BLE的綁定和配對實驗
  • 藍牙協議棧遇到的問題總結(主從模式、MAC地址、RSSI)
  • IOS藍牙iBeacon協議(UUID、Major、Minor、RSSI)
  • 手機藍牙APP工具的使用(nrf Connect)
  • JDY-10M藍牙模塊使用教程(AT指令)

參考:芯海廠家《CST92F25 SDK開發指南V1.2.pdf》 藍牙BLE 5.0
參考:「物聯網」- 藍牙4.0 BLE開發入門到精通(視頻使用CC2540藍牙BLE芯片、介紹IAR編程環境安裝及使用)
地址: https://www.bilibili.com/video/BV1qZ4y1W7dz?p=3&spm_id_from=pageDriver
配套書籍:《藍牙4.0BLE開發完全手冊》 物聯網開發技術實戰 280頁 31.5M 高清書簽版

參考:BLE協議棧入門一(基本概念)
參考:淺談BLE協議棧
參考:BLE協議棧詳解

藍牙配對和綁定

https://www.cnblogs.com/iini/p/12801242.html

藍牙4.0 BLE

BLE全稱Bluetooth Low Energy,低功耗藍牙,是一種無線傳輸小數據的超低功耗藍牙技術。藍牙設備總共分為三種:Bluetooth、Bluetooth smart、Bluetooth smart ready。

  • Bluetooth設備是經典藍牙設備(比如藍牙耳機),包括BR/EDR/AMP三種技術;
  • Bluetooth smart是BLE設備(比如藍牙溫度計),即低功耗藍牙設備;
  • Bluetooth smart ready是雙模藍牙設備(比如手機),即同時支持傳統藍牙和低功耗藍牙。

這三種設備的區別和聯系如下圖(箭頭表示可以連接):

新藍牙技術標準推動了IPv6協議引入藍牙標準的進程,藍牙4.2標準設備可以直接通過IPv6和6LoWPAN接入互聯網。

既然是無線芯片呢,其組成由軟件和硬件構成。

  • 軟件部分,為 BLE 協議棧
  • 硬件部分包含 RF PHY(無線收發裝置),Modem(調制解調器),以及 Baseband(基帶)構成。

BLE 的協議規范,全部需要遵循 Core Spec 來進行定制,Core Spec 中包含了 RF 、Modem、Air Interface,數據編碼/解碼,以及軟件的協議規范

信道(RF Channel)

摘自:BLE(2)——基本特性(狀態、角色、地址、信道)

藍牙 BLE 工作在 2.4GHz 的頻段上,分為 40 個 RF 信道,每個信道 2M。同一時刻,只能用一個信道進行數據的傳輸/接收。

這 40 個 RF Channel 上,并不是平等的, SIG 把物理信道轉換成為一個叫做 Channel Index 的玩意(其實就是簡單的轉換關系):

物理信道從 0 - 39 進行編號。Index廣播信道:PHY Ch0 對應 37,PHY Ch12 對應 38,PHY 39 對應 39。


在 BLE 4.2 時代,Advertising、Scanning、Initiating 狀態只允許在 Ch Index 的 37/38/39 上執行數據的收發。Advertising 是為了讓其他 BLE 設備發現本設備,Scanning 是為了掃描到其他設備。為了讓發現設備和廣播更容易不受諸如 WIFI 的干擾,專門將 Advertising、Scanning、Initiating 數據收發放到了 與 WIFI 頻段隔離的部分,起到一定抗干擾作用:

除了 37、38、39 這些頻段,在 Connection 狀態下使用了 其他的 37 個 Channel通信信道,通過跳頻技術(Hopping),來減少數據干擾,增強系統的可靠性。

BLE協議棧分層

  • 協議:類似語言,如漢語、英語等。所謂協議,即將指定的字節按照一定的順序排列起來,以便他人使用自己的設備時,能通過該協議同其他設備進行通信。協議的特點,就是有固定的幀格式,通過該格式發送,接收者通過解讀幀格式,進而得到新息內容;
  • 協議棧:協議的具體實現形式,通俗可理解為代碼的實現、函數庫,供開發人員調用;
  • BLE協議棧:將藍牙各個層的協議集合在一起,以函數庫的形式體現,并提供應用層的API供用戶調用。

下圖是協議棧的結構分層:

藍牙協議分host和controller兩個部分,Host是正真意義的藍牙協議,Controller為藍牙底層,或者說是基帶芯片。
Profiles(配置文件)和應用總是基于GAP和GATT 之上。
在單芯片方案中,Controller 和HOST、Profiles、應用層都在同一個芯片上。

視頻中介紹的CC2540藍牙BLE SOC芯片可單芯片實現協議棧結構的所有組件,開發者可以直接搭建自己的應用程序。

PHY層(Physical layer 物理層)

PHY層用來指定BLE所用的無線頻段(2.4G),調制解調方式和方法、跳頻等。PHY層做得好不好,直接決定整個BLE芯片的功耗,靈敏度以及selectivity等射頻指標。

LL層(Link Layer 鏈路層)

主要是RF射頻控制,鏈路層定義了協議棧中最為基礎的狀態機、數據包格式、廣播和連接流程等問題

LL層是整個BLE協議棧的核心,也是BLE協議棧的難點和重點。像Nordic的BLE協議棧能同時支持20個link(連接),就是LL層的功勞。
LL層要做的事情非常多,比如具體選擇哪個RF射頻通道進行通信,怎么識別空中數據包,具體在哪個時間點把數據包發送出去,怎么保證數據的完整性,ACK如何接收,如何進行重傳,以及如何對鏈路進行管理和控制等等。LL層只負責把數據發送出去或者接收回來,對數據進行怎樣的解析則交給上面的GAP或者GATT。

LL層的五種RF射頻狀態:

  • Standby 待機狀態
  • Advertising 廣播狀態
  • Scaning 掃描狀態
  • Initiating 發起連接狀態
  • Connected 連接狀態

(1)Advertising、Scaning
廣播狀態下還沒有任何連接,廣播者只是單純地往外廣播數據。
掃描狀態下,掃描者僅僅接收廣播者廣播的數據。

(2)Initiating 、Connected
發起連接狀態是發起者發起的,發起者是通過發出request連接請求來響應廣播者的一個設備,如果廣播者接受了這個request則進行連接,進入Connected連接狀態。
進入連接狀態之后,發起連接的設備成為主設備,接受連接的設備成為從設備。

HCI層(Host controller interface 主機控制接口層)

HCI 層通信層,host 和 controller 提供一個標準化的傳輸接口。該層可以由軟件api 實現或者使用硬件接口 uart、spi、usb 來控制。

HCI是可選的(具體請參考文章: 三種藍牙架構實現方案(藍牙協議棧方 案)),HCI主要用于2顆芯片實現BLE協議棧的場合,用來規范兩者之間的通信協議和通信命令等。

L2CAP層(Logic link control and adaptation protocol 邏輯鏈路控制和自適應協議)

L2CAP 為上層提供數據封裝服務。層相當于快遞,將數據打包,可以讓客戶點對點的通信(允許點對多點)。

L2CAP對LL進行了一次簡單封裝,LL只關心傳輸的數據本身,L2CAP就要區分是加密通道還是普通通道,同時還要對連接間隔進行管理。

L2CAP 是BLE 藍牙的復用層,其支持數據的分割和重組,使得較大的報文可以在底層無線電中進行傳輸。L2CAP 決定了MTU size(Maximum Transmission Unit:最大傳輸單元),目前芯片支持的MTU_SIZE 為23~247 Bytes。

SMP層(Secure manager protocol 安全管理協議)

SM 層安全服務層,提供配對和密鑰的分發,實現安全連接和數據交換。

SMP用來管理BLE連接的加密和安全的,如何保證連接的安全性,同時不影響用戶的體驗,這些都是SMP要考慮的工作。

GAP層(Generic access profile 通用訪問配置文件) —— 用于連接

直接與應用程序、profile配置文件進行通信的接口,處理設備發現和連接等相關服務就是通過這一層。另外還處理安全特性的初始化,對上級提供應用接口,對下層進行配置。
GAP是對LL層payload(有效數據包)如何進行解析的兩種方式中的一種,而且是最簡單的那一種。
GAP簡單的對LL payload進行一些規范和定義,因此GAP能實現的功能極其有限。GAP目前主要用來進行廣播,掃描和發起連接等,控制LL層的五種RF狀態切換。

BLE協議棧GAP層實現了藍牙連接功能,其定義了設備的訪問模式與流程,包括:設備發現,建立連接,斷開連接,初始化安全特性,設備配置等。

GAP 狀態(待機、廣播、掃描、連接、主從)

GAP 層的藍牙狀態切換圖如圖5.3所示,每個狀態描述如下:

  • 1)待機狀態(Standby)
    設備沒有傳輸和發送數據,并且沒有連接到任何設備
  • 2)廣播狀態(Advertiser)
    周期性廣播狀態
  • 3)掃描狀態(Scanner)
    主動地尋找正在廣播的設備
  • 4)發起連接狀態(Initiator)
    主動向某個設備發起連接
  • 5)已連接,主機狀態(Master)
  • 6)已連接,從機狀態(Slave)

BLE 連接請求參數(連接間隔、廣播間隔、從機潛伏、監督超時)

BLE 連接參數包含如下:

1)連接時間間隔:
在藍牙通信過程中,所有的數據傳輸均發生在連接事件(connection interval)期間。連接事件周期性的發生,兩個連接事件間的間隔時間即為連接間隔。每個連接事件內可傳輸多個包,該芯片支持的最大傳輸包數量為8 個。
連接間隔示意圖如圖5.4所示。連接間隔單位時間為1.25ms,時間范圍為7.5ms~4.0s 之間。


2)從機潛伏:
當Slave 沒有數據發送時,允許Slave 跳過連接事件。從機潛伏值(Latency),是允許從設備跳過的最大連接次數。在連接事件中,如果Slave 沒有對Master 的包做出回應,Master 將會在后來的連接事件中重復發送,直到Slave 回應。圖5.5 為Latency=0 與Latency=3 的對比示意圖。

3)監督超時:
在每個連接事件中,主機發送信號,從機進行回應。當長時間未收到對方信號包時,藍牙將斷開,超時斷開的時間即為監督超時時間。監督超時時間單位為10ms,范圍為100ms~32s 之間。
連接參數由主機進行維護與更新,從機無法更改連接參數,但是從機可以請求主機進行連接參數更新。從機將連接參數期望值發送給主機,主機根據自身情況,選擇一個合適的連接參數更新或者拒絕更新。

4)BLE 廣播間隔

當設備處于廣播狀態時,將發送廣播信號。廣播信號發生于廣播事件中,相鄰兩個廣播事件的間隔即為廣播間隔。在每次廣播事件中,廣播包會分別在3 個廣播通道(37、38、39 信道)中被發送一次。
廣播事件如圖5.6 所示。廣播間隔單位時間為0.625ms,范圍為20ms~10.24s。

GAP Role Task(參數配置api、廣播內容、連接間隔、斷開藍牙、更新參數)

GAP Role 為一個單獨的任務,其主要實現GAP 參數的配置,例如廣播內容、連接參數更新參數等。

GAP 層的角色包含如下:

  • 1)Broadcaster:廣播者,發射不可連接廣播信號
  • 2)Observer:觀察者,進行廣播信號掃描,但不發起連接
  • 3)Peripheral:發射可連接廣播信號,并能夠被主機連接
  • 4)Central:掃描廣播信號并發起連接。

常用的API 函數包含如下:

1)獲取參數

2)設置參數

3)主動斷開藍牙

4)發送更新連接參數請求

GAP Bond Manager(GAP Bond Mgr 連接安全初始化api)

視頻里講的GAP security profiles

GAPBondMgr 用于藍牙連接時安全特性的初始化。藍牙安全特性定義如表5.5 所示。

類型描述
Pairing配對,進行密鑰交換的過程
Encryption加密,配對完成后或重新建立連接后,數據將加密
Authentication認證,在配對過程中采用了MITM 保護(如Passcode、NFC 等)
Bonding綁定,存儲加密密鑰至flash 存儲器以便下次連接使用
Authorization授權,除了認證外的一種應用層密鑰交換方式
OOB一種MITM 認證方式,密鑰交換不通過空中傳輸,如通過NFC、串口等傳輸
MITMMan in the Middle Protection. 在配對過程中,通過該方式實現了認證過程,防止通信被監聽
Just Works在配對過程中,不需要MITM,實現了密鑰傳輸

在通常的帶有安全特性的連接中,首次連接步驟如下:

  • 1)Pairing:配對,采用Just Works 或者MITM(如passcode)交換秘鑰
  • 2)Encryption:使用步驟1)的秘鑰加密鏈路
  • 3)Bonding:保存加密秘鑰至Flash

當需要重新建立連接時,可使用首次連接過程中Bonding 中的加密秘鑰,對連接鏈路進行加密。如果取消Bonding 步驟,那么每次連接均需要進行重新配對。

配對綁定配置例程如程序清單5.5 所示。

uint32 passkey = DEFAULT_PASSCODE; uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; uint8 mitm = TRUE; //開啟MITM 認證加密 uint8 ioCap = GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT; uint8 bonding = TRUE; //開啟bonding GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey ); GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode ); GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm ); GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap ); GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );

ATT(Attribute protocol 屬性協議層)

簡單來說,ATT層用來定義用戶命令及命令操作的數據,比如讀取某個數據或者寫某個數據。BLE協議棧中,開發者接觸最多的就是ATT。

ATT 層 ATT 環境中,允許設備向另外一個設備展示一塊特定的數據,稱之為“屬性” ,展示“屬性”的設備稱為服務器,與之配對的設備稱為客戶端

鏈路層LL狀態(主機和從機)與設備的 ATT 角色(服務器和客戶端)是相互獨立的,鏈路層的主機設備可以是 ATT 服務器,也可以是 ATT客戶端,從機也一樣。

BLE引入了attribute概念,用來描述一條一條的數據。Attribute除了定義數據,同時定義該數據可以使用的ATT命令,因此這一層被稱為ATT層。

GATT(Service/Characteristic的UUID主從機通信) —— 用于通信

Generic attribute profile通用屬性配置文件
GATT 層從名字就能看出,GATT 是在 ATT 上面的一層結構,定義了使用 ATT的服務框架,

GATT用來規范attribute中的數據內容,并運用group(分組)的概念對attribute進行分類管理。沒有GATT,BLE協議棧也能跑,但互聯互通就會出問題,也正是因為有了GATT和各種各樣的應用profile,BLE擺脫了ZigBee等無線協議的兼容性困境,成了出貨量最大的2.4G無線通信產品。

BLE 協議棧GATT 層用于實現兩個設備間的應用層數據通信。GATT 層采用Client/Server 架構,客戶端(Client)通過訪問服務器端(Server)的服務(Service)與特征(Characteristic),實現數據交互。
GATT 層架構如圖5.7 所示。

關于服務與特征的描述如下:

  • 用戶的應用由一個或多個服務(Service)組成的

  • 每個服務Service 包含一個或多個特征(Characteristic)

  • 每個特征(Characteristic)包含一個或多個屬性(Attribute),Attribute屬性是設備之間傳輸的信息的基本單元,GATT將這些基本單元組織成一塊一塊的數據,稱為Characteristic。屬性分別如下:

    • a. Characteristic Value:特征值
    • b. Characteristic Declaration:特征申明,描述特征的權限、類型等
    • c. Client Characteristic Configuration:允許GATT 服務器發送notification 或indication 數據。
    • d. Characteristic User Description:描述特征的ASCII 字符串

  • Characteristic Value:特征值的數據,層層解包之后最終想要的值。
  • Characteristic Declaration:特征值數據值的屬性,位置和類型。
  • Client Characteristic Configuration:配置GATT服務器主動發送出去的屬性(notified),并且期望一個回應(indicated)。
  • Characteristic User Description:描述特征值的ASCII字符串。
  • Handle:屬性表中的索引,每個屬性有一個唯一的handle。
  • Type:指示屬性數據表示的什么樣的內容,被稱為UUID。有一些UUID被SIG定義,有一些自定義。
  • Permission:限制GATT客戶端對屬性值的訪問權限,注意區分和特征值數據的訪問權限。


GATT里定了發現、讀取、寫入整個屬性過程,特征值、內容配置文件都存在屬性表中,下圖是GATT某個服務的屬性表(TI為例):


上表中,每一行就是一個屬性
第1行表示一個服務(比如溫濕度服務)的開始
第2, 3,4行是該服務的第一個Characteristic,包含了UUID、Declaration、Char Value、Description。
第5, 6,7行是該服務的第二個Characteristic。。。
特別的是第13行,作用是配置客戶端特征值,用于server主動發送數據給client。
藍牙的應用開發入門就是設定特征值的屬性表,然后調用API去接收發送屬性。

頂層profile配置文件

由兩個部分組成,處于協議棧的最頂層,將協議棧和應用層緊密的連接到一起,開發者對協議棧本身底層原理不用深入理解,就可以進行使用開發。


下面這兩個是芯海藍牙模塊開發指南的說明

Lib 庫文件

Lib 為藍牙庫文件,大部分藍牙協議棧在MASK ROM 代碼中實現,少部分藍牙協議棧代碼在Lib 庫文件中。

外設驅動

為了實現更好的移植性,協議棧將硬件層抽象出了一個HAL 硬件抽象層,當新的硬件平臺做好后,只需修改HAL,而不需修改HAL 之上的協議棧的其他組件和應用程序。

藍牙主機和從機之間傳輸數據實現

https://blog.csdn.net/happygrilclh/article/details/76290561

一款強大的芯片nRF52840及利用藍牙5.0實現數據遠程采集

https://blog.csdn.net/daocaokafei/article/details/116949986

BLE開發環境搭建

教程使用IAR,添加BLE藍牙協議棧文件,類似操作系統的OSAL

OSAL工作原理

相關博文:OSAL
STM32 OSAL操作系統抽象層的移植

OSAL 為Operating System Abstraction Layer,即操作系統抽象層,支持多任務運行,其中BLE 協議棧、配置文件以及所有的應用程序(app)都在其上運行。它并不是一個傳統意義上的操作系統,而是一個允許軟件建立和執行事件的循環。OSAL 基于消息驅動,是一個簡易的任務輪詢系統。

OSAL層一個時間內只有一個任務在運行,CPU可以使用任務調度機制策略,每個任務分配一個特定的時間片,就有點像操作系統,時間片用完了就進行任務切換,由于每個任務執行的時間很短(OSAL每個任務可能就15ms),任務切換的很頻繁,就看到一個假象,OSAL同時多個任務在運行。

OSAL 與RTOS 相比,缺少了任務堆棧,系統延時,中斷管理,進程間通信,保存上下文的任務調度。

軟件功能是由任務事件來實現的,創建一個任務事件需要以下工作:

  • 1)創建任務ID(task identifier);
  • 2)編寫任務初始化(task initialization routine)進程,并需要添加到OSAL 初始化進程中,這就是說系統啟動后不能動態添加任務;
  • 3)編寫任務處理程序;
  • 4)如有需要提供消息服務。

BLE 協議棧的各層都是以OSAL 任務方式實現,由于LL 控制任務的時間要求最為迫切,所以其任務優先級最高。為了實現任務管理,OSAL 通過消息處理(message process),存儲管理,計時器定時等附加服務實現。

OSAL 任務事件處理回調函數數組示例如程序清單5.1所示。任務事件處理函數xx_ProcessEvent 順序需與后續的osalInitTasks 函數內的Task 初始化順序一致。

先建立一個事件表,保存各任務對應的事件
再建立一個事件處理函數表,保存各任務對應的事件處理函數
將兩個表對應起來

事件處理函數表:
里面保存的都是函數指針

///< The order in this table must be identical to the task initialization calls below in osalInitTask. const pTaskEventHandlerFn tasksArr[] //都是函數指針,指向了事件處理函數 { LL_ProcessEvent, // task 0 HCI_ProcessEvent, // task 1 #if defined ( OSAL_CBTIMER_NUM_TASKS )OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 2 #endifL2CAP_ProcessEvent, // task 3SM_ProcessEvent, // task 4GAP_ProcessEvent, // task 5GATT_ProcessEvent, // task 6GAPRole_ProcessEvent, // task 7 #if (DEFAULT_GAPBOND_MGR_ENABLE==1)GAPBondMgr_ProcessEvent, // task 8 #endifGATTServApp_ProcessEvent, // task 9SimpleBLEPeripheral_ProcessEvent, // task 10 };

TASK初始化(osal_start_system調用初始化函數osalInitTasks)

為了使用OSAL,在main 函數的最后要啟動一個名叫osal_start_system 的進程,該進程會調用由特定應用決定的初始化函數osalInitTasks。osalInitTasks 函數示例如程序清單5.2所示。

事件表:

接上文程序 const uint8 tasksCnt = sizeof(tasksArr)/sizeof(tasksArr[0]); uint16 *tasksEvents;/** * @fn void osalInitTasks(void) * @brief This function invokes the initialization function for each task. * @param none * @return none */ void osalInitTasks( void ) {uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); //tasksEvents事件表首地址 通過這個指針可以訪問到事件表的每一項 //如果有事件發生,就查找函數表,找到對應事件的處理函數進行處理//處理完成繼續訪問事件表,看是否還有其他事件要發生 基于事件驅動的輪詢操作系統osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));/* LL Task */ LL_Init( taskID++ );//ID越小,優先級越高 LL控制任務的時間要求最為迫切,任務優先級最高/* 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++ );/* SM Task */SM_Init( taskID++ );/* GAP Task */GAP_Init( taskID++ );/* GATT Task */GATT_Init( taskID++ );/* Profiles */GAPRole_Init( taskID++ ); #if(DEFAULT_GAPBOND_MGR_ENABLE==1)GAPBondMgr_Init( taskID++ ); #endifGATTServApp_Init( taskID++ );/* Application */SimpleBLEPeripheral_Init( taskID );//GAP GATT的配置 視頻中串口、LED、ADC實驗也在此函數內完成 }

osalInitTasks 函數逐個調用BLE 協議棧各層的啟動進程來初始化協議棧,并設置一個任務的8bit 任務ID(task ID)。osalInitTasks 函數執行完成后,將跳入循環等待執行任務,系統啟動完成。

使用OSAL 時,注意事項如下:

  • 1)任務優先級決定于任務ID,任務ID 越小,優先級越高
  • 2)BLE 協議棧各層的任務優先級比應用程序的高。

TASK與event 處理(osal_start_system調用運行函數osal_run_system)

OSAL 完成TASK 初始化后,將調用osal_start_system 函數開始運行OSAL系統。系統是以一個死循環的形式工作的,其函數實現如程序清單5.3 所示,該代碼在MaskROM 中運行。

void osal_start_system( void ) {for(;;) // Forever Loop{osal_run_system();} }


OSAL 任務事件采用16 位變量定義,每1 位表示1 個唯一的事件標識,因此每個任務最多可定義16個不同類型事件。OSAL 事件處理流程圖如圖5.1所示。

osal_run_system 函數(在osal_start_system 函數的死循環內調用)流程如下:

  • 1)更新OSAL Timer,以便設置timeout 事件,同時將事件查詢task id 設置為0
  • 視頻中此處Hal_ProcessPoll(),HAL層信息處理
  • 2)判斷當前task id 的任務是否有事件發生,如有跳轉至步驟3),如無則進行task id 自增,并繼續執行步驟2)的判斷流程。當task id 超出任務數量時,跳轉至步驟4)
  • 3)執行tasksArr 回調函數數組內的對應xx_ProcessEvent 函數,執行完成后,退出osal_run_system 函數,并在下次循環里繼續開始整個流程。
  • 4)執行Sleep 調度,當喚醒后,繼續開始整個流程。

當事件處理程序處理完相應事件后,需要清除相應標識。如未清除相應標識,OSAL 會認為事件還沒有處理完成,后續會繼續調用相應處理函數進行處理。

如在simpleBLEPeripheral(從機) 例程中,當事件START_DEVICE_EVT 發生,其處理函數SimpleBLEPeripheral_ProcessEvent 就運行,結束后返回16bit 事件變量,并清除事件標識SBP_START_DEVICE_EVT。程序代碼如程序清單5.4 所示。

if ( events & SBP_START_DEVICE_EVT ) {……return ( events ^ SBP_START_DEVICE_EVT ); }

OSAL函數api介紹

OSAL 添加事件函數

視頻課程里介紹的這些api在OSAL.c文件里面

  • 1)立即事件
uint8 osal_set_event( uint8 task_id, uint16 event_flag ) 調用該函數后將產生立即事件。
  • 2)定時器事件
uint8 osal_start_timerEx( uint8 task_id, uint16 event_id, uint32 timeout_value ) 調用該函數將設置一個軟件定時器,超時后將產生對應事件。超時時間timeout_value 單位為ms。
  • 3)自動加載定時器事件
uint8 osal_start_reload_timer( uint8 taskID, uint16 event_id, uint32 timeout_value ); 調用該函數將設置一個自動加載的軟件定時器,超時后將產生對應事件,并自動重新加載定時器。 超時時間timeout_value 單位為ms。

OSAL內存管理函數

視頻課程里介紹的這些api在OSAL.c文件里面

OSAL 提供了基本的內存管理函數。內存管理函數定義如下:

1)內存分配

void *osal_mem_alloc( uint16 size ) 調用該函數將分配指定size 的內存空間,并返回內存首地址。當分配失敗時,將返回NULL

2)內存釋放

void osal_mem_free( void *ptr ) 調用該函數將釋放之前分配的內存空間。

OSAL消息通信函數

OSAL 消息機制實現了不同子系統之間的通信。消息即為數據,數據種類和長度都不限定。消息管理函數定義如下:

  • 1)OSAL 消息創建
uint8 * osal_msg_allocate(uint16 len ); 發送消息前,需要調用該函數創建消息占用的內存空間(內部已經包含了osal_mem_alloc 函數功 能)。需要為該函數指定空間大小,該函數返回內存空間地址指針。
  • 2)OSAL 消息發送
uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ) 將待發送的消息內容拷貝至msg_ptr 內存空間后,調用該函數向指定任務發送消息。調用該函數將產 生SYS_EVENT_MSG 事件并告知對應Task。
  • 3)OSAL 消息接收
uint8 *osal_msg_receive( uint8 task_id ) 目標Task 判斷有SYS_EVENT_MSG 事件后,將調用該函數從指定任務接收消息數據。
  • 4)OSAL 消息釋放
uint8 osal_msg_deallocate( uint8 *msg_ptr ); 消息處理完成后,需要調用該函數來釋放內存空間(內部已經包含了osal_mem_free 函數功能)。

SYS_EVENT_MSG(0x8000)是OSAL 保留的消息處理事件,所有任務均包含該事件。該事件用于消息的傳遞,即將參數從一個任務傳遞給另一個任務,詳情請參考“OSAL 消息”章節。

其他的OSAL層API函數接口

OSAL API

OSAL UART實驗

uart結構體:

uart函數:

uart調用,290行串口輸出:Hello BLE World

串口回調函數內容:

OSAL 主從機通信實驗(添加特征值)

主從機通信通過特征值實現的,類似標簽,有四個屬性:長度、讀寫、UUID、功能。

本實驗實現了R6的功能。


UUID

長度

讀寫

把char6所有的屬性加入到屬性表里

set函數添加char6


get函數添加char6


Read讀取回調函數
特征值被主機讀取或被從機通知的時候,調用這個回調函數


write寫入回調函數

change回調函數



init函數設置char6屬性參數,這里才是真正把char6屬性值設置好了

這個可有可無

連接狀態改變的時候,,可有可無

實驗現象

從機上電開始廣播,主機(比如手機藍牙助手)進行通信。

視頻中又寫了一個主機的程序,雙方通過串口轉發(透傳),方便演示:

客戶端發現事件處理




從機上電如何實現廣播

在SimpleBLEPeripheral_Init函數里面,將從機廣播功能設置為TRUE

主機自動掃描



主機連接設備



從機串口的數據處理

從機藍牙讀屬性的數據處理

主機串口數據處理

OSAL BLE獲得多個特征值句柄實驗

主機當客戶端代碼分析

添加特征值


修改事件函數simpleBLEGATTDiscoveryEvent

OSAL BLE自動重連設備實驗

默認斷開設備主機是不能重新連接的,

OSAL BLE的綁定和配對實驗

一般要輸入密碼,安全,限制非法連接

在SimpleBLEPeripheral_Init函數里面

改回調函數



不要每次都輸入密碼綁定


藍牙協議棧遇到的問題總結(主從模式、MAC地址、RSSI)

參考:藍牙4.0BLE協議棧學習筆記(二)
地址:https://blog.csdn.net/u012246376/article/details/47700477?spm=1001.2014.3001.5502

在學習開發藍牙協議棧遇到的問題總結:

1.藍牙設備號BD_ADDR就是MAC地址,不同于uuid,uuid是服務號,作為唯一標識符。

2.scanRspData數組是掃描回應數據數組,用戶可以自定義設備名。advertData數組是廣播數據數組,主要是包含在廣播里的數據信息。

3.主從機通信:
主從機通信具體流程就是 Scanning (搜索) -->Devices Found(發現從機) --> Connected (連接) --> discover Service(發現設備服務)–>讀寫characteristic(屬性)。

協議棧中的SimpleBLEPeripheral是從機模式,主要是廣播信息,讓其他設備知道。
SimpleBLECentral是主機模式,主要是與從機建立連接。
讀寫characteristic可以理解為GATT層的client向service發送數據,或者是service向client端發送數據。

主機設備可以是client(客戶端),也可以是service(服務器),即主機向從機發送數據,從機主動向主機發送數據。

主機向從機讀寫數據調用GATT_WriteCharValue函數和ATT_ReadCharValue函數。如下:

if ( simpleBLEDoWrite ) {// Do a writeattWriteReq_t req;req.handle = simpleBLECharHdl+2;req.len = 2;req.value[0] = simpleBLECharVal;req.sig = 0;req.cmd = 0;status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); if ( status == SUCCESS ) {NPI_WriteTransport(“write ok\r\n”, 10);simpleBLEProcedureInProgress = TRUE;simpleBLEDoWrite = !simpleBLEDoWrite; }else {// Do a readattReadReq_t req;req.handle = simpleBLECharHdl+2;status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); }

從機和主機發送數據機制不一樣。主機用write命令,從機用Notification通知命令。從機向主機發送數據調用GATT_Notification函數,如:

static attHandleValueNoti_t Report ; uint16 GetHandle; noti.len = 1; noti.value[0] = GetLen; GATT_Notification(GetHandle, &Report, FALSE );

4.獲取電池電量:
battMeasure函數是通過ADC采集內部電壓獲得的電壓值,參考電壓是1.25v,最大測量電壓是3.75V。如果要獲取精度較高的值需要從外部輸入引腳接入穩定性較高的參考電壓,然后通過ADC采集轉換。

if ( events &SBP_ADV_RGB_EVT ) {//P0_3=~P0_3;advertData[6]= battMeasure();//獲取電池電量GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );osal_start_timerEx(simpleBLEBroadcaster_TaskID,SBP_ADV_RGB_EVT,1000);return ( events ^ SBP_ADV_RGB_EVT ); }

5.獲取RSSI值:
通過獲取信號強度RSSI值,可以測定信號源與接收點的距離,即標簽和基站的距離。從而用相關算法進行定位。注意的是由于受到脈沖干擾等會出現浮動值,需要進行濾波算法來獲得比較準確的采樣值。

case GAP_DEVICE_INFO_EVENT: {if( (pEvent->deviceInfo.pEvtData+7)==0xA7)simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType, pEvent->deviceInfo.rssi ,(pEvent->deviceInfo.pEvtData+6)); } break;

IOS藍牙iBeacon協議(UUID、Major、Minor、RSSI)

ibeacon和藍牙有什么區別_它們的區別在哪里

7-iBeacon參數

藍牙IBEACON協議案例詳細解析

手機藍牙APP工具的使用(nrf Connect)

摘自:nrf Connect低功耗藍牙APP工具的使用

APP下載: nRF Master Control Panel (BLE)
安卓、IOS平臺都有
該APP可以實現SCANER和ADVERTER兩種角色
下面主要來講講SCANER角色的使用

掃描者

點擊SCAN或者下拉界面,可以刷新設備列表,右滑界面可以看到每個設備的信號強度的變化曲線圖,不同顏色代表不同的設備。

連接設備

測試設備的設備名稱GCBT40-my,點擊CONNECT
連接成功后會自動獲取所有的服務UUID

可寫與可監聽

設備GCBT40-my發布了服務UUID=0xff10,
特征值UUID=0xff11為可寫操作(點擊圖標”↑“),特征值UUID=0xff12為可監聽操作(點擊圖標”↓↓↓“),

寫操作(APP到從設備)

寫操作,數據從APP端發送到從設備端

點擊寫操作后,可以選擇輸入數據的格式,TEXT為字符串格式,可以先在Save as里輸入數據,再點SAVE保存,下次可以直接在LOAD里發送該數據包

監聽操作(從設備到APP0)

數據從從設備端發送到APP端

點擊圖標”↓↓↓“后,APP后臺自動監聽從設備notify上來的數據,右滑界面,可以看到接收到的每條數據

JDY-10M藍牙模塊使用教程(AT指令)

參考:千鋒嗨哥_物聯網_嵌入式開發與應用教程(教程包含藍牙、4G、WIFI、NB-iot、ZigBee等)
地址:https://www.bilibili.com/video/BV1Ui4y1s71B?p=52

藍牙開發介紹


JDY-10M模塊介紹




JDY-10M引腳說明



普通數據收發AT指令
使用AT指令,隱藏了底層的藍牙通信協議棧


控制功能數據AT指令

手機APP通信



總結

以上是生活随笔為你收集整理的蓝牙BLE(协议栈、OSAL、蓝牙APP工具)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。