在藍(lán)牙協(xié)議棧開(kāi)發(fā)過(guò)程中,有時(shí)需要預(yù)先知道 LLCP。本文將介紹如何利用 Trace 機(jī)制實(shí)現(xiàn) LLCP 預(yù)覽功能。
實(shí)現(xiàn)原理
打開(kāi) TracePLATFORM_TRACE_ID_LLCP類型,Controller 會(huì)在接收到 LLCP 時(shí)通過(guò) Trace 回調(diào)函數(shù)導(dǎo)出數(shù)據(jù)。 我們可以在回調(diào)函數(shù)里截獲PLATFORM_TRACE_ID_LLCP,并預(yù)覽數(shù)據(jù)。這個(gè)的“預(yù)覽”包含兩層含義:
Controller 尚未處理該 PDU(Controller 將于 Trace 回調(diào)完成后處理 PDU);
只可讀取 PDU 內(nèi)容,不可修改。
讓我們?cè)敿?xì)介紹實(shí)現(xiàn)方法。
1.Trace數(shù)據(jù)結(jié)構(gòu)
PLATFORM_TRACE_ID_LLCPTrace 類型使用的頭信息結(jié)構(gòu)如下:
#pragmapack (push, 1)
typedefstruct
{
uint32_tA;
uint32_tB;
uint8_t id;
uint8_t tag;
}header_t;
#pragmapack (pop)
這個(gè)結(jié)構(gòu)使用#pragmapack (push, 1)指令確保內(nèi)存對(duì)齊。
2.Trace回調(diào)處理
假設(shè)cb_trace_read_llcp函數(shù)為 Trace 回調(diào)函數(shù),在函數(shù)開(kāi)頭添加代碼截獲接收到的 LLCP:
staticuint32_tcb_trace_read_llcp(constplatform_evt_trace_t*Trace,void*ctx)
{
if(Trace->len1 ==sizeof(header_t))
{
constheader_t*p = (constheader_t*)Trace->data1;
if((p->id == PLATFORM_TRACE_ID_LLCP) && (p->tag &1))
{
constuint8_t*p8 = (constuint8_t*)Trace->data2;
llcp_preview(p->tag >>1, p8[0], p8 +1, Trace->len2 -1);
}
}
// ...
return0;
}
3.PUD預(yù)覽顯示
llcp_preview函數(shù)負(fù)責(zé)預(yù)覽 LLCP。下面的參考代碼打印了關(guān)于 LLCP 的完整信息:
連接句柄(handle)
操作碼(op_code)
控制數(shù)據(jù)
staticvoidllcp_preview(hci_con_handle_thandle,uint8_top_code,constuint8_t*ctr_data,intctr_data_len)
{
platform_printf("LLCP[%d] OP %02x: ", handle, op_code);
printf_hexdump(ctr_data, ctr_data_len);
platform_printf("
");
}
特殊用法
目前 SDK 未提供設(shè)置公司 ID 的接口,暫時(shí)可以通過(guò)直接修改LLCP_VERSION_IND內(nèi)容的方法修改公司 ID(修改這個(gè)值不影響 Controller 的行為和流程。) 在下面的代碼里,公司 ID 被修改為0xABCD,小版本號(hào)被修改為0x1234。
#pragmapack (push, 1)
typedefstruct
{
uint8_t version;
uint16_tcompany_id;
uint16_tsubversion;
}llcp_version_ind_t;
#pragmapack (pop)
staticuint32_tcb_trace_read_llcp(constplatform_evt_trace_t*trace,void*ctx)
{
if(trace->len1 ==sizeof(header_t))
{
constheader_t*p = (constheader_t*)trace->data1;
// 判斷是否為發(fā)送方向的 LLCP
if((p->id == PLATFORM_TRACE_ID_LLCP) && (0== (p->tag &1)))
{
constuint8_t*p8 = (constuint8_t*)trace->data2;
constuint16_tcon_handle = p->tag >>1;
constuint8_t op_code = p8[0];
constintctrl_data_len = trace->len2 -1;
uint8_t* ctrl_data = (uint8_t*)p8 +1;
// 判斷是否為 LLCP_VERSION_IND
if((op_code ==0x0c) && (ctrl_data_len ==sizeof(llcp_version_ind_t)))
{
llcp_version_ind_t*ver_ind = (llcp_version_ind_t*)(ctrl_data);
ver_ind->company_id =0xABCD;
ver_ind->subversion =0x1234;
}
}
}
// ...
return0;
}
總結(jié)
利用 Trace 機(jī)制實(shí)現(xiàn)的 PDU 預(yù)覽功能,能幫助開(kāi)發(fā)者實(shí)時(shí)監(jiān)控 LLCP 通信,實(shí)現(xiàn)必要功能。
溫馨提示:不要忘記設(shè)置PLATFORM_CFG_TRACE_MASK,其中要包含PLATFORM_TRACE_ID_LLCP。
-
藍(lán)牙
+關(guān)注
關(guān)注
119文章
6271瀏覽量
178150 -
Trace
+關(guān)注
關(guān)注
0文章
20瀏覽量
10953 -
PDU
+關(guān)注
關(guān)注
0文章
100瀏覽量
17672 -
回調(diào)函數(shù)
+關(guān)注
關(guān)注
0文章
95瀏覽量
12149
原文標(biāo)題:《軟件設(shè)計(jì)指南》之四-基于 Trace 實(shí)現(xiàn) LLPC預(yù)覽功能
文章出處:【微信號(hào):INGCHIPS_OFFICIAL,微信公眾號(hào):桃芯科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
請(qǐng)問(wèn)STM32H7是否支持Trace功能?
程序的TRACE需求及功能
IAR EWARM的SWO Trace調(diào)試功能
使用IAR ETM Trace調(diào)試功能的要求
如何利用STM32實(shí)現(xiàn)紅外收發(fā)機(jī)制的人體感應(yīng)設(shè)計(jì)?
如何利用pdf.js 實(shí)現(xiàn)在前端預(yù)覽 .pdf 文件?
MDK上如何使用ULINK2設(shè)備上的SW調(diào)試實(shí)現(xiàn)STM32的trace功能?
如何使用SEGGER J-Trace Pro流模式實(shí)現(xiàn)指令跟蹤功能?
Trace32的高級(jí)功能特性
Trace輔助工具實(shí)現(xiàn)代碼分析與實(shí)時(shí)覆蓋率統(tǒng)計(jì)
如何利用Trace機(jī)制實(shí)現(xiàn)LLCP預(yù)覽功能
評(píng)論