rusEFI
The most advanced open source ECU
Functions | Variables
microsecond_timer.cpp File Reference

Detailed Description

Here we have a 1MHz timer dedicated to event scheduling. We are using one of the 32-bit timers here, so this timer can schedule events up to 4B/100M ~ 4000 seconds ~ 1 hour from current time.

GPT5 timer clock: 84000000Hz If only it was a better multiplier of 2 (84000000 = 328125 * 256)

Date
Apr 14, 2014
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file microsecond_timer.cpp.

Functions

void setHardwareSchedulerTimer (efitick_t nowNt, efitick_t setTimeNt)
 
void globalTimerCallback ()
 
void portMicrosecondTimerCallback ()
 
static void watchDogBuddyCallback (void *)
 
static void timerValidationCallback (void *)
 
static void validateHardwareTimer ()
 
void initMicrosecondTimer ()
 

Variables

uint32_t maxPrecisionCallbackDuration = 0
 
static efitick_t lastSetTimerTimeNt
 
static bool isTimerPending = false
 
static int timerCallbackCounter = 0
 
static int timerRestartCounter = 0
 
static int timerFreezeCounter = 0
 
static int setHwTimerCounter = 0
 
static bool hwStarted = false
 
static MicrosecondTimerWatchdogController watchdogControllerInstance
 
static scheduling_s watchDogBuddy
 
static volatile bool testSchedulingHappened = false
 
static Timer testScheduling
 

Function Documentation

◆ globalTimerCallback()

void globalTimerCallback ( )

Definition at line 36 of file single_timer_executor.cpp.

36  {
37  efiAssertVoid(ObdCode::CUSTOM_ERR_6624, hasLotsOfRemainingStack(), "lowstck#2y");
38 
40 }
SingleTimerExecutor executor
Definition: engine.h:240
Engine ___engine
@ CUSTOM_ERR_6624

Referenced by portMicrosecondTimerCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initMicrosecondTimer()

void initMicrosecondTimer ( )

Definition at line 167 of file microsecond_timer.cpp.

167  {
169 
170  hwStarted = true;
171 
173 
175 
176  watchDogBuddyCallback(NULL);
177 #if EFI_EMULATE_POSITION_SENSORS
179 #endif /* EFI_EMULATE_POSITION_SENSORS */
180 }
efitick_t getTimeNowNt()
Definition: efitime.cpp:19
static bool hwStarted
static void watchDogBuddyCallback(void *)
static MicrosecondTimerWatchdogController watchdogControllerInstance
static void validateHardwareTimer()
static efitick_t lastSetTimerTimeNt
void portInitMicrosecondTimer()

Referenced by initSingleTimerExecutorHardware().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ portMicrosecondTimerCallback()

void portMicrosecondTimerCallback ( )

Definition at line 93 of file microsecond_timer.cpp.

93  {
95  isTimerPending = false;
96 
97  uint32_t before = getTimeNowLowerNt();
99  uint32_t precisionCallbackDuration = getTimeNowLowerNt() - before;
100  if (precisionCallbackDuration > maxPrecisionCallbackDuration) {
101  maxPrecisionCallbackDuration = precisionCallbackDuration;
102  }
103 }
void globalTimerCallback()
static bool isTimerPending
uint32_t maxPrecisionCallbackDuration
static int timerCallbackCounter
uint32_t getTimeNowLowerNt()

Referenced by hwTimerCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setHardwareSchedulerTimer()

void setHardwareSchedulerTimer ( efitick_t  nowNt,
efitick_t  setTimeNt 
)

sets the alarm to the specified number of microseconds from now. This function should be invoked under kernel lock which would disable interrupts.

#259 BUG error: not positive deltaTimeNt Once in a while we night get an interrupt where we do not expect it

Definition at line 50 of file microsecond_timer.cpp.

50  {
51  criticalAssertVoid(hwStarted, "HW.started");
52 
53  // How many ticks in the future is this event?
54  auto timeDeltaNt = setTimeNt - nowNt;
55 
57 
58  /**
59  * #259 BUG error: not positive deltaTimeNt
60  * Once in a while we night get an interrupt where we do not expect it
61  */
62  if (timeDeltaNt <= 0) {
65  }
66 
67  // We need the timer to fire after we return - 1 doesn't work as it may actually schedule in the past
68  if (timeDeltaNt < US2NT(2)) {
69  timeDeltaNt = US2NT(2);
70  }
71 
72  if (timeDeltaNt >= TOO_FAR_INTO_FUTURE_NT) {
73  // we are trying to set callback for too far into the future. This does not look right at all
74  firmwareError(ObdCode::CUSTOM_ERR_TIMER_OVERFLOW, "setHardwareSchedulerTimer() too far: %d", timeDeltaNt);
75  return;
76  }
77 
78  // Skip scheduling if there's a firmware error active
79  if (hasFirmwareError()) {
80  return;
81  }
82 
83  // Do the actual hardware-specific timer set operation
84  portSetHardwareSchedulerTimer(nowNt, setTimeNt);
85 
87  isTimerPending = true;
89 }
bool warning(ObdCode code, const char *fmt,...)
void firmwareError(ObdCode code, const char *fmt,...)
static int timerFreezeCounter
static int timerRestartCounter
static int setHwTimerCounter
void portSetHardwareSchedulerTimer(efitick_t nowNt, efitick_t setTimeNt)
@ CUSTOM_ERR_TIMER_OVERFLOW
@ CUSTOM_OBD_LOCAL_FREEZE

