generic timer介紹
armv7-A架構中每個CPU核心都包含自己的私有定時器,所有cpu的定時器共享一個System counter, System counter負責產生計數,傳遞到每個核心的私有定時器,架構如下圖所示:
該定時器可以產生中斷,作為系統心跳使用,類似于cortex-M的systick,詳細的中斷號在DDI0471B_gic400_r0p1_trm.pdf中有說明,下面PPI中斷號的截圖說明:
gtimer寄存器介紹
armv7-A架構中generic timer寄存器如下圖所示:
在ARMv7-A中定義了不同的特權級別,分別是PL0, PL1, PL2,PL0是普通用戶模式,在PL1、PL2模式下分別有對應的定時器。
下面介紹PL1模式下的定時器,也就是svc、FIQ模式下的定時器,rt-thread的宏內核版本運行在svc模式下,所以我們著重研究PL1物理定時器的使用。
關鍵寄存器說明
CNTFRQ寄存器是定時器頻率值,這個需要根據實際的硬件情況設置,在全志平臺上是24M,這個必須設置, 操作寄存器的內聯匯編代碼:
asm volatile("MCR p15, 0 , %0, c14, c0, 0" : : "r" (Rt) : "memory" )
CNTPCT是物理計數器寄存器,這個寄存器是64位的,寄存器值會一直累加,根據CNTFRQ寄存器中的頻率進行累加,所以這個值可以作為時間tick來使用,在一些需要簡短的延時場景可以借助這個計數器。獲取計數器值的代碼:
uint64_t get_arch_counter(void)
{
uint32_t low=0, high = 0;
asm volatile("mrrc p15, 0, %0, %1, c14"
: "=r" (low), "=r" (high) |
---|
: "memory"); |
return (((uint64_t)high)<<32 |
} |
CNTP_TVAL寄存器, 這個寄存器一般在開啟gtimer的中斷時使用。
寫入CNTP_TVAL寄存器時,硬件會自動把該值加上System Counter的值,一并寫入CNTP_CVAL寄存器中,作為下一次中斷的時基。內聯匯編偽代碼如下:
asm volatile("MCR p15, 0 , %0, c14, c2, 0" : : "r" (Rt) : "memory" )
特別說明
CNTP_CVAL = CNTP_TVAL + System Counter。
CNTP_CVAL寄存器,該寄存器是比較寄存器,當System Counter的值大于等于CNTP_CVAL的值時產生中斷,如果需要改寫此寄存器的值可以,通過寫入CNTP_TVAL來實現,避免讀改寫寄存器的繁瑣操作。
CNTP_CTL是PL1物理定時器的控制寄存器, 操作的內聯匯編代碼如下:
asm volatile("MCR p15, 0 , %0, c14, c2,
CNTP_CTL寄存器控制位說明:
其中bit0負責使能定時器,bit1是否打開中斷信號。
PL1物理定時器的中斷號,在全志平臺是29,其他CPU平臺待驗證。
詳細gtimer操作代碼可以參考rt-thread源碼目錄中libcpu->cortex-a中的gtimer.c文件。
-
計數器
+關注
關注
32文章
2256瀏覽量
94568 -
ARM處理器
+關注
關注
6文章
360瀏覽量
41742 -
定時器
+關注
關注
23文章
3248瀏覽量
114800 -
控制寄存器
+關注
關注
0文章
34瀏覽量
11489 -
RT-Thread
+關注
關注
31文章
1289瀏覽量
40129
發布評論請先 登錄
相關推薦
評論