Kernel high-resolution timer support #6498
Comments
@anangl @tbursztyka FYI |
In addition to a high-resolution timer API, I imagine users that have the high-frequency clock always-on anyway would like to be able to Kconfigure "_arch_k_cycle_get_32" to use the high-frequency clock instead of the low-frequency clock. |
Why only a microseconds resolution? |
Agreed, I checked the Linux HR timer API and it uses nanoseconds.
Well, there is also |
Agreed, the only issue in the Nordic platforms then is that we'd need a secondary implementation of our system timer driver that uses a timer instead of the RTC. |
Yeah, on systems with a high precision cycle counter, k_busy_wait() does what you want already. It just spins on k_cycle_get_32() as described. On essentially all the current platforms, k_cycle_get_32() is provided out of the timer driver as _timer_cycle_get_32(). Pretty sure you have what you want already, no? |
@andyross yeah, I think so. Unless we really need nanosecond precision, but on current microcontrollers this make little sense actually, since the overhead in instructions would already clobber the added resolution. @diytronic would that cover your needs, if k_busy_wait() was actually precise on Nordic platforms? |
@carlescufi For current task yes, but I am implementing 1-wire bus now (need it for ds18b20 sensor, so really writing driver for it too) and among the standard mode 1-wire has so called overdrive mode (faster). Here you can look at timings (just to make sure it is not my stupid caprice) https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 So in overdrive mode it required for example 1us, 2.5us delays and so on. So on my opinion nanosecond resolution could be way better. |
@carlescufi BTW just checked for example CAN BUS timings https://www.nxp.com/docs/en/application-note/AN1798.pdf So nanosecond delays there. So I think nanosecond delay must be implemented. |
So... two issues: one is that k_busy_wait() only allows a microsecond argument, where the actual cycle counter it wraps can (usually) do better. I don't see any reason we can't have a k_nano_wait() or whatever that takes different units, though honestly an app with precision requirements like this could trivially write its own loop over k_cycle_get_32(). But a request for true nanosecond precision just isn't going to work on CPUs running clocks 10-100x slower than that. We can't fix that. |
No - it does not work. For example for nRF51x MCU family system tick used 32kHz timer which is unable to provide even microseconds resolution. Really this was the only reason for |
nRF51x MCU has separate 16Mhz timer which can be used for this. So I expect some other MCU can have something similar. Mean some built in mechanisms not related to system clock. |
@diytronic: k_cycle_get_32() returns a hardware cycle counter, not scheduler ticks (except on platforms that have no such timer, I guess). I'm all but certain this would work just fine on nRF1x. Are you sure you actually have a problem with the API as it stands (which has some precision aliasing due to microsecond conversion, but otherwise should be close to cycle accurate)? |
@andyross I am absolutely sure, because I tried to get a delay based on this http://docs.zephyrproject.org/kernel/timing/clocks.html#measuring-time-with-high-precision and finally got that k_cycle_get_32() working with 32kHz frequency what was a big surprise (tested on nRF51822 MCU). So I discovered code and found what 32kHz timer used for that (nRF51822 has second timer working at 16Mhz). So I asked in mailing list about it and got the following reply
And later this
But anyway checking k_cycle_get_32() (pin output with logic analyser) I see 32kHz frequency of k_cycle_get_32(). So to get smaller delay I am separately turning on and using 16Mhz timer. |
I need a 1us timestamp "service". In my use-case it is simply a variable that increments every 1 us infinitely, and that gets read asynchronously as per need. -be always monotonic at a 1us resolution Neglecting any os issues, would not this be easy to do in the nrf devices by using a 32b-wide timer clocked at a 1MHz and a compare register to detect rollovers. The timer Thanks Abderrezak |
Saw this came up again on the mailing list. As diytronic explains above: NRF51 devices have power consumption requirements that mean that the system clock will simply never be able to produce timing information of this precision in a way that Zephyr can expose as a straightforward API. If the clock has to be kHZ-scale at idle, there's just no way to get the main timer (i.e. k_cycle_get_32(), and its derivatives like k_busy_wait()) to give you answers in microseconds. You have to use some other device, and manage it outside the system timer framework. I don't think that would be a bad API to have available, but it's much more complicated than "high-resolution timer support", which we already have. |
Copying @pizi-nordic since this was raised in the API meeting today by him. |
I am working an IO-Link application using the FRDM-K64F development board. This application requires the use of timers in microseconds. There are multiple timers that need to be implemented in microseconds. As of now |
Setting the priority high due to popular demand for this feature |
Would be useful to have hr timers for a nanosleep(2) call (#25559). I have not looked into Zephyr's clock structure yet though. It would be nice to register multiple clock sources and make them available to applications / userspace similar to how clock_getres, clock_gettime, etc work. |
Several users in the mailing list have asked for highly precise busy-wait primitives that allow them to time with precision.
I don't know what sort of APIs we'd need, but at the very least something like:
k_hr_busy_wait(u64_t microseconds)
The text was updated successfully, but these errors were encountered: