You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@nuttx.apache.org by Grr <ge...@gmail.com> on 2021/03/24 16:36:04 UTC

Sleep Resolution

Hello to all.

Looking for the right way to create a _very_ short delay (10-100 ns), I
found clock_nanosleep, whose description says:

"The suspension time caused by this function may be longer than requested
because the argument value is rounded up to an integer multiple of the
sleep resolution"

What is the sleep resolution and where/how is defined?

TIA
Grr

Re: Sleep Resolution

Posted by Gregory Nutt <sp...@gmail.com>.
> Is the Tickless mode considered stable enough for production use now?
> IIRC it had some caveats when I last looked into it and I haven't had
> a chance to study it again.
I believe so.  I am not aware of any issues.  It has been around for 
several years and has been used by a lot of NuttX users.  So from what I 
know the answer is "Yes."  But I don't do products myself so I would 
welcome the feedback and experiences of anyone else.

Re: Sleep Resolution

Posted by Nathan Hartman <ha...@gmail.com>.
On Wed, Mar 24, 2021 at 2:53 PM Gregory Nutt <sp...@gmail.com> wrote:
>
>
> > The way the logic in clock_nanosleep() is written, the minimum delay
> > ends up being 2 such ticks. I don't remember why and I can't seem to
> > find it in the code right now, but I know this because I checked into
> > it recently and found out that that's how it works.
>
> See https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
>
> This is a translation.  It does not effect the accuracy, it effects the
> mean delay.  The accuracy is still 10 MS.  The quantization error will
> lie in the range of 0 to +10 MS.  If you did not add one tick, the error
> would be in the range of -1 to 0 MS which is unacceptable.

Thanks

> > It does not make sense to change the tick interval to a higher
> > resolution (shorter time) because then the OS will spend a
> > significantly increasing amount of time in useless interrupts etc.
>
> Unless you use Tickless mode then it is easy to get very high resolution
> (1 uS range) with no CPU overhead.

Is the Tickless mode considered stable enough for production use now?
IIRC it had some caveats when I last looked into it and I haven't had
a chance to study it again.

Nathan

Re: Sleep Resolution

Posted by Gregory Nutt <sp...@gmail.com>.
> The way the logic in clock_nanosleep() is written, the minimum delay
> ends up being 2 such ticks. I don't remember why and I can't seem to
> find it in the code right now, but I know this because I checked into
> it recently and found out that that's how it works.

See https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays

This is a translation.  It does not effect the accuracy, it effects the 
mean delay.  The accuracy is still 10 MS.  The quantization error will 
lie in the range of 0 to +10 MS.  If you did not add one tick, the error 
would be in the range of -1 to 0 MS which is unacceptable.

> It does not make sense to change the tick interval to a higher
> resolution (shorter time) because then the OS will spend a
> significantly increasing amount of time in useless interrupts etc.

Unless you use Tickless mode then it is easy to get very high resolution 
(1 uS range) with no CPU overhead.

50 ns is still probably out of reach of the system timer.


Re: Sleep Resolution

Posted by Nathan Hartman <ha...@gmail.com>.
On Wed, Mar 24, 2021 at 12:37 PM Grr <ge...@gmail.com> wrote:
> Looking for the right way to create a _very_ short delay (10-100 ns), I
> found clock_nanosleep, whose description says:
>
> "The suspension time caused by this function may be longer than requested
> because the argument value is rounded up to an integer multiple of the
> sleep resolution"
>
> What is the sleep resolution and where/how is defined?

I'm a little late to the party, but...

The resolution would likely be 20 milliseconds, which is far more than you want.

Here's how I get that 20 millisecond value:

If you do not configure CONFIG_USEC_PER_TICK to a custom value, it is
10,000 microseconds (10 milliseconds) per "tick" by default.

The way the logic in clock_nanosleep() is written, the minimum delay
ends up being 2 such ticks. I don't remember why and I can't seem to
find it in the code right now, but I know this because I checked into
it recently and found out that that's how it works.

Note that all the sleep functions, whether sleep(), usleep(),
nanosleep(), etc., promise to delay for AT LEAST the length of time
you specify. There is no upper limit to the length of the delay as
it's subject to scheduling, the resolution of the clock, and whatever
else is going on in the system.

It does not make sense to change the tick interval to a higher
resolution (shorter time) because then the OS will spend a
significantly increasing amount of time in useless interrupts etc.

Also, it does not make sense to use these functions for such short
delays in the nanosecond range. Just the processing overhead of
calling one of those functions is much more than 10 to 100 ns.

When I need such a short delay (e.g., when you need a delay between
setting Chip Select of a SPI peripheral and actual start of
communication), I measure how long a NOP instruction takes on the
microcontroller in question and I insert that many NOPs. If the delay
would require a lot of NOPs, you can use a for-loop with a volatile
loop counter ensuring that the compiler doesn't just optimize away the
loop. Note that if there's a task switch or interrupt during that
time, the delay will likely be much longer than you intend. If the
timing is critical, a simple hack is to use a critical section around
it, but I would use that as a last resort; first, I would look into
doing whatever needs that fine delay, e.g., waveform shaping, with
hardware instead.

These solutions are obviously very closely tied to the specific
microcontroller and its clock speed, so they're very non-portable. If
someone has a better suggestion, I'd love to learn about it!

Nathan

Re: Sleep Resolution

Posted by Alan Carvalho de Assis <ac...@gmail.com>.
Hi Grr,

It is not a simple challenge even using a microcontroller running a
baremetal busy loop code, let alone using a RTOS. More info:

https://forum.allaboutcircuits.com/threads/programming-a-1-ns-delay-for-microcontroller-processor.90227/

It is better to have a dedicated hw taking care of the ns-resolution
delays and using the RTOS to control and gather the resulted data.

What are trying to achive? (of course if can share or talk about it).

BR,

Alan

On 3/24/21, Grr <ge...@gmail.com> wrote:
> Hello to all.
>
> Looking for the right way to create a _very_ short delay (10-100 ns), I
> found clock_nanosleep, whose description says:
>
> "The suspension time caused by this function may be longer than requested
> because the argument value is rounded up to an integer multiple of the
> sleep resolution"
>
> What is the sleep resolution and where/how is defined?
>
> TIA
> Grr
>

Re: Sleep Resolution

Posted by Arie de Muijnck <nu...@ademu.com>.
A trick I often used was writing to the volatile (!) CS pin control 
register twice (or more).
The extra writes change nothing, but provide the tiny delay.
The compilers never optimized the extra writes away.
An obj file dumper and scope are handy to check the actual generated 
code and delay.

Arie

On 2021-03-24 18:08, Grr wrote:
> Thank you very much for your response
>
> What I'm trying to do is to generate hold and disable times for SPI CS,
> which should be about 50 ns
>
> I started by an empty for loop but it seems optimization gets rid of it (I
> haven't researched the issue properly). Then I thought a proper function
> would be better but got stuck in that expression "sleep resolution"
>
> For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
> make sure there's not a more appropriate system tool
>
> El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
> saramonteirosouza44@gmail.com>) escribió:
>
>> Hi Grr,
>>
>> I have never needed to use this function neither this range (ns).
>> But I used the usleep function which resolution is defined as
>> CONFIG_USEC_PER_TICK.
>> But maybe, in your case, for such range, you should consider using a
>> hardware timer or a Timer Hook.
>> Take a look at this wiki:
>> https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
>>
>> Sara
>>
>> Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:
>>
>>> Hello to all.
>>>
>>> Looking for the right way to create a _very_ short delay (10-100 ns), I
>>> found clock_nanosleep, whose description says:
>>>
>>> "The suspension time caused by this function may be longer than requested
>>> because the argument value is rounded up to an integer multiple of the
>>> sleep resolution"
>>>
>>> What is the sleep resolution and where/how is defined?
>>>
>>> TIA
>>> Grr
>>>


Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
for(delay = 0; delay < transfer->dev->afterstart; delay++);

afterstart is loop's limit, which determines the desired delay length,
known by definition

El mié, 24 mar 2021 a las 14:57, Johnny Billquist (<bq...@softjar.se>)
escribió:

> Well. There was nothing in there that showed me that afterstart == 0. Is
> this a known fact, or an assumption?
>
>    Johnny
>
> On 2021-03-24 21:47, Grr wrote:
> > Since afterstart = 0, there should be no loop to optimize out except ONE
> > value test
> >
> > One hundred cycles for that would seem excessive for me
> >
> > TWENTY THOUSAND CYCLES for a _zero_ loop?!?
> >
> > Maybe in Java
> >
> >
> >
> > El mié, 24 mar 2021 a las 14:30, Gregory Nutt (<sp...@gmail.com>)
> > escribió:
> >
> >>
> >>> Weird behavior:
> >>>
> >>> Simply changing loop counter variable from uint16_t to volatile
> uint16_t
> >>> causes initial delay (with variable delay = 0) going from ~500 ns to
> >> ~120 us
> >>>
> >>> The code is
> >>>
> >>> uint16_t delay;
> >>>
> >>> select_function();
> >>> for(delay = 0; delay < transfer->dev->afterstart; delay++);
> >>>
> >>> Any ideas?
> >>>
> >> I imagine that the delay loop is no longer being optimized out. That is
> >> what volatile is supposed to do (people often don't understand that, it
> >> is a great interview question).
> >>
> >
>
> --
> Johnny Billquist                  || "I'm on a bus
>                                    ||  on a psychedelic trip
> email: bqt@softjar.se             ||  Reading murder books
> pdp is alive!                     ||  tryin' to stay hip" - B. Idol
>

Re: Sleep Resolution

Posted by Johnny Billquist <bq...@softjar.se>.
Well. There was nothing in there that showed me that afterstart == 0. Is 
this a known fact, or an assumption?

   Johnny

On 2021-03-24 21:47, Grr wrote:
> Since afterstart = 0, there should be no loop to optimize out except ONE
> value test
> 
> One hundred cycles for that would seem excessive for me
> 
> TWENTY THOUSAND CYCLES for a _zero_ loop?!?
> 
> Maybe in Java
> 
> 
> 
> El mié, 24 mar 2021 a las 14:30, Gregory Nutt (<sp...@gmail.com>)
> escribió:
> 
>>
>>> Weird behavior:
>>>
>>> Simply changing loop counter variable from uint16_t to volatile uint16_t
>>> causes initial delay (with variable delay = 0) going from ~500 ns to
>> ~120 us
>>>
>>> The code is
>>>
>>> uint16_t delay;
>>>
>>> select_function();
>>> for(delay = 0; delay < transfer->dev->afterstart; delay++);
>>>
>>> Any ideas?
>>>
>> I imagine that the delay loop is no longer being optimized out. That is
>> what volatile is supposed to do (people often don't understand that, it
>> is a great interview question).
>>
> 

-- 
Johnny Billquist                  || "I'm on a bus
                                   ||  on a psychedelic trip
email: bqt@softjar.se             ||  Reading murder books
pdp is alive!                     ||  tryin' to stay hip" - B. Idol

Re: Sleep Resolution

Posted by Nathan Hartman <ha...@gmail.com>.
On Wed, Mar 24, 2021 at 4:49 PM Grr <ge...@gmail.com> wrote:
>
> Since afterstart = 0, there should be no loop to optimize out except ONE
> value test
>
> One hundred cycles for that would seem excessive for me
>
> TWENTY THOUSAND CYCLES for a _zero_ loop?!?
>
> Maybe in Java

We didn't see the value of transfer->dev->afterstart.

Could this be exposing a bug elsewhere? E.g., afterstart has a
different value than you expect?

Alternately could it be that afterstart had the correct value but the
task was interrupted during the loop and a big portion of the 20,000
cycles were spent doing something else?

Nathan

Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
Since afterstart = 0, there should be no loop to optimize out except ONE
value test

One hundred cycles for that would seem excessive for me

TWENTY THOUSAND CYCLES for a _zero_ loop?!?

Maybe in Java



El mié, 24 mar 2021 a las 14:30, Gregory Nutt (<sp...@gmail.com>)
escribió:

>
> > Weird behavior:
> >
> > Simply changing loop counter variable from uint16_t to volatile uint16_t
> > causes initial delay (with variable delay = 0) going from ~500 ns to
> ~120 us
> >
> > The code is
> >
> > uint16_t delay;
> >
> > select_function();
> > for(delay = 0; delay < transfer->dev->afterstart; delay++);
> >
> > Any ideas?
> >
> I imagine that the delay loop is no longer being optimized out. That is
> what volatile is supposed to do (people often don't understand that, it
> is a great interview question).
>

Re: Sleep Resolution

Posted by Gregory Nutt <sp...@gmail.com>.
> Weird behavior:
>
> Simply changing loop counter variable from uint16_t to volatile uint16_t
> causes initial delay (with variable delay = 0) going from ~500 ns to ~120 us
>
> The code is
>
> uint16_t delay;
>
> select_function();
> for(delay = 0; delay < transfer->dev->afterstart; delay++);
>
> Any ideas?
>
I imagine that the delay loop is no longer being optimized out. That is 
what volatile is supposed to do (people often don't understand that, it 
is a great interview question).

Re: Sleep Resolution

Posted by Nathan Hartman <ha...@gmail.com>.
On Wed, Mar 24, 2021 at 3:53 PM Johnny Billquist <bq...@softjar.se> wrote:
>
> Perfectly expected.
> With volatile, the compiler are not allowed to optimize away the memory
> accesses for updating the loop variable. So you are suddenly getting a
> lot of memory read/write cycles that probably didn't happen before.
> I would even have expected that prior to the volatile, that loop would
> be totally optimized away.

Yes, that's exactly right.

Be careful with volatile:
https://blog.regehr.org/archives/28

Enjoy,
Nathan

Re: Sleep Resolution

Posted by Johnny Billquist <bq...@softjar.se>.
Perfectly expected.
With volatile, the compiler are not allowed to optimize away the memory 
accesses for updating the loop variable. So you are suddenly getting a 
lot of memory read/write cycles that probably didn't happen before.
I would even have expected that prior to the volatile, that loop would 
be totally optimized away.

   Johnny

