elapsed time in nanoseconds

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

elapsed time in nanoseconds

5,509 Views
heinzroitner
Contributor II

Dear Freescale team,

in section 3.9.3.4 of MQXUG you say that I can get elapsed time in ns by calling _time_get_elapsed, followed by _time_get_nanoseconds.

The _time_get_elapsed gives something like 10 seconds, 756 milliseconds, right? Does the _time_get_nanoseconds then count the remaining ns ? It says 'ns since last periodic timer interrupt', when was this interrupt in our case?

Thanks for your help.

Heinz

17 Replies

2,686 Views
soledad
NXP Employee
NXP Employee

Hello Heinz Roitner,

Please check the below link

Delay in microsecond

let me know if this helps.
Have a great day,
Sol

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

2,686 Views
heinzroitner
Contributor II

Hi Sol,

the link refers how to create a time delay, but I need the time from MQX start, so I have to use _time_get_elapsed !

I would just need an example code how to apply  _time_get_elapsed  together with  _time_get_nanoseconds.

Thanks,

Heinz

0 Kudos

2,687 Views
RadekS
NXP Employee
NXP Employee

Basic MQX timing is based on ticks (default value of tick time is 5ms=5000us=5000000ns (200Hz timer)).

So, you can get elapsed time as

time_elapsed = (_time_get_elapsed_ticks() * tick time in ns) + _time_get_nanoseconds();

Of course, you have to also take into account size of this number (maximum uint32 value is approximately 4295 millions => 4.295s).

It depends for what reason you need it and what resolution you expect.

Of course, it depends also on timer which was selected as clock source. For example LPT timer runs at 1kHz and it has no sense measure something below 1ms.

I hope it helps you.


Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,687 Views
heinzroitner
Contributor II

Hi Radek,

thanks for your response. We have 2 points here:

1. maximal achievable resolution: in my code I have the line

    hwtimer_set_freq(&hwtimer, CM_CLOCK_SOURCE_SYSTEM, 8000);

   So I guess this is the clock source and it would limit the resolution to 1/8000 s = 125 us, right ?

2. So _time_get_nanoseconds()  counts the nanoseconds from the last tick, which is the 'last periodic interrupt' mentioned in MQXUG. Is that correct ?

Thanks,

Heinz

0 Kudos

2,687 Views
heinzroitner
Contributor II

One additional question: how high can I set the frequency in hwtimer_set_freq ? Can I read about this somewhere in MQXUG ?

Thanks, Heinz

0 Kudos

2,687 Views
RadekS
NXP Employee
NXP Employee
  1. _time_get_nanoseconds and _time_get_elapsed_ticks works with systick timer. I suppose that your hwtimer has nothing to do with systick timer (typically PIT timer). This systick timer is initialized in init_bsp.c file. Tick time is defined by BSP_ALARM_FREQUENCY macro. I would like to strongly recommend keep this value in ms (BSP_ALARM_FREQUENCY<1000)
  2. Yes
  3. It depends on type of timer and what is input clock (e.g. bus clock) for this timer module…Anyway, I would like to recommend call hwtimer_get_freq() function after you executed hwtimer_set_freq(). hwtimer_get_freq() will tell you real frequency which hw timer set.
0 Kudos

2,687 Views
heinzroitner
Contributor II

Now I don't think the hwtimer is relevant for this time measurement.

I would like to keep ticks at 5 ms rate (BSP_ALARM_FREQUENCY = 200), and measure the rest with _time_get_nanoseconds.

That way I get an elapsed time in ns from MQX start. I don't quite see why the clock source or clock rate should matter here? What do you think?

Thanks, Heinz

0 Kudos

2,687 Views
DavidS
NXP Employee
NXP Employee

Hi Heinz,

Hopefully this additional information helps.

The Kinetis processor by default is using the SysTick timer which is operating at the core processor frequency.

The SysTick is a count down timer that when the counter reaches zero, will generate an interrupt which indicates a 5ms Tick.  The countdown value is chosen based on core processor frequency and whatever count down value will generate an interrupt every 5ms.

