我正在嘗試使用ARM Cortex-a9上的事件計數器(在Xilinx zynq EPP上)來計數週期。爲此,我已經調整了ARM的一些ARM示例代碼。我正在用GNU ARM EABI編譯器編寫這個裸機。ARM Cortex-a9事件計數器返回0
我理解使用PMU的方式是,您首先必須啓用PMU。
void enable_pmu (void){
asm volatile( "MRC p15, 0, r0, c9, c12, 0\n\t"
"ORR r0, r0, #0x01\n\t"
"MCR p15, 0, r0, c9, c12, 0\n\t"
);
}
然後再配置性能計數器計數(在這種情況下,對於週期0x11
)某種類型的事件
void config_pmn(unsigned counter,int event){
asm volatile( "AND %[counter], %[counter], #0x1F\n\t" :: [counter] "r" (counter)); //Mask to leave only bits 4:0
asm volatile( "MCR p15, 0, %[counter], c9, c12, 5\n\t" :: [counter] "r" (counter)); //Write PMSELR Register
asm volatile( "ISB\n\t"); //Synchronize context
asm volatile( "MCR p15, 0, %[event], c9, c13, 1\n\t" :: [event] "r" (counter)); //Write PMXEVTYPER Register
}
然後啓用事件計數器
void enable_pmn(int counter){
asm volatile( "MOV r1, #0x1\n\t");
asm volatile( "MOV r1, r1, LSL %[counter]\n\t" :: [counter] "r" (counter));
asm volatile( "MCR p15, 0, r1, c9, c12, 1\n\t"); //Write PMCNTENSET Register
}
在此之後您立即重置事件計數器
void reset_pmn(void){
asm volatile( "MRC p15, 0, r0, c9, c12, 0\n\t"); //Read PMCR
asm volatile( "ORR r0, r0, #0x2\n\t"); //Set P bit (Event counter reset)
asm volatile( "MCR p15, 0, r0, c9, c12, 0\n\t"); //Write PMCR
}
你讓你的應用程序運行和讀取事件計數器
int read_pmn(int counter){
int value;
asm volatile( "AND %0,%0, #0x1F\n\t" :: "r" (counter)); //Mask to leave only bits 4:0
asm volatile( "MCR p15, 0, %[counter], c9, c12, 5\n\t" ::[counter] "r" (counter)); //Write PMSELR Register
asm volatile( "ISB\n\t"); //Synchronize context
asm volatile( "MRC p15, 0,%[value] , c9, c13, 2\n\t" : [value] "=r" (value)); //Read current PMNx Register
return value;
}
然後禁用事件計數器
void disable_pmn(int counter){
asm volatile( "MOV r1, #0x1\n\t");
asm volatile( "MOV r1, r1, LSL %[counter] \n\t":: [counter] "r" (counter));
asm volatile( "MCR p15, 0, r1, c9, c12, 2\n\t"); //Write PMCNTENCLR Register
}
和PMU。
void disable_pmu (void){
asm volatile( "MRC p15, 0, r0, c9, c12, 0\n\t"
"BIC r0, r0, #0x01\n\t"
"MCR p15, 0, r0, c9, c12, 0\n\t"
);
}
然而,當我嘗試讀取存儲在事件計數器的值,我得到0。我知道,因爲我能沒有問題,讀入週期計數器(PMCCNTR
)我的PMU配置是否正確。我配置計數器的方式或閱讀方式可能存在問題。這個內聯彙編對我來說是非常新穎的,所以如果有人能指引我朝着正確的方向發展,我將永遠感激。
參見[皮質-A8 PMNC](http://stackoverflow.com/questions/15492120/arm-cortex-a8-pmnc-read-gives-0-after-enabling-also-any-idea-suggestions)和[Cortex-a8 profiling](http://stackoverflow.com/questions/15524138/profling-on-arm-cortex-a8),它們可能會有所幫助。假設是Linux [perf_event_v7.c](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/kernel/perf_event_v7.c)用於Cortex CPU afaik。這可能是簡單的事情;我總是遇到'MCR' /'MRC'參數的問題。 – 2013-04-26 22:50:53
您還有一些* in-line彙編程序*的問題。在很多情況下,你修改'計數器',但不要註釋這個。此外,您正在使用硬編碼的'r0','r1',但未指定此項。您可以在同一個'asm'語句中將多個* asm操作碼*組合在一起。只需使用'\ n';您不需要多次指定參數,但是要正確地指定參數。另外[A8](http://stackoverflow.com/questions/3247373/how-to-measure-program-execution-time-in-arm-cortex-a8-processor)[A8-2](http:// stackoverflow的.com /問題/ 9795132 /測量執行的時間啓動臂-皮質-使用A8-硬件計數器) – 2013-04-26 23:03:59