WIP: Nanosecond resolution monotonic timer
This set of changes aims to upgrade the OS's time keeping abilities, by adding support for a 64 bit, nanosecond-resolution monotonic time source. This includes:
- A SWI to get the time (OS_ReadMonotonicTime64)
- The ability to schedule one-shot and repeating events using the 64 bit timer (like OS_CallAfter / OS_CallEvery), via the OS_TimerControl SWI
- The ability to fine-tune the timer rate (via the OS_TimerControl SWI), to allow the RTC module or similar to apply clock corrections
- The ability to read the unscaled, 64 bit hardware timer value at its native frequency (via OS_TimerControl 4/5), which could be useful either for code to know roughly how accurate the nanosecond timestamps are, or for a way of reading the time with lower overheads (e.g. for profiling)
- Definition of the new 'timer' HAL device, which HALs are expected to implement in order to provide the OS with the necessary functionality for the new system to function
- If the device is missing, the new APIs will not be available and HAL timer 0 will be used for timekeeping, as before
- If the HAL device is present, then:
- The old time keeping systems (OS_ReadMonotonicTime, TickerV, OS_CallAfter, etc.) will all be driven by the new timer
- In particular, OS_ReadMonotonicTime will (normally) be in sync with OS_ReadMonotonicTime64, so there's minimal risk of software getting confused about the current time if it's using a mix of the old and new APIs
- The kernel will intercept the HAL timer calls and remap the timers so that the numbering starts at 1 (i.e. RISC OS software which talks to HAL timer 1 will actually talk to HAL timer 0)
- If RISC OS software talks to HAL timer 0 (or uses the HAL counter calls) then it will actually talk to an emulation of timer 0 which reports the value of the new 64 bit timer; this is to ensure compatibility with software which computes high resolution timestamps by combining OS_ReadMonotonicTime with the HAL timer 0 value
- The old time keeping systems (OS_ReadMonotonicTime, TickerV, OS_CallAfter, etc.) will all be driven by the new timer
See Doc/NanoTime for more in-depth documentation, Dev/NanoTime, and https://www.riscosopen.org/forum/forums/3/topics/11109 for the original forum thread.
Other changed components:
- https://gitlab.riscosopen.org/jlee/RTC/-/tree/TimerControl - updating the RTC module to use OS_TimerControl (since fine-tuning the clock via HAL_TimerSetPeriod isn't supported)
- https://gitlab.riscosopen.org/jlee/HAL_BCM2835/-/tree/NanoTime - RPi implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_iMx6/-/tree/MicroTime - iMx6 implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_IOMD/-/tree/NanoTime - IOMD implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_OMAP3/-/tree/MicroTime - OMAP3 implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_OMAP4/-/tree/NanoTime - OMAP4 implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_OMAP5/-/tree/NanoTime - OMAP5 implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_PineA64/-/tree/NanoTime - Pinebook implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_Titanium/-/tree/NanoTime - Titanium implementation of the timer device
- https://gitlab.riscosopen.org/jlee/HAL_Tungsten/-/tree/NanoTime - Tungsten implementation of the timer device
Important TODO items:
- Official allocation for the new SWIs
- Better errors & error checking
-
Use chocolate blocks for- donetimernode_t
allocation -
Modifications to cope with systems where the timer rate may change? (e.g. Cortex-A9 system timer is affected by CPU speed, but it looks like the HALs can mostly deal with that themselves)- doesn't look like this will be needed -
Change to nanosecond resolution instead of microsecond- done -
Optimise HAL devices by making the kernel be responsible for scheduling any regular interrupt that's guard against overflow of the underlying timer device (many platforms only have a 32 bit hardware timer, so regular interrupts or timer reads are needed to protect against overflow causing backwards time travel when the HAL extends the time to 64 bits)- done