Page 1 of 1

Using the TM module in 3.0.0

Posted: Tue Jul 08, 2014 9:37 pm
by Korken
Hi,

I've been looking for a good way to measure time between function calls and the TM module seems to be the way to go.
However I have some questions regarding its usage and implementation.

The TM module is based on the DWT which (if I read the manual correctly) clocks at the same rate as the system clock.
For example in my STM32F405RGT running at 168 MHz, this "timer" counts at 168 MHz.

Now to the questions.
--- The system should know from the initialization it's calculated clock rate (at least the ST start driver does this), is there a way to access this in ChibiOS? I could not find this in the documentation.
This would be very good to have when calculating a time from the counter.

--- The TM module does not seem to allow the chaining of multiple calls using a singe call (except chTMChainMeasurementToX(), but it needs two TM modules).
How is it meant to be used for chaining time measurements?

Code: Select all

...
chTMStopMeasurementX(&mytm); // Stop the old measurement
chTMStartMeasurementX(&mytm); // Start the new measurement
...  // Use the measurement in mytm
Would give erroneous results since tmp->last is overwritten by chTMStartMeasurementX(&mytm). Should one just readout tmp->last before starting a new measurement?

--- The TM module does not seem to take into account overflows of the DWT counter? Something like this is how I believe tm_stop() should be:

Code: Select all

static inline void tm_stop(time_measurement_t *tmp,
                           rtcnt_t now,
                           rtcnt_t offset) {

  tmp->n++;
  if (now > tmp->last)  /* No overflow */
    tmp->last = now - tmp->last - offset;
  else if (now < tmp->last)  /* Timer overflow */
    tmp->last = ((0xffffffff - tmp->last) + now) - offset;
  tmp->cumulative += (rttime_t)tmp->last;
  if (tmp->last > tmp->worst)
    tmp->worst = tmp->last;
  else if (tmp->last < tmp->best)
    tmp->best = tmp->last;
}
Or have I misread the code?

--- What is the meaning of ch.measurement_offset in chTMStopMeasurementX()? Why should an offset be added to the measured time?
Edit: Figured this one out. It is to compensate for the cycles needed to call chTMStopMeasurementX and chTMStartMeasurementX.

Please advice.

Best Regards
Emil

Re: Using the TM module in 3.0.0

Posted: Wed Jul 09, 2014 10:47 am
by Giovanni
You need two measurement structure since you are measuring two different things. HAL and OSAL export macros that help with conversion from cycles to time.

About the code, is it working? if so then probably there is not a problem, counters are meant to overflow.

Giovanni

Re: Using the TM module in 3.0.0

Posted: Wed Jul 09, 2014 12:33 pm
by Korken
Hi Giovanni,

I still don't understand why two structures are needed since I measure the same thing every time.
As an example I want to use this to measure the sampling rate of my sensor accurately. So I would do something like this:

Code: Select all

static time_measurement_t mytm;

void MySampleTimeMeasurement(bool first_time) {
  float dt;

  if (first_time == true) {
    /* Initialize the measurements */
    chTMObjectInit(&mytm);
    chTMStartMeasurementX(&mytm);
  } else {
    /* Stop and read the time */
    chTMStopMeasurementX(&mytm);

    /* Extract the time */
    dt = (float)RTC2US(GetFrequencyFromSomewhere(), mytm.last) / 1000000.0f;

    /* Restart the measurement for next time the function is called */
    chTMStartMeasurementX(&mytm);

    /*
     *
     * Rest of code that uses the time dt from the measurement.
     *
     */
  }
}
And this would not need two structures if I have read the TM code correctly.

About the macros to convert the ticks to time, I have found the RTC2US(freq, n) definition, however it requires freq as an input.
Where is freq available from ChibiOS as it can be caclulated from the PLL values? Does ChibiOS calculate this at initialization? Or must it me defined manually?

When it comes to the timer overflow, you are correct. :) I forgot the values were unsigned so it should not be a problem.

Best Regards
Emil

Re: Using the TM module in 3.0.0

Posted: Sat Apr 25, 2015 1:43 pm
by cruz_91
I know that few weeks passed from last reply but... I also tried to find mcu frequency function and couldn't find it.
If you still need STM32F4 core frequency in macro you can use this define:

#define STM32_CORE_FREQUENCY (((STM32_HSECLK/STM32_PLLM_VALUE)*STM32_PLLN_VALUE)/STM32_PLLP_VALUE)

STM32_HSECLK define is related to board.h. The other ones you can find in mcuconf.h

Re: Using the TM module in 3.0.0

Posted: Sat Apr 25, 2015 1:47 pm
by Giovanni
It is STM32_SYSCLK on all families.

Giovanni

Re: Using the TM module in 3.0.0

Posted: Sun Apr 26, 2015 12:22 am
by cruz_91
It really works! Thanks Giovanni!