When you call the _time_get_nanoseconds() function it is looking at the SysTick count down register to get the nanoseconds since the last Tick was generated.

Now the resolution of the nanosecond counter is dependent on the Kinetis device you are using. As example with the K70 operating at 120MHz the nanosecond resolution is 8.33nsec.

I played around with the MQX4.1/mqx/examples/isr example to see how many times I would read the _time_get_nanoseconds() and fill result into a buffer.

I set a breakpoint to stop/halt/break when the SW1 switch is pressed (again I did this on the TWR-K70F120M) and then added the global variable ns_buff[] to the variable window to look at it.

Regards,

David

0 Kudos

2,687 Views
michaelschwager
Contributor III

Hi, I have MK60DN512VLQ10 running MQX 4.1.  I haven't messed with any of the timings in MQX.

My PTC.3 GPIO pin (FB_CLKOUT) is running at 48MHz.  I think I read someplace that FB_CLKOUT is the core clock/2, so this means my core clock is 96MHz.  Does this make sense?  Why isn't it running at 100MHz per the spec for this particular K60?  Where can I change this so it runs at the correct speed (100Mhz)?  Any time I've tried messing with the clock definition files it never works the way I expect, so I've learned to leave them alone.

When I do _time_get_hwticks_per_tick I get 480,000, but you're saying by default there is 1 core clock per tick, not 2.

Can you please confirm then that there are 480,000 hwticks in 5ms, but the actual CPU is running at 96MHz?

Do these clocks stop when I'm stopped at a breakpoint when debugging?  I'm using IAR if that's relevant.

Thanks

0 Kudos

2,687 Views
DavidS
NXP Employee
NXP Employee

Hi Michael,

Good questions and observations.

For the K60-100MHz device.

The core clock is operating at 96MHz (you are correct that you could tweak it to 100MHz but read below for why 96MHz used).

The peripheral clock is operating at 1/2 of the core processor clock.

The bus clock is operating at 1/2 of the core processor clock.

The  flash clock is limited to 25MHz or less (it has a wider bus with prefetching and other stuff to help keep the core fed with instructions).


Typical SIM_CLKDIV1[OUTDIV1-4] fields set to dividers are 1:2:2:4 so the respective frequencies are 96:48:48:24MHz.


Why 96MHz?  Because the peripheral bus that the USB module is connected to requires 48MHz for proper operation.  If not using USB you can setup max frequency of core to 100MHz.


The Clock Distribution section of the silicon Reference Manual cover this.


I'll look into the _time_get_hwticks_per_tick returns 480,000 SysTicks per 5ms window.  96MHz*5Ms = 480,000..

Regards,

David

0 Kudos

2,687 Views
michaelschwager
Contributor III

Thanks, that makes sense. I’m not using USB. Is there a one-line change someplace in one of the config files to bump this up to 100MHz?

0 Kudos

2,687 Views
DavidS
NXP Employee
NXP Employee

Hi Michael,

Sort of.....in bsp_cm.h you could update the clock configuration 0 from the below define's to your define's (conveniently in hex....sorry) to get to 100:50:50:25 MHz or you could use Processor Expert in CW10.6 to access the BSP Processor Expert component and use the GUI to change the clocking.

/* CPU frequencies in clock configuration 0 */

#define CPU_CLOCK_CONFIG_0              0x00U           /* Clock configuration 0 identifier */

#define CPU_CORE_CLK_HZ_CONFIG_0        0x05B8D800UL    /* Core clock frequency in clock configuration 0 */

#define CPU_BUS_CLK_HZ_CONFIG_0         0x02DC6C00UL    /* Bus clock frequency in clock configuration 0 */

#define CPU_FLEXBUS_CLK_HZ_CONFIG_0     0x02DC6C00UL    /* Flexbus clock frequency in clock configuration 0 */

#define CPU_FLASH_CLK_HZ_CONFIG_0       0x016E3600UL    /* FLASH clock frequency in clock configuration 0 */

#define CPU_USB_CLK_HZ_CONFIG_0         0x02DC6C00UL    /* USB clock frequency in clock configuration 0 */