On 2021-03-24 20:47, Grr wrote:
> Weird behavior:
> 
> Simply changing loop counter variable from uint16_t to volatile uint16_t
> causes initial delay (with variable delay = 0) going from ~500 ns to ~120 us
> 
> The code is
> 
> uint16_t delay;
> 
> select_function();
> for(delay = 0; delay < transfer->dev->afterstart; delay++);
> 
> Any ideas?
> 
> El mié, 24 mar 2021 a las 12:21, Gregory Nutt (<sp...@gmail.com>)
> escribió:
> 
>>
>>> What I'm trying to do is to generate hold and disable times for SPI CS,
>>> which should be about 50 ns
>> That resolution is too high for any system timer.
>>> I started by an empty for loop but it seems optimization gets rid of it
>> (I
>>> haven't researched the issue properly). Then I thought a proper function
>>> would be better but got stuck in that expression "sleep resolution"
>>
>> Add volatile to the loop counter variable and the optimizer will not
>> remove it.
>>
>>
>>
> 

-- 
Johnny Billquist                  || "I'm on a bus
                                   ||  on a psychedelic trip
email: bqt@softjar.se             ||  Reading murder books
pdp is alive!                     ||  tryin' to stay hip" - B. Idol

Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
Weird behavior:

Simply changing loop counter variable from uint16_t to volatile uint16_t
causes initial delay (with variable delay = 0) going from ~500 ns to ~120 us

The code is

uint16_t delay;

select_function();
for(delay = 0; delay < transfer->dev->afterstart; delay++);

Any ideas?

El mié, 24 mar 2021 a las 12:21, Gregory Nutt (<sp...@gmail.com>)
escribió:

>
> > What I'm trying to do is to generate hold and disable times for SPI CS,
> > which should be about 50 ns
> That resolution is too high for any system timer.
> > I started by an empty for loop but it seems optimization gets rid of it
> (I
> > haven't researched the issue properly). Then I thought a proper function
> > would be better but got stuck in that expression "sleep resolution"
>
> Add volatile to the loop counter variable and the optimizer will not
> remove it.
>
>
>

Re: Sleep Resolution

Posted by Gregory Nutt <sp...@gmail.com>.
> What I'm trying to do is to generate hold and disable times for SPI CS,
> which should be about 50 ns
That resolution is too high for any system timer.
> I started by an empty for loop but it seems optimization gets rid of it (I
> haven't researched the issue properly). Then I thought a proper function
> would be better but got stuck in that expression "sleep resolution"

Add volatile to the loop counter variable and the optimizer will not 
remove it.



RE: Sleep Resolution

Posted by David Sidrane <Da...@nscdg.com>.
I asked about HW because some of the new SPI controller IP have the delays
programmable in HW. One from CS active to clock/data and the other is inter
data delays.

Using HW SS and the timers it is built in.

The issue is on a shared bus. We would need to extend the SPI API to support
the settings.

David

-----Original Message-----
From: Grr [mailto:gebbet00@gmail.com]
Sent: Wednesday, March 24, 2021 10:52 AM
To: dev@nuttx.apache.org
Subject: Re: Sleep Resolution

This is a SocketCAN driver for MCP2515 with a new SPI system that
streamlines the select->write->read->deselect process and so exposes the
need to guarantee hold time between read and deselect and disable time
between deselect and next select

Looking at David's code, it seems the loop is the right answer. The DWT
cannot be used for a portable solution but maybe an inline function. Thanks
for the idea

I believe NOPs are optimized away but it seems asm("") or something close
to that is not

It would be nice to incorporate a general solution for this problem to the
Nuttx toolbox

El mié, 24 mar 2021 a las 11:24, David Sidrane (<Da...@nscdg.com>)
escribió:

> What HW is this on?
>
> -----Original Message-----
> From: Grr [mailto:gebbet00@gmail.com]
> Sent: Wednesday, March 24, 2021 10:09 AM
> To: dev@nuttx.apache.org
> Subject: Re: Sleep Resolution
>
> Thank you very much for your response
>
> What I'm trying to do is to generate hold and disable times for SPI CS,
> which should be about 50 ns
>
> I started by an empty for loop but it seems optimization gets rid of it (I
> haven't researched the issue properly). Then I thought a proper function
> would be better but got stuck in that expression "sleep resolution"
>
> For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
> make sure there's not a more appropriate system tool
>
> El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
> saramonteirosouza44@gmail.com>) escribió:
>
> > Hi Grr,
> >
> > I have never needed to use this function neither this range (ns).
> > But I used the usleep function which resolution is defined as
> > CONFIG_USEC_PER_TICK.
> > But maybe, in your case, for such range, you should consider using a
> > hardware timer or a Timer Hook.
> > Take a look at this wiki:
> > https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
> >
> > Sara
> >
> > Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:
> >
> > > Hello to all.
> > >
> > > Looking for the right way to create a _very_ short delay (10-100 ns),
> > > I
> > > found clock_nanosleep, whose description says:
> > >
> > > "The suspension time caused by this function may be longer than
> > > requested
> > > because the argument value is rounded up to an integer multiple of the
> > > sleep resolution"
> > >
> > > What is the sleep resolution and where/how is defined?
> > >
> > > TIA
> > > Grr
> > >
> >
>

Re: Sleep Resolution

Posted by Nathan Hartman <ha...@gmail.com>.
On Thu, Mar 25, 2021 at 2:22 PM Grr <ge...@gmail.com> wrote:

> > 1nsec means 1GHz, it is very hard to achieve the required accuracy even
> > with the high end CPU. But since the standard defines nano_sleep,
> up_ndelay
> > looks not so unreasonable.
> >
>
> I don't mean 1 ns
>
> I mean delays in the order of _dozens_ of ns
>
> 100 MHz (a very reasonable frequency nowadays) means 10 ns per cycle, so a
> standard function that eases the task of delaying a few cycles for things
> like hold times is a _very_ needed tool



What about the ASM function Fotis shared earlier in this thread?

If you're not on an ARM CPU it would just need translation of the ASM
instructions for that CPU.

I recommend to make macros that given a delay time in ns will take into
account the delay loop calibration Greg mentioned, and run the ASM delay
loop. That way, there is only one calibration to make for ns, us, and ms.

Cheers,
Nathan

Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
> 1nsec means 1GHz, it is very hard to achieve the required accuracy even
> with the high end CPU. But since the standard defines nano_sleep, up_ndelay
> looks not so unreasonable.
>

I don't mean 1 ns

I mean delays in the order of _dozens_ of ns

100 MHz (a very reasonable frequency nowadays) means 10 ns per cycle, so a
standard function that eases the task of delaying a few cycles for things
like hold times is a _very_ needed tool


> > El mié, 24 mar 2021 a las 22:34, Xiang Xiao (<xiaoxiang781216@gmail.com
> >)
> > escribió:
> >
> > > Another way to avoid the calibration is to reuse the hardware timer in
> > the
> > > busy loop:
> > >
> > >
> >
> https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_alarm.c#L60-L74
> > >
> > >
> >
> https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_timer.c#L122-L144
> > >
> > > On Thu, Mar 25, 2021 at 11:42 AM Gregory Nutt <sp...@gmail.com>
> > wrote:
> > >
> > > >
> > > > > Why not call up_udelay or up_mdelay? The arch/soc should provide a
> > best
> > > > > implementation for you.
> > > >
> > > > I was wondering that too.
> > > >
> > > > Also, as a side note, it is very important to calibrate the delay
> loop
> > > > using in those functions.  If the delay loop is properly calibrated,
> > > > these can be very accurate (but I suspect most people no longer
> > > > calibrate the delay loop).
> > > >
> > > > There is an app at apps/examples/calib_udelay that can be used to do
> > > that.
> > > >
> > > >
> > >
> >
>

Re: Sleep Resolution

Posted by Xiang Xiao <xi...@gmail.com>.
On Thu, Mar 25, 2021 at 5:25 AM Grr <ge...@gmail.com> wrote:

> Why not use msec & usec delays?
>
> Because the need is nsec delays
>
>
Ok, I understand.


> My question is:
>
> Why not add a portable, general purpose nsec delay function to Nuttx?
>
>
1nsec means 1GHz, it is very hard to achieve the required accuracy even
with the high end CPU. But since the standard defines nano_sleep, up_ndelay
looks not so unreasonable.


> El mié, 24 mar 2021 a las 22:34, Xiang Xiao (<xi...@gmail.com>)
> escribió:
>
> > Another way to avoid the calibration is to reuse the hardware timer in
> the
> > busy loop:
> >
> >
> https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_alarm.c#L60-L74
> >
> >
> https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_timer.c#L122-L144
> >
> > On Thu, Mar 25, 2021 at 11:42 AM Gregory Nutt <sp...@gmail.com>
> wrote:
> >
> > >
> > > > Why not call up_udelay or up_mdelay? The arch/soc should provide a
> best
> > > > implementation for you.
> > >
> > > I was wondering that too.
> > >
> > > Also, as a side note, it is very important to calibrate the delay loop
> > > using in those functions.  If the delay loop is properly calibrated,
> > > these can be very accurate (but I suspect most people no longer
> > > calibrate the delay loop).
> > >
> > > There is an app at apps/examples/calib_udelay that can be used to do
> > that.
> > >
> > >
> >
>

Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
Why not use msec & usec delays?

Because the need is nsec delays

My question is:

Why not add a portable, general purpose nsec delay function to Nuttx?

El mié, 24 mar 2021 a las 22:34, Xiang Xiao (<xi...@gmail.com>)
escribió:

> Another way to avoid the calibration is to reuse the hardware timer in the
> busy loop:
>
> https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_alarm.c#L60-L74
>
> https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_timer.c#L122-L144
>
> On Thu, Mar 25, 2021 at 11:42 AM Gregory Nutt <sp...@gmail.com> wrote:
>
> >
> > > Why not call up_udelay or up_mdelay? The arch/soc should provide a best
> > > implementation for you.
> >
> > I was wondering that too.
> >
> > Also, as a side note, it is very important to calibrate the delay loop
> > using in those functions.  If the delay loop is properly calibrated,
> > these can be very accurate (but I suspect most people no longer
> > calibrate the delay loop).
> >
> > There is an app at apps/examples/calib_udelay that can be used to do
> that.
> >
> >
>

Re: Sleep Resolution

Posted by Xiang Xiao <xi...@gmail.com>.
Another way to avoid the calibration is to reuse the hardware timer in the
busy loop:
https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_alarm.c#L60-L74
https://github.com/apache/incubator-nuttx/blob/master/drivers/timers/arch_timer.c#L122-L144

On Thu, Mar 25, 2021 at 11:42 AM Gregory Nutt <sp...@gmail.com> wrote:

>
> > Why not call up_udelay or up_mdelay? The arch/soc should provide a best
> > implementation for you.
>
> I was wondering that too.
>
> Also, as a side note, it is very important to calibrate the delay loop
> using in those functions.  If the delay loop is properly calibrated,
> these can be very accurate (but I suspect most people no longer
> calibrate the delay loop).
>
> There is an app at apps/examples/calib_udelay that can be used to do that.
>
>

Re: Sleep Resolution

Posted by Gregory Nutt <sp...@gmail.com>.
> Why not call up_udelay or up_mdelay? The arch/soc should provide a best
> implementation for you.

I was wondering that too.

Also, as a side note, it is very important to calibrate the delay loop 
using in those functions.  If the delay loop is properly calibrated, 
these can be very accurate (but I suspect most people no longer 
calibrate the delay loop).

There is an app at apps/examples/calib_udelay that can be used to do that.


Re: Sleep Resolution

Posted by Xiang Xiao <xi...@gmail.com>.
Why not call up_udelay or up_mdelay? The arch/soc should provide a best
implementation for you.

On Thu, Mar 25, 2021 at 2:00 AM Fotis Panagiotopoulos <f....@gmail.com>
wrote:

> If you are using an ARM MCU you may find the following helpful.
> You must ensure that it cannot be scheduled out in any way though...
>
> (Directly copy-pasting from one of our HAL libraries... You will need to
> fine-tune it to your needs.)
>
> /**
>  * Multiplier value for the ASM delay function. The delay cycles will be
>  * the requested uSecs delay multiplied by this value. The ASM loop needs
>  * two instructions per loop, which need 2 cycles to execute (4 if branch
>  * predictor misses, but that would not be the case for most executions).
>  * Assuming a 180MHz clock we need 60 loops per microsecond.
>  * @note The value is verified to be accurate after oscilloscope
> measurements.
>  */
> #define DELAY_ASM_MULTIPLIER        ( 60 )
>
> void delayASM(uint32_t us)
> {
>     us *= DELAY_ASM_MULTIPLIER;
>
>     //This implementation is taking care of the loop in assembly
>     //instructions, making the result much more predictable than
>     //a standard for loop with "nop" instructions, and it is
>     //independent of the compiler, and its optimizations.
>     asm volatile("   mov r0, %[us]          \n\t"
>                  "1: subs r0, #1            \n\t"
>                  "   bhi 1b                 \n\t"
>                  :
>                  : [us] "r" (us)
>                  : "r0");
> }
>
> Στις Τετ, 24 Μαρ 2021 στις 7:53 μ.μ., ο/η Grr <ge...@gmail.com> έγραψε:
>
> > This is a SocketCAN driver for MCP2515 with a new SPI system that
> > streamlines the select->write->read->deselect process and so exposes the
> > need to guarantee hold time between read and deselect and disable time
> > between deselect and next select
> >
> > Looking at David's code, it seems the loop is the right answer. The DWT
> > cannot be used for a portable solution but maybe an inline function.
> Thanks
> > for the idea
> >
> > I believe NOPs are optimized away but it seems asm("") or something close
> > to that is not
> >
> > It would be nice to incorporate a general solution for this problem to
> the
> > Nuttx toolbox
> >
> > El mié, 24 mar 2021 a las 11:24, David Sidrane (<David.Sidrane@nscdg.com
> >)
> > escribió:
> >
> > > What HW is this on?
> > >
> > > -----Original Message-----
> > > From: Grr [mailto:gebbet00@gmail.com]
> > > Sent: Wednesday, March 24, 2021 10:09 AM
> > > To: dev@nuttx.apache.org
> > > Subject: Re: Sleep Resolution
> > >
> > > Thank you very much for your response
> > >
> > > What I'm trying to do is to generate hold and disable times for SPI CS,
> > > which should be about 50 ns
> > >
> > > I started by an empty for loop but it seems optimization gets rid of it
> > (I
> > > haven't researched the issue properly). Then I thought a proper
> function
> > > would be better but got stuck in that expression "sleep resolution"
> > >
> > > For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted
> to
> > > make sure there's not a more appropriate system tool
> > >
> > > El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
> > > saramonteirosouza44@gmail.com>) escribió:
> > >
> > > > Hi Grr,
> > > >
> > > > I have never needed to use this function neither this range (ns).
> > > > But I used the usleep function which resolution is defined as
> > > > CONFIG_USEC_PER_TICK.
> > > > But maybe, in your case, for such range, you should consider using a
> > > > hardware timer or a Timer Hook.
> > > > Take a look at this wiki:
> > > > https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
> > > >
> > > > Sara
> > > >
> > > > Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com>
> > escreveu:
> > > >
> > > > > Hello to all.
> > > > >
> > > > > Looking for the right way to create a _very_ short delay (10-100
> > ns), I
> > > > > found clock_nanosleep, whose description says:
> > > > >
> > > > > "The suspension time caused by this function may be longer than
> > > > > requested
> > > > > because the argument value is rounded up to an integer multiple of
> > the
> > > > > sleep resolution"
> > > > >
> > > > > What is the sleep resolution and where/how is defined?
> > > > >
> > > > > TIA
> > > > > Grr
> > > > >
> > > >
> > >
> >
>

Re: Sleep Resolution

Posted by Fotis Panagiotopoulos <f....@gmail.com>.
If you are using an ARM MCU you may find the following helpful.
You must ensure that it cannot be scheduled out in any way though...

(Directly copy-pasting from one of our HAL libraries... You will need to
fine-tune it to your needs.)

/**
 * Multiplier value for the ASM delay function. The delay cycles will be
 * the requested uSecs delay multiplied by this value. The ASM loop needs
 * two instructions per loop, which need 2 cycles to execute (4 if branch
 * predictor misses, but that would not be the case for most executions).
 * Assuming a 180MHz clock we need 60 loops per microsecond.
 * @note The value is verified to be accurate after oscilloscope
measurements.
 */
#define DELAY_ASM_MULTIPLIER        ( 60 )

void delayASM(uint32_t us)
{
    us *= DELAY_ASM_MULTIPLIER;

    //This implementation is taking care of the loop in assembly
    //instructions, making the result much more predictable than
    //a standard for loop with "nop" instructions, and it is
    //independent of the compiler, and its optimizations.
    asm volatile("   mov r0, %[us]          \n\t"
                 "1: subs r0, #1            \n\t"
                 "   bhi 1b                 \n\t"
                 :
                 : [us] "r" (us)
                 : "r0");
}

Στις Τετ, 24 Μαρ 2021 στις 7:53 μ.μ., ο/η Grr <ge...@gmail.com> έγραψε:

> This is a SocketCAN driver for MCP2515 with a new SPI system that
> streamlines the select->write->read->deselect process and so exposes the
> need to guarantee hold time between read and deselect and disable time
> between deselect and next select
>
> Looking at David's code, it seems the loop is the right answer. The DWT
> cannot be used for a portable solution but maybe an inline function. Thanks
> for the idea
>
> I believe NOPs are optimized away but it seems asm("") or something close
> to that is not
>
> It would be nice to incorporate a general solution for this problem to the
> Nuttx toolbox
>
> El mié, 24 mar 2021 a las 11:24, David Sidrane (<Da...@nscdg.com>)
> escribió:
>
> > What HW is this on?
> >
> > -----Original Message-----
> > From: Grr [mailto:gebbet00@gmail.com]
> > Sent: Wednesday, March 24, 2021 10:09 AM
> > To: dev@nuttx.apache.org
> > Subject: Re: Sleep Resolution
> >
> > Thank you very much for your response
> >
> > What I'm trying to do is to generate hold and disable times for SPI CS,
> > which should be about 50 ns
> >
> > I started by an empty for loop but it seems optimization gets rid of it
> (I
> > haven't researched the issue properly). Then I thought a proper function
> > would be better but got stuck in that expression "sleep resolution"
> >
> > For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
> > make sure there's not a more appropriate system tool
> >
> > El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
> > saramonteirosouza44@gmail.com>) escribió:
> >
> > > Hi Grr,
> > >
> > > I have never needed to use this function neither this range (ns).
> > > But I used the usleep function which resolution is defined as
> > > CONFIG_USEC_PER_TICK.
> > > But maybe, in your case, for such range, you should consider using a
> > > hardware timer or a Timer Hook.
> > > Take a look at this wiki:
> > > https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
> > >
> > > Sara
> > >
> > > Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com>
> escreveu:
> > >
> > > > Hello to all.
> > > >
> > > > Looking for the right way to create a _very_ short delay (10-100
> ns), I
> > > > found clock_nanosleep, whose description says:
> > > >
> > > > "The suspension time caused by this function may be longer than
> > > > requested
> > > > because the argument value is rounded up to an integer multiple of
> the
> > > > sleep resolution"
> > > >
> > > > What is the sleep resolution and where/how is defined?
> > > >
> > > > TIA
> > > > Grr
> > > >
> > >
> >
>

Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
This is a SocketCAN driver for MCP2515 with a new SPI system that
streamlines the select->write->read->deselect process and so exposes the
need to guarantee hold time between read and deselect and disable time
between deselect and next select

Looking at David's code, it seems the loop is the right answer. The DWT
cannot be used for a portable solution but maybe an inline function. Thanks
for the idea

I believe NOPs are optimized away but it seems asm("") or something close
to that is not

It would be nice to incorporate a general solution for this problem to the
Nuttx toolbox

El mié, 24 mar 2021 a las 11:24, David Sidrane (<Da...@nscdg.com>)
escribió:

> What HW is this on?
>
> -----Original Message-----
> From: Grr [mailto:gebbet00@gmail.com]
> Sent: Wednesday, March 24, 2021 10:09 AM
> To: dev@nuttx.apache.org
> Subject: Re: Sleep Resolution
>
> Thank you very much for your response
>
> What I'm trying to do is to generate hold and disable times for SPI CS,
> which should be about 50 ns
>
> I started by an empty for loop but it seems optimization gets rid of it (I
> haven't researched the issue properly). Then I thought a proper function
> would be better but got stuck in that expression "sleep resolution"
>
> For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
> make sure there's not a more appropriate system tool
>
> El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
> saramonteirosouza44@gmail.com>) escribió:
>
> > Hi Grr,
> >
> > I have never needed to use this function neither this range (ns).
> > But I used the usleep function which resolution is defined as
> > CONFIG_USEC_PER_TICK.
> > But maybe, in your case, for such range, you should consider using a
> > hardware timer or a Timer Hook.
> > Take a look at this wiki:
> > https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
> >
> > Sara
> >
> > Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:
> >
> > > Hello to all.
> > >
> > > Looking for the right way to create a _very_ short delay (10-100 ns), I
> > > found clock_nanosleep, whose description says:
> > >
> > > "The suspension time caused by this function may be longer than
> > > requested
> > > because the argument value is rounded up to an integer multiple of the
> > > sleep resolution"
> > >
> > > What is the sleep resolution and where/how is defined?
> > >
> > > TIA
> > > Grr
> > >
> >
>

Re: Sleep Resolution

Posted by Barbiani <ba...@gmail.com>.
How about adding a few nops with the interrupts disabled?

A context switch would take longer than this delay.

On Wed, Mar 24, 2021, 14:24 David Sidrane <Da...@nscdg.com> wrote:

> What HW is this on?
>
> -----Original Message-----
> From: Grr [mailto:gebbet00@gmail.com]
> Sent: Wednesday, March 24, 2021 10:09 AM
> To: dev@nuttx.apache.org
> Subject: Re: Sleep Resolution
>
> Thank you very much for your response
>
> What I'm trying to do is to generate hold and disable times for SPI CS,
> which should be about 50 ns
>
> I started by an empty for loop but it seems optimization gets rid of it (I
> haven't researched the issue properly). Then I thought a proper function
> would be better but got stuck in that expression "sleep resolution"
>
> For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
> make sure there's not a more appropriate system tool
>
> El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
> saramonteirosouza44@gmail.com>) escribió:
>
> > Hi Grr,
> >
> > I have never needed to use this function neither this range (ns).
> > But I used the usleep function which resolution is defined as
> > CONFIG_USEC_PER_TICK.
> > But maybe, in your case, for such range, you should consider using a
> > hardware timer or a Timer Hook.
> > Take a look at this wiki:
> > https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
> >
> > Sara
> >
> > Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:
> >
> > > Hello to all.
> > >
> > > Looking for the right way to create a _very_ short delay (10-100 ns), I
> > > found clock_nanosleep, whose description says:
> > >
> > > "The suspension time caused by this function may be longer than
> > > requested
> > > because the argument value is rounded up to an integer multiple of the
> > > sleep resolution"
> > >
> > > What is the sleep resolution and where/how is defined?
> > >
> > > TIA
> > > Grr
> > >
> >
>

RE: Sleep Resolution

Posted by David Sidrane <Da...@nscdg.com>.
What HW is this on?

-----Original Message-----
From: Grr [mailto:gebbet00@gmail.com]
Sent: Wednesday, March 24, 2021 10:09 AM
To: dev@nuttx.apache.org
Subject: Re: Sleep Resolution

Thank you very much for your response

What I'm trying to do is to generate hold and disable times for SPI CS,
which should be about 50 ns

I started by an empty for loop but it seems optimization gets rid of it (I
haven't researched the issue properly). Then I thought a proper function
would be better but got stuck in that expression "sleep resolution"

For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
make sure there's not a more appropriate system tool

El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
saramonteirosouza44@gmail.com>) escribió:

> Hi Grr,
>
> I have never needed to use this function neither this range (ns).
> But I used the usleep function which resolution is defined as
> CONFIG_USEC_PER_TICK.
> But maybe, in your case, for such range, you should consider using a
> hardware timer or a Timer Hook.
> Take a look at this wiki:
> https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
>
> Sara
>
> Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:
>
> > Hello to all.
> >
> > Looking for the right way to create a _very_ short delay (10-100 ns), I
> > found clock_nanosleep, whose description says:
> >
> > "The suspension time caused by this function may be longer than
> > requested
> > because the argument value is rounded up to an integer multiple of the
> > sleep resolution"
> >
> > What is the sleep resolution and where/how is defined?
> >
> > TIA
> > Grr
> >
>

Re: Sleep Resolution

Posted by Grr <ge...@gmail.com>.
Thank you very much for your response

What I'm trying to do is to generate hold and disable times for SPI CS,
which should be about 50 ns

I started by an empty for loop but it seems optimization gets rid of it (I
haven't researched the issue properly). Then I thought a proper function
would be better but got stuck in that expression "sleep resolution"

For that scale (10 SYSCLK cycles), a loop is probably OK but I wanted to
make sure there's not a more appropriate system tool

El mié, 24 mar 2021 a las 10:46, Sara da Cunha Monteiro de Souza (<
saramonteirosouza44@gmail.com>) escribió:

> Hi Grr,
>
> I have never needed to use this function neither this range (ns).
> But I used the usleep function which resolution is defined as
> CONFIG_USEC_PER_TICK.
> But maybe, in your case, for such range, you should consider using a
> hardware timer or a Timer Hook.
> Take a look at this wiki:
> https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays
>
> Sara
>
> Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:
>
> > Hello to all.
> >
> > Looking for the right way to create a _very_ short delay (10-100 ns), I
> > found clock_nanosleep, whose description says:
> >
> > "The suspension time caused by this function may be longer than requested
> > because the argument value is rounded up to an integer multiple of the
> > sleep resolution"
> >
> > What is the sleep resolution and where/how is defined?
> >
> > TIA
> > Grr
> >
>

Re: Sleep Resolution

Posted by Sara da Cunha Monteiro de Souza <sa...@gmail.com>.
Hi Grr,

I have never needed to use this function neither this range (ns).
But I used the usleep function which resolution is defined as
CONFIG_USEC_PER_TICK.
But maybe, in your case, for such range, you should consider using a
hardware timer or a Timer Hook.
Take a look at this wiki:
https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays

Sara

Em qua., 24 de mar. de 2021 às 13:37, Grr <ge...@gmail.com> escreveu:

> Hello to all.
>
> Looking for the right way to create a _very_ short delay (10-100 ns), I
> found clock_nanosleep, whose description says:
>
> "The suspension time caused by this function may be longer than requested
> because the argument value is rounded up to an integer multiple of the
> sleep resolution"
>
> What is the sleep resolution and where/how is defined?
>
> TIA
> Grr
>

RE: Sleep Resolution

Posted by David Sidrane <Da...@nscdg.com>.
Have a look at

https://github.com/PX4/PX4-Autopilot/blob/3ef93823f4b8f870b056549d321473a02fb69b1f/platforms/nuttx/src/px4/common/srgbled/srgbled.cpp#L112-L115


-----Original Message-----
From: Grr [mailto:gebbet00@gmail.com]
Sent: Wednesday, March 24, 2021 9:36 AM
To: dev@nuttx.apache.org
Subject: Sleep Resolution

Hello to all.

Looking for the right way to create a _very_ short delay (10-100 ns), I
found clock_nanosleep, whose description says:

"The suspension time caused by this function may be longer than requested
because the argument value is rounded up to an integer multiple of the
sleep resolution"

What is the sleep resolution and where/how is defined?

TIA
Grr