Page 1 of 1

Real Time Clock, once again

Posted: Mon Apr 14, 2014 3:41 am
by russian
I am not sure if this is ChibiIOS question or maybe a general stm32 question or maybe even general programming question:

I am trying to implement precise event scheduling. I use

Code: Select all

#define CH_FREQUENCY 100000

(that's 0.01ms sysclock)

Now, let's assume that I am generating PWM programmatically (that would be just an example):

Code: Select all

while(true) {
  time nextHalfMs = (chTimeNow() + 49) % 50;
  timeToSleep = nextHalfMs  - chTimeNow();
  chThdSleep(timeToSleep);
  toggelePin();
}


This code is supposed to sleep till the next half-millisecond point in time, do job, and loop.

Now the reality: chTimeNow() would always use HSE, right? HSE is not exactly precise, it ticks +-10% to real time. So, my code would not generate a 1KHz PWM but it would generate something like a 910Hz or 1100Hz PWM. How can I improve precision?

I cannot use LSE because LSE granularity is 1ms (is it?), so I cannot measure half a ms times using LSE via RTC. Also there is 'sleep till RTC point' function.

Ideas? Suggestions? How stable is HSE precision? Should I run some dynamic precision test by measuring a second with LSE and with HSE, and adjust to that HSE time error coefficient? That would only help me is HSE imprecision is stable. Is it? Does it depend on temperature or the weather on mars or is it changing over time randomly?

Re: Real Time Clock, once again

Posted: Mon Apr 14, 2014 7:19 am
by Giovanni
HSE should be very precise, that kind of errors should not be there.

Are there any other things that may interfere with that code? threads, very long ISRs?

Note that 100kHz as system tick is way beyond what I would recommend.

Giovanni

Re: Real Time Clock, once again

Posted: Mon Apr 14, 2014 12:38 pm
by russian
Will run some tests with most of the threads disabled.

Giovanni wrote:Note that 100kHz as system tick is way beyond what I would recommend.

Why is that? Can you please elaborate?

Re: Real Time Clock, once again

Posted: Mon Apr 14, 2014 6:20 pm
by Giovanni
It means that you CPU has to serve 100000 interrupts per second doing almost nothing. You are wasting your CPU time and worsening the response time for all other interrupts.

Giovanni

Re: Real Time Clock, once again

Posted: Mon Apr 14, 2014 6:47 pm
by russian
Right, I should probably go back to the default CH_FREQUENCY1000.
One of the requirements I have is sub-ms time measurement. I am now considering either a FAST_IRQ which would be just incrementing a time counter, or maybe a 64 bit counter based on hal_lld_get_counter_value(). That's unless I am missing a better way to get a sub-ms time counter.

Re: Real Time Clock, once again

Posted: Sat Apr 26, 2014 8:02 pm
by Vic20
I don't get it.

Why do you need to have such high frequencies programatically.
Over 1kHz it is best to be done at hardware level using timers in capture or compare mode for instace.

Of course generating an interrupt al high frequency will be better that switching thread contexts at the same frequency. But I'm sure that whatever you want to do can be done, at least in part, in hardware using a MCU peripheral.

Vicente

Re: Real Time Clock, once again

Posted: Sat Apr 26, 2014 9:21 pm
by russian
Vic20 wrote:Why do you need to have such high frequencies programatically.

That's because I do not enjoy the limitations of hardware timers. If there were 32 HW timers which would be able to drive any of the 176 pins I would go with that.

I think I've got what I wanted: I have a 1MHz timer in one-shot mode which I constantly set to the time of the soonest event, I use a 64 bit cycle counter for time measurements - that combined has allowed me to get back to CH_FREQUENCY 1000 and that has resolved the issue of too much CPU used for thread switches.

See https://svn.code.sf.net/p/rusefi/code/t ... ecutor.cpp

Re: Real Time Clock, once again

Posted: Sat Apr 26, 2014 9:59 pm
by Vic20
russian wrote:I think I've got what I wanted: I have a 1MHz timer in one-shot mode which I constantly set to the time of the soonest event, I use a 64 bit cycle counter for time measurements - that combined has allowed me to get back to CH_FREQUENCY 1000 and that has resolved the issue of too much CPU used for thread switches.


Ok, that's the kind of think I thought.

In one project I used timer programed with a repetitive RSI on compare event instead of one shot. After each compare I increment the compare to the next time to have the interrupt. It works ok for times smaller than the period of a full counter cycle. But you have some 32 bit counters in the STM32 MCUs so it should be no problem.
Moreover, as the timer is always ON, the start of interrupts have always the exact programmed interval.

That needs to access the internal MCU registers of course.