#define CPU_PLL_FLL_CLK_HZ_CONFIG_0     0x05B8D800UL    /* PLL/FLL clock frequency in clock configuration 0 */

#define CPU_MCGIR_CLK_HZ_CONFIG_0       0x00UL          /* MCG internal reference clock frequency in clock configuration 0 */

#define CPU_OSCER_CLK_HZ_CONFIG_0       0x02FAF080UL    /* System OSC external reference clock frequency in clock configuration 0 */

#define CPU_ERCLK32K_CLK_HZ_CONFIG_0    0x8000UL        /* External reference clock 32k frequency in clock configuration 0 */

#define CPU_MCGFF_CLK_HZ_CONFIG_0       0x5F5EUL        /* MCG fixed frequency clock */

Regards,

David

0 Kudos

2,687 Views
heinzroitner
Contributor II

Hi David,

so are you telling me that _time_get_nanoseconds will not get me real ns but something I can only determine by experiment depending on processor ?

What about _time_get_microseconds, here the same? No real us ?

What is the SW1 switch ? Could you describe the buffer experiment im more detail to me ?

Thanks, Heinz

0 Kudos

2,687 Views
DavidS
NXP Employee
NXP Employee

Hi Heinz,

Not sure how to answer your question but let me try.

Every Kinetis device uses the SysTick timer as its master clock source. Different Kinetis devices can be clocked at different frequencies. K70 @120 or 150MHz, K60 @100, etc… So the range is 50-150MHz depending on the device.

In MQX the SysTick timer is clocked at the core frequency.

Ex: Using the K70-120MHz as my example 120MHz has an 8.333 nanosecond/SysTick.

MQX calculates the SysTick timer count down value to generate an interrupt every 5ms.

Ex: 5ms/8.333nanoseconds = 600024 SysTicks.

When you are calling the timeget_nanoseconds() function in the PSP time.c file, it is grabbing the SysTick counter value and scaling it to return a value in nanoseconds since the last MQX Tick occurred.

This value is based off of hardware so it is real. But the resolution is based on the SysTick counting rate which ic equal to the process core frequency. Faster processor core frequency means better resolution.

The accuracy of the timeget_microseconds() function call is better than the timeget_nanoseconds() function call since there are 120 SysTick clocks per microsecond.

With respect to SW1. I was just placing a breakpoint in the btn_kernel_isr() routine as a place to stop and then use IDE to inspect the variable window. Nothing more.

With respect to your code to get the TICKS from start of MQX I modified it to the following:

#if 1 //DES 1=test, 0=default code

{

MQX_TICK_STRUCT tickstruct;

uint32 ticknum[2];

timeget_elapsed_ticks(&tickstruct);

ticknum[0] = tickstruct.TICKS[0]; //DES lower 32-bits

ticknum[1] = tickstruct.TICKS[1]; //DES upper 32-bits

printf("\n ticknum64 = %u%u\n", ticknum[1], ticknum[0]); //DES 64-bit TICKS value.

}

#endif

Hope this helps.

Regards,

David

0 Kudos

2,687 Views
heinzroitner
Contributor II

Hi David,

thanks for your answer. One last question: what you call SysTick is equal to the field HWTICKS in MQX_TICK_STRUCT ?

Best regards,

Heinz

0 Kudos

2,687 Views
DavidS
NXP Employee
NXP Employee

Hi Heinz,

Correct.  The SysTick is hardware in the core doing the clocking and the HWTICKS gets updated from the SysTick timer.

Happy clocking ;-)

Regards,

David

0 Kudos

2,687 Views
heinzroitner
Contributor II

Hi David,

I am also confused about the  mqx_tick_struct  format. It has the fields TICKS[MQX_NUM_TICK_FIELDS] and HWTICKS.

So if I want to get the number of  5 ms ticks since MQX start, can I do

MQX_TICK_STRUCT tickstruct;

uint32 ticknum;

_time_get_elapsed_ticks(&tickstruct);

ticknum = tickstruct.TICKS[0];  // 0 or what else ?

Hope you can help.

Heinz

0 Kudos