threadx的trace源碼分析--Apple的學(xué)習(xí)筆記

一颂郎,前言

之前做了基于Segger RTT的上下位機(jī)谒获,來測試os的task調(diào)度扳埂。我向來對整體系統(tǒng)(上下位機(jī)的通信很感興趣)知道了RTT的原理业簿,所以就進(jìn)行了資源利用,后來底層我改成了自己寫的精簡FIFO聂喇,也很好用辖源。那么threadx的traceX模塊設(shè)計(jì)是否也能為我所用呢蔚携!

二,帶著問題看源碼

1. threadx中的traceX模塊的上下位機(jī)設(shè)計(jì)原理和RTT一樣嗎克饶?
答:不一樣酝蜒。我看了Azure RTOS TraceX的使用,它描述是轉(zhuǎn)儲(將內(nèi)存數(shù)據(jù)轉(zhuǎn)為s19等上位機(jī)工具支持的格式)矾湃,而且是事后查看亡脑。于是我去看了單片機(jī)端的code,就找到了TX_TRACE_IN_LINE_INSERT邀跃。也就是FIFO進(jìn)入的函數(shù)霉咨,沒有找到退出的函數(shù),且用循環(huán)覆蓋來實(shí)現(xiàn)環(huán)形FIFO拍屑。所以我理解上位機(jī)是不支持實(shí)時(shí)查看的途戒,等于單片機(jī)一直把log放入FIFO內(nèi)存,等用戶暫停調(diào)試單片機(jī)的時(shí)候僵驰,可以將內(nèi)存取出轉(zhuǎn)儲后喷斋,通過上位機(jī)來查看切換情況。

2.TX_TRACE_IN_LINE_INSERT入隊(duì)列中怎么沒有開關(guān)中斷蒜茴?
答:RTT主要用來實(shí)時(shí)打印及和上位機(jī)交互數(shù)據(jù)的(其實(shí)是用來代替串口的)星爪,所用不同優(yōu)先級的task會去調(diào)用它的寫數(shù)據(jù)函數(shù),就存在一個(gè)是否函數(shù)可重入的問題粉私,由于多個(gè)task用一個(gè)資源顽腾,那么就需要用到互斥,也就是要加開關(guān)全局中斷的诺核。當(dāng)然抄肖,全局開關(guān)中斷也不能加太多,否則會影響整體系統(tǒng)運(yùn)行猪瞬,但是不添加的話憎瘸,可能打印的log準(zhǔn)確性可能會有問題,這在使用的時(shí)候可以綜合考慮陈瘦。
threadx的trace log功能僅僅是向內(nèi)存寫入事件切換的時(shí)間戳及相關(guān)對象的4個(gè)附帶信息。那么若僅在切換的時(shí)候?qū)懭氤笔郏蛘哒f是os 切換各種事件的時(shí)候?qū)懭肴睿敲次依斫獠辉趖ask或中斷運(yùn)行時(shí)候?qū)懭刖筒淮嬖诖驍鄦栴},因?yàn)樗写驍喽际莖s切換導(dǎo)致的酥诽,若僅在os切換事件的時(shí)候?qū)懭氚叭涂梢圆挥锰砑娱_關(guān)中斷。

3.循環(huán)隊(duì)列成員為什么都用指針
答:循環(huán)隊(duì)列之前了解的比較多肮帐。設(shè)計(jì)時(shí)候結(jié)構(gòu)體用數(shù)組的比較多咖驮,單鏈表方式也有边器,里面特別的元素成員就是size和溢出flag。這里的設(shè)計(jì)直接用end和start地址托修,所以省略了size忘巧。關(guān)于溢出的判斷也變簡單了,就是start==end地址說明溢出了睦刃。我理解這是不同的用途導(dǎo)致FIFO設(shè)計(jì)時(shí)候使用的結(jié)構(gòu)體也設(shè)計(jì)的不同砚嘴,因?yàn)榇藅race功能只有FIFO輸入沒有輸出,所有size成員用途不大涩拙。稍微功能有點(diǎn)點(diǎn)區(qū)別际长,就可以考慮更為優(yōu)化的設(shè)計(jì)了。設(shè)計(jì)真是千變?nèi)f化呢兴泥,這就是編碼吸引我的地方工育,可以自由創(chuàng)作,然后尋找最優(yōu)方案搓彻。

