You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@nuttx.apache.org by Michal Lenc <mi...@seznam.cz> on 2021/07/11 14:01:52 UTC

Tickless mode for iMXRT MCU

Hello,




I´ve finished the implementation of tickless mode support for iMXRT MCU, 
which is a part of my Google Summor of Code project (https://cwiki.apache.
org/confluence/display/NUTTX/%5B2021%5D+NuttX+Support+for+Rapid+Control+
Applications+Development+with+pysimCoder). The source code can be found here
in my NuttX fork (https://github.com/michallenc/incubator-nuttx/blob/imxrt-
tickless/arch/arm/src/imxrt/imxrt_tickless.c), I used the alarm option to 
take the advantage of using just one timer running in free-run mode. I did 
some tests with applications (ADC reading example and control application of
DC motor designed with pysimCoder) and they are working fine, but command 
"sleep" bothers me a little bit.




When I compile normal NuttX nsh configuration with tickless mode, "sleep 2" 
is accurate and takes about 2.0001 seconds. But when I use some bigger 
configuration (like configurating PWM, qencoder, GPIO, ethernet and so on 
for DC motor control), "sleep 2" is much less accurate. Sometimes it really 
takes 2 seconds, but sometimes I get values like 1.9947 (I am using "time" 
command). I did found out that sleep command takes one tick more in normal 
mode, can some of those inaccuracies also happen in tickless mode?




The other source of the inaccuracy can be in clock frequency. I use 32 kHz 
clock source, but this value cannot be properly represented by CONFIG_USEC_
PER_TICK, which I set to 31 (which is aproximately 32.25 kHz). But 32 kHz 
clock source seems to be the only possible in iMXRT as others are to hight 
(tens or hundreds of MHz) and can´t be represended by the timer prescaler 
divider. Did anyone have similar problems when implementing tickless mode 
for some platforms?




Thanks for your inputs.


Best regards,
Michal Lenc

Re: Tickless mode for iMXRT MCU

Posted by Michal Lenc <mi...@seznam.cz>.
Hi Alan,




thanks for the link! I will take a look into it.


Best regards,
Michal Lenc

---------- Původní e-mail ----------
Od: Alan Carvalho de Assis <ac...@gmail.com>
Komu: dev@nuttx.apache.org
Datum: 11. 7. 2021 16:19:59
Předmět: Re: Tickless mode for iMXRT MCU 
"Hi Michal, 

Please take a look at this wiki page, it could help you to understand 
the issue with sleep take one more context switch cycle: 
https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays 

Unfortunately the Timer Hook that could help you in this case will not 
work in Tickless mode (according with the wiki). 

BR, 

Alan 

On 7/11/21, Michal Lenc <mi...@seznam.cz> wrote: 
> 
> Hello, 
> 
> 
> 
> 
> I´ve finished the implementation of tickless mode support for iMXRT MCU, 
> which is a part of my Google Summor of Code project (https://cwiki.apache.

> org/confluence/display/NUTTX/%5B2021%5D+NuttX+Support+for+Rapid+Control+ 
> Applications+Development+with+pysimCoder). The source code can be found 
> here 
> in my NuttX fork (https://github.com/michallenc/incubator-nuttx/blob/imxrt
- 
> tickless/arch/arm/src/imxrt/imxrt_tickless.c), I used the alarm option to 
> take the advantage of using just one timer running in free-run mode. I did

> some tests with applications (ADC reading example and control application 
> of 
> DC motor designed with pysimCoder) and they are working fine, but command 
> "sleep" bothers me a little bit. 
> 
> 
> 
> 
> When I compile normal NuttX nsh configuration with tickless mode, "sleep 
2" 
> 
> is accurate and takes about 2.0001 seconds. But when I use some bigger 
> configuration (like configurating PWM, qencoder, GPIO, ethernet and so on 
> for DC motor control), "sleep 2" is much less accurate. Sometimes it 
really 
> 
> takes 2 seconds, but sometimes I get values like 1.9947 (I am using "time"

> command). I did found out that sleep command takes one tick more in normal

> mode, can some of those inaccuracies also happen in tickless mode? 
> 
> 
> 
> 
> The other source of the inaccuracy can be in clock frequency. I use 32 kHz

> clock source, but this value cannot be properly represented by CONFIG_USEC
_ 
> PER_TICK, which I set to 31 (which is aproximately 32.25 kHz). But 32 kHz 
> clock source seems to be the only possible in iMXRT as others are to hight

> (tens or hundreds of MHz) and can´t be represended by the timer prescaler 
> divider. Did anyone have similar problems when implementing tickless mode 
> for some platforms? 
> 
> 
> 
> 
> Thanks for your inputs. 
> 
> 
> Best regards, 
> Michal Lenc 
"

Re: Tickless mode for iMXRT MCU

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

Please take a look at this wiki page, it could help you to understand
the issue with sleep take one more context switch cycle:
https://cwiki.apache.org/confluence/display/NUTTX/Short+Time+Delays

