1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-23 16:25:26 +03:00

Merge pull request #3581 from iNavFlight/de_diehertz_micros_fix

Ensured micros() doesn't return a smaller value on millisecond bound
This commit is contained in:
Alberto García Hierro 2018-07-14 11:45:25 +01:00 committed by GitHub
commit 2081d30a67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 8 additions and 9 deletions

View file

@ -51,7 +51,8 @@ void registerExtiCallbackHandler(IRQn_Type irqn, extiCallbackHandlerFunc *fn)
// cycles per microsecond
STATIC_UNIT_TESTED timeUs_t usTicks = 0;
// current uptime for 1kHz systick timer. will rollover after 49 days. hopefully we won't care.
STATIC_UNIT_TESTED volatile timeMs_t sysTickUptime = 0;
STATIC_UNIT_TESTED volatile timeMs_t sysTickUptime = 0;
STATIC_UNIT_TESTED volatile uint32_t sysTickValStamp = 0;
// cached value of RCC->CSR
uint32_t cachedRccCsrValue;
@ -81,6 +82,7 @@ void SysTick_Handler(void)
{
ATOMIC_BLOCK(NVIC_PRIO_MAX) {
sysTickUptime++;
sysTickValStamp = SysTick->VAL;
sysTickPending = 0;
(void)(SysTick->CTRL);
}
@ -148,12 +150,8 @@ timeUs_t micros(void)
do {
ms = sysTickUptime;
cycle_cnt = SysTick->VAL;
/*
* If the SysTick timer expired during the previous instruction, we need to give it a little time for that
* interrupt to be delivered before we can recheck sysTickUptime:
*/
asm volatile("\tnop\n");
} while (ms != sysTickUptime);
} while (ms != sysTickUptime || cycle_cnt > sysTickValStamp);
return ((timeUs_t)ms * 1000LL) + (usTicks * 1000LL - (timeUs_t)cycle_cnt) / usTicks;
}

View file

@ -25,6 +25,7 @@ extern "C" {
#include "drivers/time.h"
extern timeUs_t usTicks;
extern volatile timeMs_t sysTickUptime;
extern volatile timeMs_t sysTickValStamp;
}
#include "unittest_macros.h"
@ -44,7 +45,7 @@ TEST(TimeUnittest, TestMillis)
TEST(TimeUnittest, TestMicros)
{
usTicks = 168;
SysTick->VAL = 1000 * usTicks;
sysTickValStamp = SysTick->VAL = 1000 * usTicks;
sysTickUptime = 0;
EXPECT_EQ(0, micros());
sysTickUptime = 1;
@ -58,7 +59,7 @@ TEST(TimeUnittest, TestMicros)
EXPECT_EQ(500000000, micros());
sysTickUptime = 0;
SysTick->VAL = 0;
sysTickValStamp = SysTick->VAL = 0;
EXPECT_EQ(1000, micros());
sysTickUptime = 1;
EXPECT_EQ(2000, micros());