三如绸,traceX底層源碼分析

官網(wǎng)先看了help,也把traceX上位機(jī)軟件打開對照字段看了下好唯。還是很容易理解它的設(shè)計(jì)的竭沫。主的一個(gè)結(jié)構(gòu)體對象中,包括了obj和buffer成員骑篙。
為什么要obj和buffer2個(gè)成員呢蜕提?原因就是buffer的后面4個(gè)u32字節(jié)為每個(gè)obj成員特有的,所以trace對象就包括了obj和buffer2個(gè)成員靶端,buffer可以引用obj的數(shù)據(jù)谎势。上位機(jī)用的就是buffer成員。
最簡單的看代碼的方法就是先看數(shù)據(jù)結(jié)構(gòu)杨名,因?yàn)閿?shù)據(jù)解構(gòu)決定算法設(shè)計(jì)脏榆。

/* Define the an Trace Buffer Entry.  */
 typedef struct TX_TRACE_BUFFER_ENTRY_STRUCT
{

    ULONG                    tx_trace_buffer_entry_thread_pointer;
    ULONG                    tx_trace_buffer_entry_thread_priority;
    ULONG                    tx_trace_buffer_entry_event_id;
    ULONG                    tx_trace_buffer_entry_time_stamp;
#ifdef TX_MISRA_ENABLE
    ULONG                    tx_trace_buffer_entry_info_1;
    ULONG                    tx_trace_buffer_entry_info_2;
    ULONG                    tx_trace_buffer_entry_info_3;
    ULONG                    tx_trace_buffer_entry_info_4;
#else
    ULONG                    tx_trace_buffer_entry_information_field_1;
    ULONG                    tx_trace_buffer_entry_information_field_2;
    ULONG                    tx_trace_buffer_entry_information_field_3;
    ULONG                    tx_trace_buffer_entry_information_field_4;
#endif
} TX_TRACE_BUFFER_ENTRY;
traceX的上位機(jī)截圖.png

代碼的結(jié)構(gòu)體和上位機(jī)的截圖前8個(gè)完全對應(yīng),所以就是從單片機(jī)獲取的數(shù)據(jù)台谍。對應(yīng)的4個(gè)不同內(nèi)容也有注釋须喂,比如queue對象,就有queue prt,destination ptr,wait option和enqueued和上位機(jī)一致趁蕊。

/* I1 = queue ptr, I2 = destination ptr, I3 = wait option, I4 = enqueued    */
#define TX_TRACE_QUEUE_RECEIVE                              68          
/* I1 = queue ptr, I2 = source ptr, I3 = wait option, I4 = enqueued         */
#define TX_TRACE_QUEUE_SEND                                 69          

再看看源碼中TX_TRACE_IN_LINE_INSERT宏函數(shù)坞生,賦值8個(gè)字段,全部可以對應(yīng)上掷伙。

trace_event_ptr -> tx_trace_buffer_entry_thread_pointer = (ULONG) trace_thread_ptr; \
trace_event_ptr -> tx_trace_buffer_entry_thread_priority = (ULONG) trace_priority; \
trace_event_ptr -> tx_trace_buffer_entry_event_id = (ULONG) (i); \
trace_event_ptr -> tx_trace_buffer_entry_time_stamp = (ULONG) TX_TRACE_TIME_SOURCE; \
TX_TRACE_INFO_FIELD_ASSIGNMENT((a),(b),(c),(d)) \

我之前說它是FIFO且覆蓋方式代碼如下是己,完成current的指針賦值8個(gè)字段后,就指向下一個(gè)空閑內(nèi)容任柜,且判斷下一個(gè)空閑內(nèi)容是否為end卒废,若為end就指向start沛厨。

