Dear Graeme Russ, In message <4e1c23b8.6020...@gmail.com> you wrote: > > So how do we deal with Nios2? It is what caused such a deep investigation > into the timer API. We have three choices I can think of off the top of my > head: > > 1. Move the whole timer API up to the architecture level and replicate > code everywhere > 2. Make the whole timer API weak > 3. Fundamentally allow the timer API to handle arbitrary timer resolutions > > 1. Way ugly. We already have this, and that is why we are here today > 2. Well, you know what will happen - Someone will be unhappy with the > generic API and rewrite a completely different one (timer_masked anyone!) > 3. Why is this so evil?
The big disadvantage of 3) is that you cannot make any reasonable assumptions any more in the code. If I place a "udelay(10)" in some device driver, I am probably aware that we don't have exact times, and that the actual delay may be 10 or 12 or eventually even 20 micro- seconds. We should make sure that the delay never takes less than 10 us, but we also have to guarantee that it does not take - for example - 10 milliseconds. What exactly is the reason that we cannot have better timer resolutions in NIOS? I'm anything but a NIOS export, but skimming through the "Altera Embedded Peripherals IP User Guide", section "28. Interval Timer Core" I see that we can have "32-bit and 64-bit counters", "Two count modes: count down once and continuous count-down", and the example in section "Configuration: Timeout Period" on p. 28-3 reads: For example, if the associated system clock has a frequency of 30 ns, and the specified Timeout Period value is 1 µs, the true timeout period will be 1.020 microseconds. Well, if I understand this correctly, we can have a continuously running 64 bit counter with microsecond resolution. There are other sections that describe configurations that might probably be used as well, for example in "HAL System Library Support": Timestamp Driver The interval timer core may be used as a timestamp device ... Also, the "Nios II Software Developer's Handbook" says in "Chapter 6: Developing Programs Using the Hardware Abstraction Layer - Using Timer Devices" on o. 6-16: The HAL API provides two types of timer device drivers: - System clock driver--Supports alarms, such as you would use in a scheduler. - Timestamp driver--Supports high-resolution time measurement. ... You can obtain the rate at which the timestamp counter increments by calling the function alt_timestamp_freq(). This rate is typically the hardware frequency of the Nios II processor system--usually millions of cycles per second. The timestamp drivers are defined in the alt_timestamp.h header file. High-resolution time measurement? Isn't this what we are looking for? Or am I missing something? Scott, maybe you can comment here? > I'm open to other options if you have any At the moment I'm trying to understand if we really have a problem on NIOS2 that cannot be fixed in a way that is compatible with our current plans. > 1) Get the current time Agreed. That's time(). > 2) Report the minimum time elapsed since an arbitrary epoch > 3) Report the maximum time elapsed since an arbitrary epoch I don't understand why we would need this. > 4) Delay for an arbitrary period of time > > 4 is a derivative of 2 - Just loop until at least the required time has > elapsed. Right. Both delays and timeouts work like that, the difference being that delays are "blocking", i. e. there is no other code running inbetween, and you can just sit in a tight spinning loop. I have not seen any requirement yet for 3. > And you then suggest bringing in no less than 6 functions from Linux It's just macros. And we don't need to use them all. Actually time_after() is all that's needed to satisfy our current usage. > Done - I will reject the current series and rebase/repost the patches you > have already ack'd and assign them to you in patchwork - I'll leave it up > to you to pull them in Don't reject them - just mark them as RFC. > Provided you have access to an incrementing value which increments at a > fixed rate and you know the rate, the rest is architecture independent We also have to deal with decrementing counters, but this is just aan unimportant detail. And it appears that we actually can have this, even on NIOS. > > We could also say this is all we need. If we have a working high > > precision TOD timestamp, we can derive all other things we need from > > that. > > So you want to look at bringing in the Linux TOD API as well? That means we No, I don't. > > See my previous comments. And the longer I think about it, the more I > > think we should just use > > > > u64 time(void) > > > > as core of this new code. > > Agreed - As said before (for the time being) the return value of any > arbitrary call to time() means nothing. It _may_ mean the number of > nanoseconds since power-up, but this is by no means guaranteed. True. But it is also garanteet to be usable in constructs as the aforementioned u64 then = time() + number_of_nanoseconds; ... if (time_after(time(), then)) ... > But what about delays (no-brainer - ndelay, udelay, mdelay) and 'elapsed time' Well, like this: void udelay(u32 usec) { u64 then = time() + (u64)usec * (u64)1000; while (!time_after(time(), then)) ... do something, like trigger watchdogs etc ... } For 'elapsed time' it should be sufficient to store the start value of time() as early as possible in the (architecture specific) code. > > Well, here I think we should have a look at Linux again here. In > > include/linux/jiffies.h they provide a nice set of inlines, which in > > our case would reuse directly: > > > > time_after() > > time_after_eq() > > time_before() > > time_before_eq() > > time_in_range() > > time_in_range_open() > > > > When would we use time_in_range and time_in_range_open? I don't think we I don;t suggest that we need to use all of these. As mentioned, currently I only see use for time_after() (and/or time_after_eq(), it if should make a difference). > > The classic timeout code then becomes: > > > > u64 then = time() + TIMEOUT; > > ... > > if (time_after(time(), then)) { > > /* handle timeout */ > > } > > Arrrgh - Sorry, but we have been around and around and around this. There > are sooooo many way to do this - The two big contenders have been: Yes, and both of them do the compare in local code. This is what we should get rid of. > And now we throw a third into the mix. Please read the comments for the implementation of the time_after() macro. It makes sense to do it this way. > time_since and future_time are designed to take into account the underlying > resolution of the hardware timer/counter. The big thing to remember is that > we _must_ handle the case where the underlying timer is too coarse Do we? What exactly is the needed resolution of the underlying hardware timer? So far, it appears sufficient to have it ticking with 1000 Hz or more. Are there really systems that cannot provide that? The only architecture I remember that seemed prolematic was NIOS - but then the NIOS documentation suggests that this might actually be solvable. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de Immortality consists largely of boredom. -- Zefrem Cochrane, "Metamorphosis", stardate 3219.8 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot