-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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. |
(Doing a grooming pass on bugs/issues that are sitting around with my name on or near them. No one pays me right now so I get to be an unaccountable whirlwind of chaos!) Think this one can be closed, as there's nothing in the discussion here that isn't well captured by @cfriedt in #40099. Broadly the big missing piece is just a sub-microsecond busy wait. Timer (i.e. interrupt-driven) subsystem rates are arbitrarily precise already (subject to unit overflow) and have been proven out down to a 20us tick granularity on existing platforms. And even for busy waiting, we have only a handful of platforms (bigcore x86 and the intel_adsp devices, maybe ARM64?) which have software-accessible counters much below 1us anyway. |
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: