Question about setting configCPU_CLOCK_HZ in FreeRTOS

Hi all.

In the case of setting “#define configCPU_CLOCK_HZ ( MTIME_RATE_HZ )” in FreeRTOSConfig.h among the contents of the demo source provided by FreeRTOS
MTIME_RATE_HZ was set to 32768 to use the external clock configured on the board. Does anyone know what could be the reason??

And can’t I set the configCPU_CLOCK_HZ value to 320MHz, which is the system’s maximum clock??

1 Like

Nice question @jose there are two kinds of clocks in general; what FreeRTOS has in mind with its configCPU_CLOCK_HZ parameter is the low-frequency “clock” which can be more aptly called a timer (as in a systick timer) – it controls and drives interrupts and other events to the core, not the core itself.

Setting MTIME_RATE_HZ with 32768 will provide for a rollover and/or interrupt every 1 second, because the LFR upon which the MTIME counter/timer is based runs at, by default, 22.9 KHz. TIP: use 22900 rather than 32768 for best results :slight_smile:.

The 320 MHz rate applies to the high-frequency clock, controlling and directly driving the core.

There are four low-frequency clock/timers in the FE310 SoC: LFR, WDT, RTC, and MTIME. The first three are in the AON (Always ON) clock and power domain, while the fourth is in the MOFF (Mostly OFF) domain. LFR (Low Frequency Ring oscillator) is more like a clock because it self-generates a train of pulses; the others are more like timers or counters because they do their counting and timing based on an input train of pulses. When you set the MTIME_RATE_HZ value in FreeRTOS, you’re actually setting a counter/timer divider number; it’s based upon the rate of the LFR clock which is, by default at power-up, 22.9 KHz. This is the setting for LFROSC register fields trim=0 and div=4; thus, use MTIME_CLOCK_HZ as 22900 instead of 32768 and you’ll get closer to 1 second. The settings of trim=0 and div=3 give slightly higher LFR rate, 28.6 KHz; no other setting comes closer to 32.768 KHz.

There are two high-frequency clocks in the FE310: HFR and HFX, being the High Frequency Ring oscillator, and High Frequency eXternal oscillator, respectively. The latter externally requires a crystal or other source present for better stability and performance. Both clocks are in the MOFF power and clock domain. There is also a PLL block which helps either of the two high-frequency clock options get up to that 320 MHz value you mention. The default at power-up state for the core clock is to use the HFR at 17.3 MHz (with its HFROSC register fields trim=0 and div=4), without PLL, and with an output division-by-2 to keep good core clock symmetry and minimal 2nd harmonic, thus giving a CPU TileLink clock of about 8.65 MHz.

Configuration and programming details for the low-frequency clock/timers is fairly simple and well-documented. See my github link below for exact calculations and design parameters for the LFR oscillator.

Configuration and programming details of the high-frequency clocks is a bit more tricky. To my knowledge, there’s no general way in FreeRTOS to configure or change settings of the high-frequency clock, especially while running. I’ve tried to make a comprehensive Demonstration of PRCI on github, and suggest a state machine approach for safely changing the high-frequency clock at any time; it’s highly SoC device specific, and probably beyond the scope of an O/S layer (though critical for maximizing both power consumption and operating performance). There is related discussion here on the forums to help Understand the PRCI Clock Path inside the FE310 single-core RV32IMAC(U) SoC.