關於configCPU_CLOCK_HZ
在FreeRTOS配置文件FreeRTOSConfig.h,定義宏configCPU_CLOCK_HZ來表示CPU時鐘的頻率。則系統一個Tick的時間是1/configCPU_CLOCK_HZ。
關於configTICK_RATE_HZ
FreeRTOS的時鐘Tick的頻率,也就是FreeRTOS用到的定時中斷的產生頻率。默認值是1000,即1ms,即1000個Tick上報一次timer中斷。
Risc-v時鐘信號
Risc-v的時鐘信號是由rtc_toggle接入的,一般不能超過core-clock的1/2。這個信號僅用來計時使用,所以不需要太高頻率。一般1mHz就夠了。
mtime
mtime是risc-v一直在走的真實時間,是由rtc_toggle直接決定的。是系統時間。
mtimecmp
mtimecmp是用來觸發timer中斷的,當mtime大於等於mtimecmp時,會觸發上報一次timer中斷。
在FreeRTOS中,每次上報timer中斷會重置mtimecmp的值。
mtimecmp = mtime + configCPU_CLOCK_HZ/configTICK_RATE_HZ;
以此來決定下一次timer中斷觸發的時間,在實際使用中,需要再加10cycles左右的時間,這是算一些io訪問消耗的時間。
關於FreeRTOS線程調度
調度器調度的調度週期是一個timer中斷時間。
所以在risc-v中需要合理設置configCPU_CLOCK_HZ/configTICK_RATE_HZ的值,來保證一個調度週期內能夠執行足夠多的指令。
降頻處理
以Risc-v core-clock爲200kHz爲例(降頻5000倍,實際1gHz),則cpu 1秒能夠執行200k條指令(以單指令週期來算)。
Risc-v rtc_toggle爲31.25kHz,即時鐘信號是這麼多。一個tick時間爲1/31250;
configCPU_CLOCK_HZ和configTICK_RATE_HZ怎麼設置才合理?
以實際值爲例
configCPU_CLOCK_HZ = 31250
configTICK_RATE_HZ = 1000
則觸發一次timer中斷的時間是31250/1000=31.25Tick,即1ms。
再算一下1ms之內cpu能夠執行的指令數:1秒是200k,1ms就是200條。
所以可以看出一個timer中斷時間內只能執行200條指令,是遠遠不夠調度器使用的。線程不可能運行起來。
所以在這種情況下,需要使用軟件“欺騙”的方法,將configCPU_CLOCK_HZ變大或者configTICK_RATE_HZ變小。
我的做法是:
configCPU_CLOCK_HZ = 3125000
configTICK_RATE_HZ = 1000
相當於是把時間放大100倍,實際是1ms的,這裏變成了100ms。這樣算下來,一個調度節點執行20k條指令,足夠FreeRTOS調度器使用。