Hi all,
I recently put together FreeRTOS and freedom-e-sdk to run on a HiFive1 board, but it was running slower than it should. I realised later that FreeRTOS was working correctly, but that the calculated ticks were too long. For example: the demo used pdMS_TO_TICKS( 1000 ) to delay a task for 1 second. However that would take minutes of real time.
In the end I had to use these values to get close to the real time delays:
define configCPU_CLOCK_HZ ( 17500 )
define configTICK_RATE_HZ ( ( TickType_t ) 100 )
Please, have anyone tried FreeRTOS on a HiFive1 and got different results?
And do you think it is a problem to “lie” to FreeRTOS about the clock, in order to get timers close to real time values?
Thanks!
You shouldn’t need to ‘lie’ to FreeRTOS. The likely problem is that the port layer has a bug for that system and isn’t setting up the tick timer right. The define configCPU_CLOCK_HZ should only be used by the port layer to setup the timer, which should also be using the configTICK_RATE_HZ define. If the ticks aren’t occuring at the right rate, that setup function is wrong.
I don’t know those particular systems/projects, but I do know how FreeRTOS works, and getting wrong period tick interurpts it the responsibility/fault of the port layer in port.c in a function called an named to set up the system timer (I don’t have the code in front of me to get the exact name, but it should be obvious looking throgh port.c). Values being that far off sounds like something may be wanting values scaled differently than being provided.
What is generating the clock input to the MCU? Does the part have a
CLINT (I think it does)? If so, does it have a machine clock (mclock -
I think it does)? If so, how do you know how fast the machine clock is
running? Maybe the clock needs initialising to do something like enable
the PLL to make it go quickly.
“The mcycle CSR holds a countof the number of cycles the hart has executed since some arbitrary time in the past.” (section 3.1.16)
“Platforms provide a real-time counter, exposed as a memory-mapped machine-mode register, mtime. mtime must run at constant frequency, and the platform must provide a mechanism for determining the time base of mtime.” (section 3.1.15)
I found considerable evidence that mtime frequency is 32768 Hz, or 32KHz:
And in turn the E31 Core Complex User Guide says on section 8.2.1:
“Generally, rtc_toggle is connected to either a Real Time Clock (e.g. 32.768 kHz) or to the base clock input frequency of the platform.”
But the code on FreeRTOS/Source/portable/GCC/RISCV/port.c, more specifically, the function vPortSetupTimerInterrupt, wasn’t considering it. I “fixed” it dividing the clock by 32KHz, which is the frequency of the mtime cycles:
const uint32_t ulTimerIncrementsForOneTick = ( uint32_t ) ( ( configCPU_CLOCK_HZ / 32768) / configTICK_RATE_HZ );
Now it calculates the next tick using “mtime cycles”, which happen at a frequency of 32KHz.
By the end the timers are no longer wrong by a factor of 8000. However, they are still wrong by a factor of 4. (32/8=4)
So I’ll continue looking into what is wrong. I’ll probably explore this sentence:
“Generally, rtc_toggle is connected to either a Real Time Clock (e.g. 32.768 kHz) or to the base clock input frequency of the platform.”
Please, if you have anything to say, or know who could I talk to about fixing the file above, leave a response.
Since my last post I was able to run the “test suite” found on FreeRTOS/Demo/RISC-V-Qemu-sifive_e-FreedomStudio/full_demo/main_full.c with mixed results.
When running them all (dynamic tasks, block timer, etc) they mostly failed.
When running them individually they all pass.
I think it might be related to timing, and I’m having better results by, for example, tweaking configTICK_RATE_HZ from 1000 to 10. Some tests use small delays that when converted using the macro pdMS_TO_TICKS would result in a 0 ticks delay.
Anyway, the whole thing still feels unstable.
Side note: I’ve also run out of memory and I had to re-program Arty’s SRAM from 16KB to 64KB.
I have not tried running on the Arty - what is the clock frequency it is
using? You are right in that the tests are self monitoring and check
their own timing. Depending on how many you are running, if the
hardware is slow, physics might get in the way of them all passing at
once. I have an Arty and can give this a go myself (although not sure
when I will get the chance) so please let me know as much about your
hardware configuration as possible.