DWT跟蹤組件
跟蹤組件:數(shù)據(jù)觀察點(diǎn)與跟蹤(DWT)
DWT 中有剩余的計(jì)數(shù)器,它們典型地用于程序代碼的“性能速寫(xiě)”(profiling)。通過(guò)編程它們,就可以讓它們?cè)谟?jì)數(shù)器溢出時(shí)發(fā)出事件(以跟蹤數(shù)據(jù)包的形式)。
最典型地,就是使用 CYCCNT寄存器來(lái)測(cè)量執(zhí)行某個(gè)任務(wù)所花的周期數(shù),這也可以用作時(shí)間基準(zhǔn)相關(guān)的目的(操作系統(tǒng)中統(tǒng)計(jì) CPU使用率可以用到它)。
Cortex-M中的DWT
在Cortex-M里面有一個(gè)外設(shè)叫DWT(Data Watchpoint and Trace),是用于系統(tǒng)調(diào)試及跟蹤。
它有一個(gè)32位的寄存器叫CYCCNT,它是一個(gè)向上的計(jì)數(shù)器,記錄的是內(nèi)核時(shí)鐘運(yùn)行的個(gè)數(shù),內(nèi)核時(shí)鐘跳動(dòng)一次,該計(jì)數(shù)器就加1,精度非常高,如果內(nèi)核時(shí)鐘是72M,那精度就是1/72M = 14ns,而程序的運(yùn)行時(shí)間都是微秒級(jí)別的,所以14ns的精度是遠(yuǎn)遠(yuǎn)夠的。
最長(zhǎng)能記錄的時(shí)間為:59.65s。計(jì)算方法為2的32次方/72000000。
當(dāng)CYCCNT溢出之后,會(huì)清0重新開(kāi)始向上計(jì)數(shù)。
使用方法
要實(shí)現(xiàn)延時(shí)的功能,總共涉及到三個(gè)寄存器:DEMCR 、DWT_CTRL、DWT_CYCCNT,分別用于開(kāi)啟DWT功能、開(kāi)啟CYCCNT及獲得系統(tǒng)時(shí)鐘計(jì)數(shù)值。
DEMCR
想要使能DWT外設(shè),需要由另外的內(nèi)核調(diào)試寄存器DEMCR的位24控制,寫(xiě)1使能(劃重點(diǎn)啦,要考試?。。?。DEMCR的地址是0xE000 EDFC
關(guān)于DWT_CYCCNT
使能DWT_CYCCNT寄存器之前,先清0。讓我們看看DWT_CYCCNT的基地址,從ARM-Cortex-M手冊(cè)中可以看到其基地址是0xE000 1004,復(fù)位默認(rèn)值是0,而且它的類(lèi)型是可讀可寫(xiě)的,我們往0xE000 1004這個(gè)地址寫(xiě)0就將DWT_CYCCNT清0了。
關(guān)于CYCCNTENA
CYCCNTENA Enable the CYCCNT counter. If not enabled, the counter does not count and no event is generated for PS sampling or CYCCNTENA. In normal use, the debugger must initialize the CYCCNT counter to 0.
它是DWT控制寄存器的第一位,寫(xiě)1使能,則啟用CYCCNT計(jì)數(shù)器,否則CYCCNT計(jì)數(shù)器將不會(huì)工作。
【https://developer.arm.com/documentation/ddi0337/e/system-debug/dwt/summary-and-description-of-the-dwt-registers?lang=en】
綜上所述
想要使用DWT的CYCCNT步驟:
先使能DWT外設(shè),這個(gè)由另外內(nèi)核調(diào)試寄存器DEMCR的位24控制,寫(xiě)1使能
使能CYCCNT寄存器之前,先清0。
使能CYCCNT寄存器,這個(gè)由DWT的CYCCNTENA 控制,也就是DWT控制寄存器的位0控制,寫(xiě)1使能
寄存器定義:
//0xE000EDFCDEMCRRWDebugExceptionandMonitorControlRegister. //使能DWT模塊的功能位 #defineDEMCR(*(unsignedint*)0xE000EDFC) #defineTRCENA(0x01<24)?//?DEMCR的DWT使能位?? ?? //0xE0001000?DWT_CTRL?RW?The?Debug?Watchpoint?and?Trace?(DWT)?unit?? //使能CYCCNT計(jì)數(shù)器開(kāi)始計(jì)數(shù) #define?DWT_CTRL????????(?*(unsigned?int?*)0xE0001000?)?? #define?CYCCNTENA???????(?0x01?<0?)?//?DWT的SYCCNT使能位 ? //0xE0001004?DWT_CYCCNT?RW?Cycle?Count?register,??? //CYCCNT計(jì)數(shù)器的內(nèi)部值(32位無(wú)符號(hào)) #define?DWT_CYCCNT??????(?*(unsigned?int?*)0xE0001004)?//顯示或設(shè)置處理器的周期計(jì)數(shù)值??
用法示例:
vvolatileunsignedint*DWT_CYCCNT; volatileunsignedint*DWT_CONTROL; volatileunsignedint*SCB_DEMCR; voidreset_timer(){ DWT_CYCCNT=(int*)0xE0001004;//addressoftheregister DWT_CONTROL=(int*)0xE0001000;//addressoftheregister SCB_DEMCR=(int*)0xE000EDFC;//addressoftheregister *SCB_DEMCR=*SCB_DEMCR|0x01000000; *DWT_CYCCNT=0;//resetthecounter *DWT_CONTROL=0; } voidstart_timer(){ *DWT_CONTROL=*DWT_CONTROL|1;//enablethecounter } voidstop_timer(){ *DWT_CONTROL=*DWT_CONTROL|0;//disablethecounter } unsignedintgetCycles(){ return*DWT_CYCCNT; } main(){ .... reset_timer();//resettimer start_timer();//starttimer //Codetoprofile ... myFunction(); ... stop_timer();//stoptimer numCycles=getCycles();//readnumberofcycles ... }
示例2:
#definestart_timer()*((volatileuint32_t*)0xE0001000)=0x40000001//EnableCYCCNTregister #definestop_timer()*((volatileuint32_t*)0xE0001000)=0x40000000//DisableCYCCNTregister #defineget_timer()*((volatileuint32_t*)0xE0001004)//GetvaluefromCYCCNTregister /*********** *Howtouse: *uint32_tit1,it2;//startandstopflag start_timer();//startthetimer. it1=get_timer();//storecurrentcycle-countinalocal //dosomething it2=get_timer()-it1;//Derivethecycle-countdifference stop_timer();//Iftimerisnotneededanymore,stop print_int(it2);//Displaythedifference ****/
示例3:
#defineDWT_CR*(uint32_t*)0xE0001000 #defineDWT_CYCCNT*(uint32_t*)0xE0001004 #defineDEM_CR*(uint32_t*)0xE000EDFC #defineDEM_CR_TRCENA(1<24) ? #define??DWT_CR_CYCCNTENA????????????????(1?<?0) ? /*?初始化時(shí)間戳?*/ ? void?CPU_TS_TmrInit(void) ? { ? ????????/*?使能DWT外設(shè)?*/ ????????DEM_CR?|=?(uint32_t)DEM_CR_TRCENA;??????????????? ? ????????/*?DWT?CYCCNT寄存器計(jì)數(shù)清0?*/ ????????DWT_CYCCNT?=?(uint32_t)0u; ??????? ? ????????/*?使能Cortex-M3?DWT?CYCCNT寄存器?*/ ????????DWT_CR?|=?(uint32_t)DWT_CR_CYCCNTENA; ? } ? uint32_t?OS_TS_GET(void) {??????? ? ????????return?((uint32_t)DWT_CYCCNT); ? }
-
單片機(jī)
+關(guān)注
關(guān)注
6040文章
44592瀏覽量
636901 -
計(jì)數(shù)器
+關(guān)注
關(guān)注
32文章
2259瀏覽量
94806 -
調(diào)試
+關(guān)注
關(guān)注
7文章
583瀏覽量
33999 -
DWT
+關(guān)注
關(guān)注
0文章
20瀏覽量
11154 -
Cortex-M
+關(guān)注
關(guān)注
2文章
229瀏覽量
29788
原文標(biāo)題:一個(gè)超級(jí)實(shí)用的單片機(jī)調(diào)試組件!
文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論