Referenced by SingleTimerExecutor::scheduleTimerCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ timerValidationCallback()

static void timerValidationCallback ( void *  )
static

Definition at line 139 of file microsecond_timer.cpp.

139  {
140  testSchedulingHappened = true;
141  efitimems_t actualTimeSinceSchedulingMs = 1e3 * testScheduling.getElapsedSeconds();
142 
143  if (absI(actualTimeSinceSchedulingMs - TEST_CALLBACK_DELAY_MS) > TEST_CALLBACK_DELAY_MS * TIMER_PRECISION_THRESHOLD) {
144  firmwareError(ObdCode::CUSTOM_ERR_TIMER_TEST_CALLBACK_WRONG_TIME, "hwTimer broken precision: %ld ms", actualTimeSinceSchedulingMs);
145  }
146 }
static Timer testScheduling
static volatile bool testSchedulingHappened
@ CUSTOM_ERR_TIMER_TEST_CALLBACK_WRONG_TIME
uint32_t efitimems_t
Definition: rusefi_types.h:43

Referenced by validateHardwareTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validateHardwareTimer()

static void validateHardwareTimer ( )
static

This method would validate that hardware timer callbacks happen with some reasonable precision helps to make sure our GPT hardware settings are somewhat right

Definition at line 152 of file microsecond_timer.cpp.

152  {
153  if (hasFirmwareError()) {
154  return;
155  }
156  testScheduling.reset();
157 
158  // to save RAM let's use 'watchDogBuddy' here once before we enable watchdog
159  engine->executor.scheduleForLater("hw-validate", &watchDogBuddy, MS2US(TEST_CALLBACK_DELAY_MS), timerValidationCallback);
160 
161  chThdSleepMilliseconds(TEST_CALLBACK_DELAY_MS + 2);
162  if (!testSchedulingHappened) {
164  }
165 }
void scheduleForLater(const char *msg, scheduling_s *scheduling, int delayUs, action_s action) override
Engine * engine
static scheduling_s watchDogBuddy
static void timerValidationCallback(void *)
@ CUSTOM_ERR_TIMER_TEST_CALLBACK_NOT_HAPPENED

Referenced by initMicrosecondTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ watchDogBuddyCallback()

static void watchDogBuddyCallback ( void *  )
static

the purpose of this periodic activity is to make watchdogControllerInstance watchdog happy by ensuring that we have scheduler activity even in case of very broken configuration without any PWM or input pins

Definition at line 127 of file microsecond_timer.cpp.

127  {
128  /**
129  * the purpose of this periodic activity is to make watchdogControllerInstance
130  * watchdog happy by ensuring that we have scheduler activity even in case of very broken configuration
131  * without any PWM or input pins
132  */
134 }

Referenced by initMicrosecondTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ hwStarted

bool hwStarted = false
static

Definition at line 44 of file microsecond_timer.cpp.

Referenced by initMicrosecondTimer(), and setHardwareSchedulerTimer().

◆ isTimerPending

bool isTimerPending = false
static

◆ lastSetTimerTimeNt

efitick_t lastSetTimerTimeNt
static

Definition at line 36 of file microsecond_timer.cpp.

Referenced by initMicrosecondTimer(), and setHardwareSchedulerTimer().

◆ maxPrecisionCallbackDuration

uint32_t maxPrecisionCallbackDuration = 0

Maximum duration of complete timer callback, all pending events together See also 'maxEventCallbackDuration' for maximum duration of one event

Definition at line 34 of file microsecond_timer.cpp.

Referenced by portMicrosecondTimerCallback(), and resetMaxValues().

◆ setHwTimerCounter

int setHwTimerCounter = 0
static

Definition at line 43 of file microsecond_timer.cpp.

Referenced by setHardwareSchedulerTimer().

◆ testScheduling

Timer testScheduling
static

Definition at line 137 of file microsecond_timer.cpp.

Referenced by timerValidationCallback(), and validateHardwareTimer().

◆ testSchedulingHappened

volatile bool testSchedulingHappened = false
static

Definition at line 136 of file microsecond_timer.cpp.

Referenced by timerValidationCallback(), and validateHardwareTimer().

◆ timerCallbackCounter

int timerCallbackCounter = 0
static

Definition at line 39 of file microsecond_timer.cpp.

Referenced by portMicrosecondTimerCallback().

◆ timerFreezeCounter

int timerFreezeCounter = 0
static

Definition at line 42 of file microsecond_timer.cpp.

Referenced by setHardwareSchedulerTimer().

◆ timerRestartCounter

int timerRestartCounter = 0
static

Definition at line 40 of file microsecond_timer.cpp.

Referenced by setHardwareSchedulerTimer().

◆ watchDogBuddy

scheduling_s watchDogBuddy
static

Definition at line 125 of file microsecond_timer.cpp.

Referenced by validateHardwareTimer(), and watchDogBuddyCallback().

◆ watchdogControllerInstance

MicrosecondTimerWatchdogController watchdogControllerInstance
static

Definition at line 123 of file microsecond_timer.cpp.

Referenced by initMicrosecondTimer().

Go to the source code of this file.