[Solved]Microsecond time value unreliable on L476

Please post bugs and enhancements for the STM core here
Post Reply
madman2003
Posts: 3
Joined: Sat May 13, 2017 7:58 am

[Solved]Microsecond time value unreliable on L476

Post by madman2003 » Sat May 13, 2017 8:04 am

When i use micros() value 10 times, i get this output:
1849:1786:1723:1660:1597:1534:1471:1408:1345:1282
1020:2956:2893:2830:2767:2704:2641:2578:2515:2452

The time goes backwards many times, but not always.

I'm using the 07-05-2017 STM32 core.

User avatar
Pito
Posts: 1626
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: Microsecond time value unreliable on L476

Post by Pito » Sat May 13, 2017 8:46 am

The more complex CPU the more issues with micros() :)
http://www.stm32duino.com/viewtopic.php ... =10#p27101
Pukao Hats Cleaning Services Ltd.

fpiSTM
Posts: 244
Joined: Fri Sep 16, 2016 12:33 pm
Location: Le Mans, France

Re: Microsecond time value unreliable on L476

Post by fpiSTM » Fri Jun 02, 2017 9:35 am


dannyf
Posts: 167
Joined: Wed May 11, 2016 4:29 pm

Re: Microsecond time value unreliable on L476

Post by dannyf » Sun Jun 04, 2017 10:17 am

I haven't had a chance to look at the code but sounds like the code isn't doing a good job taking care of atomicity between the overflow counter and the stick counter current value.

The usual solution is a double read.

Code: Select all


  1. Read the overflow counter.
  2. Read the systick current value.
  3. Read the overflow counter again. If it hasn't changed, the pair of readings is consistent.
  4. The time is overflow counter - systick value obtained in 2 above. That math is made easier if the overflow counter is given an offset equal to the reload value.
with a little bit time, here is my code used in ARMduino:

Code: Select all

	//use double reads
	do {
		m = timer_ticks;
		f = SysTick->VAL;		//24-bit only, downcounter
	} while (m != timer_ticks);
	//now m and f are atomic
	return (m - f) / clockCyclesPerMicrosecond();							//SysTick is a 24-bit downcounter
timer_ticks is my overflow counter. it is initialized with a value of (1ul<<24), and incremented with that value as well. the reload value is (1ul<<24)-1.

This approach utilizes the systick as a true 24-bit timer, thus lessens the load on the mcu to process the systick overflows - on a 16Mhz mcu, it overflows about once a second/1000ms. but it has to do a division for micros() or millis() calls -> not a problem for the higher-end chips with hardware divider. This problem can be lessened if your clockCyclesPerMicrosecond() is a static implementation -> known at compile time. But I used a dynamic implementation, allowing clock switch at run-time.

An alternate approach is to overflow systick every ms, by setting the systick reload register to SystemCoreClock() / 1000 - 1. This has the advantage that the timer overflow count is in ms, to millis() is very simple and of low cost, even on mcus without a hardware divider. it does overflow far more frequently, however.
Last edited by dannyf on Sun Jun 04, 2017 11:30 am, edited 2 times in total.

User avatar
Pito
Posts: 1626
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: Microsecond time value unreliable on L476

Post by Pito » Sun Jun 04, 2017 10:25 am

Pukao Hats Cleaning Services Ltd.

fpiSTM
Posts: 244
Joined: Fri Sep 16, 2016 12:33 pm
Location: Le Mans, France

Re: Microsecond time value unreliable on L476

Post by fpiSTM » Sun Jun 04, 2017 6:51 pm

Thanks.
I think I should review it :roll:
Probably, I will take your code pito. ;)

Post Reply