Unfortunately the Timer Hook that could help you in this case will not
work in Tickless mode (according with the wiki).

BR,

Alan

On 7/11/21, Michal Lenc <mi...@seznam.cz> wrote:
>
> Hello,
>
>
>
>
> I´ve finished the implementation of tickless mode support for iMXRT MCU,
> which is a part of my Google Summor of Code project (https://cwiki.apache.
> org/confluence/display/NUTTX/%5B2021%5D+NuttX+Support+for+Rapid+Control+
> Applications+Development+with+pysimCoder). The source code can be found
> here
> in my NuttX fork (https://github.com/michallenc/incubator-nuttx/blob/imxrt-
> tickless/arch/arm/src/imxrt/imxrt_tickless.c), I used the alarm option to
> take the advantage of using just one timer running in free-run mode. I did
> some tests with applications (ADC reading example and control application
> of
> DC motor designed with pysimCoder) and they are working fine, but command
> "sleep" bothers me a little bit.
>
>
>
>
> When I compile normal NuttX nsh configuration with tickless mode, "sleep 2"
>
> is accurate and takes about 2.0001 seconds. But when I use some bigger
> configuration (like configurating PWM, qencoder, GPIO, ethernet and so on
> for DC motor control), "sleep 2" is much less accurate. Sometimes it really
>
> takes 2 seconds, but sometimes I get values like 1.9947 (I am using "time"
> command). I did found out that sleep command takes one tick more in normal
> mode, can some of those inaccuracies also happen in tickless mode?
>
>
>
>
> The other source of the inaccuracy can be in clock frequency. I use 32 kHz
> clock source, but this value cannot be properly represented by CONFIG_USEC_
> PER_TICK, which I set to 31 (which is aproximately 32.25 kHz). But 32 kHz
> clock source seems to be the only possible in iMXRT as others are to hight
> (tens or hundreds of MHz) and can´t be represended by the timer prescaler
> divider. Did anyone have similar problems when implementing tickless mode
> for some platforms?
>
>
>
>
> Thanks for your inputs.
>
>
> Best regards,
> Michal Lenc

Re: Tickless mode for iMXRT MCU

Posted by Gregory Nutt <sp...@gmail.com>.
>
>> To avoid the accumulation of conversion error, the count in timer driver
>> should use the same time unit as the hardware. BTW, your timer driver 
>> has
>> to implement the up_alarm_xxx functions.
>
> Unfortunately, 32.768KHz is a very common clock frequency and it 
> cannot be handled by the current logic.  Without a massive overhaul of 
> the timing definitions, the only solution that I know is keep a RAM 
> copy of the time that has been corrected for the differences in precision.

Can you multiply the 32.768KHz clock to improve the precision (but not 
the resolution)?

Or, perhaps, just scale the timer in software?  The LSB is 30.517578 
usec.  Shifting the timer value by 9 left would result in an LSB of 
15,625 which is exact.




Re: Tickless mode for iMXRT MCU

Posted by Gregory Nutt <sp...@gmail.com>.
> To avoid the accumulation of conversion error, the count in timer driver
> should use the same time unit as the hardware. BTW, your timer driver has
> to implement the up_alarm_xxx functions.

Unfortunately, 32.768KHz is a very common clock frequency and it cannot 
be handled by the current logic.  Without a massive overhaul of the 
timing definitions, the only solution that I know is keep a RAM copy of 
the time that has been corrected for the differences in precision.



Re: Tickless mode for iMXRT MCU

Posted by Xiang Xiao <xi...@gmail.com>.
To avoid the accumulation of conversion error, the count in timer driver
should use the same time unit as the hardware. BTW, your timer driver has
to implement the up_alarm_xxx functions.

On Sun, Jul 11, 2021 at 9:10 AM Gregory Nutt <sp...@gmail.com> wrote:

> Actually, the situation is much worse:
>
> https://github.com/apache/incubator-nuttx/blob/master/boards/arm/sama5/sama5d3x-ek/README.txt#L2823
>
> If you use 32.768KHz clock source, then there is a small error in every
> time conversion since 1/32768 cannot be represented in microseconds.
> Normally, this will result in small errors as you have noted.  However,
> in a very busy system with man timers, that error builds up and can be
> quite large... like 50% error!  See the above reference.
>
> That huge error is not acceptable in most cases.
>
> On 7/11/2021 9:16 AM, Gregory Nutt wrote:
> >
> >> The other source of the inaccuracy can be in clock frequency. I use
> >> 32 kHz
> >> clock source, but this value cannot be properly represented by
> >> CONFIG_USEC_
> >> PER_TICK, which I set to 31 (which is aproximately 32.25 kHz). But 32
> >> kHz
> >> clock source seems to be the only possible in iMXRT as others are to
> >> hight
> >> (tens or hundreds of MHz) and can´t be represended by the timer
> >> prescaler
> >> divider. Did anyone have similar problems when implementing tickless
> >> mode
> >> for some platforms?
> >
> > I ran into this same issue with some Atmel SAM parts (I forget which)
> > and I think that there is some discussion in the README files somewhere.
> >
> > I never really found a great solution.  Options that I though of:
> >
> > - Change CONFIG_USEC_PER_TICK to CONFIG_TICK_FREQUENCY.  A frequency
> > can be represented with an integer more accurately that can a time
> > period.  32768Hz is exact where as 1/32768 sec = 0.000030517578125...
> > sec cannot be represented exactly in microseconds.
> >
> > - Use some kind of internal, higher precision, accurate version of
> > event time that is converted to and from the hardware clock time.
> >
> > I didn't like either of these because the first would affect a lot of
> > code and the second could be computationally expensive.
> >
> >
>
>

Re: Tickless mode for iMXRT MCU

Posted by Michal Lenc <mi...@seznam.cz>.
Hi Greg,




thanks for your advices.





> If you use 32.768KHz clock source, then there is a small error in every 
> time conversion since 1/32768 cannot be represented in microseconds.  
> Normally, this will result in small errors as you have noted.  However, 
> in a very busy system with man timers, that error builds up and can be 
> quite large... like 50% error!  See the above reference. 




I managed to find the (hopefully) right clock value for the GPT timer. If I 
use peripheral clock at 16.6 MHz (which is already the set value for iMXRT 
MCU) as a clock source, this value can be divided by 1660 prescaler for 100 
usec CONFIG_USEC_PER_TICK or by 166 prescaler for 10 usec CONFIG_USEC_PER_
TICK. Both values would mean that the clock frequency of GPT timer is equal 
to CONFIG_USEC_PER_TICK (or to its frequency more precisely). I did some 
tests and it seems that those inaccuracies I was having with 32.768 kHz 
clock source are not a problem now. I will do some further tests before 
creating the PR thought.




Best regards,
Michal Lenc

Re: Tickless mode for iMXRT MCU

Posted by Gregory Nutt <sp...@gmail.com>.
Actually, the situation is much worse: 
https://github.com/apache/incubator-nuttx/blob/master/boards/arm/sama5/sama5d3x-ek/README.txt#L2823

If you use 32.768KHz clock source, then there is a small error in every 
time conversion since 1/32768 cannot be represented in microseconds.  
Normally, this will result in small errors as you have noted.  However, 
in a very busy system with man timers, that error builds up and can be 
quite large... like 50% error!  See the above reference.

That huge error is not acceptable in most cases.

On 7/11/2021 9:16 AM, Gregory Nutt wrote:
>
>> The other source of the inaccuracy can be in clock frequency. I use 
>> 32 kHz
>> clock source, but this value cannot be properly represented by 
>> CONFIG_USEC_
>> PER_TICK, which I set to 31 (which is aproximately 32.25 kHz). But 32 
>> kHz
>> clock source seems to be the only possible in iMXRT as others are to 
>> hight
>> (tens or hundreds of MHz) and can´t be represended by the timer 
>> prescaler
>> divider. Did anyone have similar problems when implementing tickless 
>> mode
>> for some platforms?
>
> I ran into this same issue with some Atmel SAM parts (I forget which) 
> and I think that there is some discussion in the README files somewhere.
>
> I never really found a great solution.  Options that I though of:
>
> - Change CONFIG_USEC_PER_TICK to CONFIG_TICK_FREQUENCY.  A frequency 
> can be represented with an integer more accurately that can a time 
> period.  32768Hz is exact where as 1/32768 sec = 0.000030517578125...  
> sec cannot be represented exactly in microseconds.
>
> - Use some kind of internal, higher precision, accurate version of 
> event time that is converted to and from the hardware clock time.
>
> I didn't like either of these because the first would affect a lot of 
> code and the second could be computationally expensive.
>
>


Re: Tickless mode for iMXRT MCU

Posted by Gregory Nutt <sp...@gmail.com>.
> The other source of the inaccuracy can be in clock frequency. I use 32 kHz
> clock source, but this value cannot be properly represented by CONFIG_USEC_
> PER_TICK, which I set to 31 (which is aproximately 32.25 kHz). But 32 kHz
> clock source seems to be the only possible in iMXRT as others are to hight
> (tens or hundreds of MHz) and can´t be represended by the timer prescaler
> divider. Did anyone have similar problems when implementing tickless mode
> for some platforms?

I ran into this same issue with some Atmel SAM parts (I forget which) 
and I think that there is some discussion in the README files somewhere.

I never really found a great solution.  Options that I though of:

- Change CONFIG_USEC_PER_TICK to CONFIG_TICK_FREQUENCY.  A frequency can 
be represented with an integer more accurately that can a time period.  
32768Hz is exact where as 1/32768 sec = 0.000030517578125...  sec cannot 
be represented exactly in microseconds.

- Use some kind of internal, higher precision, accurate version of event 
time that is converted to and from the hardware clock time.

I didn't like either of these because the first would affect a lot of 
code and the second could be computationally expensive.