mirror of https://github.com/rusefi/rusefi.git
only:WrapAround62 goes to libfirmware
This commit is contained in:
parent
78e48d3718
commit
1d64003dd6
|
@ -1 +1 @@
|
||||||
Subproject commit 6af2fd11d7d35abdd893ab5520409c7c3ba29ee7
|
Subproject commit 2017ab12ffed28c75ee752fe277d1f36281e3803
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#if !EFI_UNIT_TEST
|
#if !EFI_UNIT_TEST
|
||||||
|
|
||||||
|
#include <rusefi/rusefi_time_wraparound.h>
|
||||||
|
|
||||||
static WrapAround62 timeNt;
|
static WrapAround62 timeNt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,37 +29,6 @@
|
||||||
// See USF2NT above for when to use MSF2NT
|
// See USF2NT above for when to use MSF2NT
|
||||||
#define MSF2NT(msTimeFloat) USF2NT(MS2US(msTimeFloat))
|
#define MSF2NT(msTimeFloat) USF2NT(MS2US(msTimeFloat))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/**
|
|
||||||
* Provide a 62-bit counter from a 32-bit counter source that wraps around.
|
|
||||||
*
|
|
||||||
* If you'd like it use it with a 16-bit counter, shift the source by 16 before passing it here.
|
|
||||||
* This class is thread/interrupt-safe.
|
|
||||||
*/
|
|
||||||
struct WrapAround62 {
|
|
||||||
uint64_t update(uint32_t source) {
|
|
||||||
// Shift cannot be 31, as we wouldn't be able to tell if time is moving forward or
|
|
||||||
// backward relative to m_upper. We do need to handle both directions as our
|
|
||||||
// "thread" can be racing with other "threads" in sampling stamp and updating
|
|
||||||
// m_upper.
|
|
||||||
constexpr unsigned shift = 30;
|
|
||||||
|
|
||||||
uint32_t upper = m_upper;
|
|
||||||
uint32_t relative_unsigned = source - (upper << shift);
|
|
||||||
upper += int32_t(relative_unsigned) >> shift;
|
|
||||||
m_upper = upper;
|
|
||||||
|
|
||||||
// Yes we could just do upper<<shift, but then the result would span both halves of
|
|
||||||
// the 64-bit result. Doing it this way means we only operate on one half at a
|
|
||||||
// time. Source will supply those bits anyways, so we don't need them from
|
|
||||||
// upper...
|
|
||||||
return (efitick_t(upper >> (32 - shift)) << 32) | source;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
volatile uint32_t m_upper = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a monotonically increasing (but wrapping) 32-bit timer value
|
* Get a monotonically increasing (but wrapping) 32-bit timer value
|
||||||
* Implemented at port level, based on timer or CPU tick counter
|
* Implemented at port level, based on timer or CPU tick counter
|
||||||
|
@ -76,5 +45,3 @@ efitimems_t getTimeNowMs();
|
||||||
* @brief Current system time in seconds.
|
* @brief Current system time in seconds.
|
||||||
*/
|
*/
|
||||||
efitimesec_t getTimeNowS();
|
efitimesec_t getTimeNowS();
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
|
@ -456,72 +456,6 @@ TEST(util, PeakDetect) {
|
||||||
EXPECT_EQ(dut.detect(500, startTime + timeout + 1), 500);
|
EXPECT_EQ(dut.detect(500, startTime + timeout + 1), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(util, WrapAround62) {
|
|
||||||
// Random test
|
|
||||||
{
|
|
||||||
WrapAround62 t;
|
|
||||||
uint32_t source = 0;
|
|
||||||
uint64_t actual = 0;
|
|
||||||
|
|
||||||
// Test random progression, positive and negative.
|
|
||||||
uint32_t seed = time(NULL);
|
|
||||||
printf("Testing with seed 0x%08x\n", seed);
|
|
||||||
srand(seed);
|
|
||||||
for (unsigned i = 0; i < 10000; i++) {
|
|
||||||
int32_t delta = rand();
|
|
||||||
if (delta < 0) {
|
|
||||||
delta = ~delta;
|
|
||||||
}
|
|
||||||
delta -= RAND_MAX >> 1;
|
|
||||||
|
|
||||||
// Cap negative test
|
|
||||||
if (delta < 0 && -delta > actual) {
|
|
||||||
delta = -actual;
|
|
||||||
}
|
|
||||||
|
|
||||||
source += delta;
|
|
||||||
actual += delta;
|
|
||||||
|
|
||||||
uint64_t next = t.update(source);
|
|
||||||
EXPECT_EQ(actual, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// More pointed test for expected edge conditions
|
|
||||||
{
|
|
||||||
WrapAround62 t;
|
|
||||||
|
|
||||||
EXPECT_EQ(t.update(0x03453455), 0x003453455LL);
|
|
||||||
EXPECT_EQ(t.update(0x42342323), 0x042342323LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
|
|
||||||
EXPECT_EQ(t.update(0x42342323), 0x042342323LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x0C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x01122112), 0x101122112LL); // Wrap around!
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x0C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x0C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x01122112), 0x101122112LL); // Wrap around!
|
|
||||||
EXPECT_EQ(t.update(0x42342323), 0x142342323LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
|
|
||||||
EXPECT_EQ(t.update(0x42342323), 0x142342323LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x01122112), 0x201122112LL); // Wrap around!
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x01122112), 0x201122112LL); // Wrap around!
|
|
||||||
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
|
|
||||||
EXPECT_EQ(t.update(0x42342323), 0x142342323LL);
|
|
||||||
EXPECT_EQ(t.update(0x01122112), 0x101122112LL);
|
|
||||||
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
|
|
||||||
EXPECT_EQ(t.update(0x42342323), 0x042342323LL);
|
|
||||||
EXPECT_EQ(t.update(0x03453455), 0x003453455LL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(util, isInRange) {
|
TEST(util, isInRange) {
|
||||||
EXPECT_FALSE(isInRange(5, 4, 10));
|
EXPECT_FALSE(isInRange(5, 4, 10));
|
||||||
EXPECT_TRUE(isInRange(5, 5, 10));
|
EXPECT_TRUE(isInRange(5, 5, 10));
|
||||||
|
|
Loading…
Reference in New Issue