Benchmarks Documentation Examples Repository Blog Contact

Timing provider API

CMRX kernel needs source of clock to perform certain tasks, such as preemptive multi-threading and reliable implementation of delays and timers. This resource is not provided by the kernel itself. It is a task of the integrator to provide suitable implementation of calls which form the API of timing provider. This gives the integrator a possibility to choose the source of clock which suits his intended purposes the best.

The design of timing provider API is done in a way that it is possible to implement CPU core power management here as the call directly informs the integrator on how long the kernel is not expecting any CPU activity. Integrator is free to perform the delay in any way available on the target HW, including shutting down the CPU as long as the method implemented is able to resume CPU operation in requested time or very close to it.

Kernel source tree provides SysTick-Based Timing Provider

Functions

void timing_provider_schedule(long delay_us)

Re-configure timing provider so that next timed kernel call will happen after given delay. This is the only function, whose implementation is mandatory and whose prototype nor behavior cannot be changed. If kernel calls this function, then timing provider must reconfigure itself so that it will be able to call back to the kernel as close as possible to time delay_us

delay_us delay time, in microseconds after which kernel shall be called by the timing provider. The value of 0 means that timing provider should not trigger the kernel timer callback until further notice. This function is guarranteed to be called from kernel context.

  • delay_us delay time, in microseconds after which kernel shall be called by the timing provider. The value of 0 means that timing provider should not trigger the kernel timer callback until further notice.

void timing_provider_delay(long delay_us)

Kernel calls this function whenever tight delay is required. If delays are in orders of microseconds, then it usually makes no sense to yield or try to do anything else because the overhead of thread switching will consume all the time. Timing timing provider shall perform busy-wait delay, waiting for given amount of microseconds.

delay_us amount of microseconds to wait before resuming execution This function is guarranteed to be called from kernel context.

  • delay_us amount of microseconds to wait before resuming execution

long timing_get_current_cpu_freq(void)

This call should return the current CPU speed in Hz. The kernel itself does not need to know this information as it outsources all the timing duties to the timing provider. Userspace applications and drivers might need to know this. As they all run in the userspace, typically it is not possible to access this information directly. Thus this system call is provided to make this information accessible in the userspace. Current CPU speed in Hz, or 0 if this value is not available or reliable. This function is guarranteed to be called from kernel context.

long os_sched_timing_callback(long delay_us)

Kernel entrypoint for timed events. Kernel tells the timing provider, what is the delay before the next call, whenever this function is called. Timing provider shall then wait for given amount of time and then call this callback again. If the delay is 0, then timing provider can shutdown itself as there is no expected timed wakeup.

delay_us the actual amount of microseconds which happened since the last wakeup amount of microseconds, which shall pass before next wakeup will happen. If this value is zero, then no next wakeup shall happen.

  • delay_us the actual amount of microseconds which happened since the last wakeup

Returns amount of microseconds, which shall pass before next wakeup will happen. If this value is zero, then no next wakeup shall happen.

64kB of protected memory ought to be enough for everyone.