trace_event_ptr++; \
if (trace_event_ptr >= _tx_trace_buffer_end_ptr) \
{ \
     trace_event_ptr =  _tx_trace_buffer_start_ptr; \
     _tx_trace_buffer_current_ptr =  trace_event_ptr;  \
     _tx_trace_header_ptr -> tx_trace_header_buffer_current_pointer =  (ULONG) trace_event_ptr; \
     if (_tx_trace_full_notify_function) \
                (_tx_trace_full_notify_function)((VOID *) _tx_trace_header_ptr); \
} \
else \
{ \
     _tx_trace_buffer_current_ptr =  trace_event_ptr;  \
      _tx_trace_header_ptr -> tx_trace_header_buffer_current_pointer =  (ULONG) trace_event_ptr; \
} \

這里可圈可點(diǎn)的內(nèi)容如下,就是剛進(jìn)入函數(shù)時(shí)候的if判斷是否使能摔认。而且用的是mask對象的方式逆皮,我之前自己設(shè)計(jì)沒有考慮到此項(xiàng),這樣就可以實(shí)現(xiàn)通過宏定義來配置使能某些想觀察的對象级野。而非控制所有页屠,可以用來調(diào)整的顆粒度為obj對象。這是本次閱讀源碼設(shè)計(jì)最大的收獲蓖柔。

#define TX_TRACE_IN_LINE_INSERT(i,a,b,c,d,e) \
        { \
        TX_TRACE_BUFFER_ENTRY     *trace_event_ptr; \
        ULONG                      trace_system_state; \
        ULONG                      trace_priority; \
        TX_THREAD                 *trace_thread_ptr; \
            trace_event_ptr =  _tx_trace_buffer_current_ptr; \
            if ((trace_event_ptr) && (_tx_trace_event_enable_bits & ((ULONG) (e)))) \
            { \
               ...
            } \

四辰企,小結(jié)

同樣的模板字段可以輸出不同的含義內(nèi)容,這就是buffer復(fù)用的思想况鸣。這樣就可以使用同一的框架牢贸,這樣的設(shè)計(jì)思想我也可以借鑒。另外镐捧,對不同對象進(jìn)行mask使能的方式也很有用潜索。哈哈,收獲頗豐~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末懂酱,一起剝皮案震驚了整個(gè)濱河市竹习,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌列牺,老刑警劉巖整陌,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞎领,居然都是意外死亡泌辫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門九默,熙熙樓的掌柜王于貴愁眉苦臉地迎上來震放,“玉大人,你說我怎么就攤上這事驼修〉钏欤” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵乙各,是天一觀的道長勉躺。 經(jīng)常有香客問我,道長觅丰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任妨退,我火速辦了婚禮妇萄,結(jié)果婚禮上蜕企,老公的妹妹穿的比我還像新娘。我一直安慰自己冠句,他們只是感情好轻掩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著懦底,像睡著了一般唇牧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聚唐,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天丐重,我揣著相機(jī)與錄音,去河邊找鬼杆查。 笑死扮惦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的亲桦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酣溃!你這毒婦竟也來了矩屁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舔琅,失蹤者是張志新(化名)和其女友劉穎等恐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搏明,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鼠锈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了星著。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片购笆。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虚循,靈堂內(nèi)的尸體忽然破棺而出同欠,到底是詐尸還是另有隱情,我是刑警寧澤横缔,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布铺遂,位于F島的核電站,受9級特大地震影響茎刚,放射性物質(zhì)發(fā)生泄漏襟锐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一膛锭、第九天 我趴在偏房一處隱蔽的房頂上張望粮坞。 院中可真熱鬧蚊荣,春花似錦、人聲如沸莫杈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筝闹。三九已至媳叨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間关顷,已是汗流浹背糊秆。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留解寝,地道東北人扩然。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像聋伦,于是被迫代替她去往敵國和親夫偶。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容