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

Detailed Description

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

Definition in file error_handling.cpp.

Functions

const char * getCriticalErrorMessage (void)
 
void checkLastBootError ()
 
void logHardFault (uint32_t type, uintptr_t faultAddress, port_extctx *ctx, uint32_t csfr)
 
void chDbgPanic3 (const char *msg, const char *file, int line)
 
bool warning (ObdCode code, const char *fmt,...)
 
const char * getWarningMessage (void)
 
void onLockHook (void)
 
void onUnlockHook (void)
 
void firmwareError (ObdCode code, const char *fmt,...)
 

Variables

static critical_msg_t warningBuffer
 
static critical_msg_t criticalErrorMessageBuffer
 
int warningEnabled
 
bool hasFirmwareErrorFlag = false
 
const char * dbg_panic_file
 
int dbg_panic_line
 
WarningCodeState unitTestWarningCodeState
 
uint32_t lastLockTime
 
uint32_t maxLockedDuration = 0
 

Function Documentation

◆ chDbgPanic3()

void chDbgPanic3 ( const char *  msg,
const char *  file,
int  line 
)

Definition at line 105 of file error_handling.cpp.

105  {
106 #if EFI_PROD_CODE
107  // Attempt to break in to the debugger, if attached
108  __asm volatile("BKPT #0\n");
109 #endif
110 
111 #if EFI_BACKUP_SRAM
112  auto sramState = getBackupSram();
113  strncpy(sramState->Err.hardFile, file, efi::size(sramState->Err.hardFile) - 1);
114  sramState->Err.hardLine = line;
115  sramState->Err.check = 123;
116  strncpy(sramState->Err.rawMsg, msg, efi::size(sramState->Err.rawMsg) - 1);
117 #endif // EFI_BACKUP_SRAM
118 
119  if (hasOsPanicError())
120  return;
121  dbg_panic_file = file;
122  dbg_panic_line = line;
123 #if CH_DBG_SYSTEM_STATE_CHECK
124  ch.dbg.panic_msg = msg;
125 #endif /* CH_DBG_SYSTEM_STATE_CHECK */
126 
127 #if !EFI_PROD_CODE
128  printf("chDbgPanic3 %s %s%d", msg, file, line);
129  exit(-1);
130 #else // EFI_PROD_CODE
131 
132  criticalError("assert fail %s %s:%d", msg, file, line);
133 
134  // If on the main thread, longjmp back to the init process so we can keep USB alive
135  if (chThdGetSelfX()->threadId == 0) {
136  // Force unlock, since we may be throwing-under-lock
137  chSysUnconditionalUnlock();
138 
139  // there was a port_disable in chSysHalt, reenable interrupts so USB works
140  port_enable();
141 
142  __NO_RETURN void onAssertionFailure();
144  } else {
145  // Not the main thread.
146  // All hope is now lost.
147 
148  // Reboot!
149  NVIC_SystemReset();
150  }
151 
152 #endif // EFI_PROD_CODE
153 }
BackupSramData * getBackupSram()
Definition: backup_ram.cpp:52
int dbg_panic_line
const char * dbg_panic_file
static const char * msg
void onAssertionFailure()
Definition: rusefi.cpp:165
composite packet size
printf("\n")
Here is the call graph for this function:

◆ checkLastBootError()

void checkLastBootError ( )

Definition at line 30 of file error_handling.cpp.

30  {
31 #if EFI_BACKUP_SRAM
32  auto sramState = getBackupSram();
33 
34  switch (sramState->Err.Cookie) {
36  efiPrintf("Last boot had firmware error: %s", sramState->Err.ErrorString);
37  break;
39  efiPrintf("Last boot had raw: %s", sramState->Err.rawMsg);
40  efiPrintf("Last boot had hardFile: %s", sramState->Err.hardFile);
41  efiPrintf("Last boot had line: %d", sramState->Err.hardLine);
42  efiPrintf("Last boot had check: %d", sramState->Err.check);
43  efiPrintf("Last boot had error: %s", sramState->Err.ErrorString);
44  efiPrintf("Last boot had hard fault type: %x addr: %x CSFR: %x", sramState->Err.FaultType, sramState->Err.FaultAddress, sramState->Err.Csfr);
46  criticalError("Last boot had hard fault type: %x addr: %x CSFR: %x", sramState->Err.FaultType, sramState->Err.FaultAddress, sramState->Err.Csfr);
47  }
48 
49  auto ctx = &sramState->Err.FaultCtx;
50  efiPrintf("r0 0x%x", ctx->r0);
51  efiPrintf("r1 0x%x", ctx->r1);
52  efiPrintf("r2 0x%x", ctx->r2);
53  efiPrintf("r3 0x%x", ctx->r3);
54  efiPrintf("r12 0x%x", ctx->r12);
55  efiPrintf("lr (thread) 0x%x", ctx->lr_thd);
56  efiPrintf("pc 0x%x", ctx->pc);
57  efiPrintf("xpsr 0x%x", ctx->xpsr);
58 
59  /* FPU registers - not very usefull for debug */
60  if (0) {
61  // Print rest the context as a sequence of uintptr
62  uintptr_t* data = reinterpret_cast<uintptr_t*>(&sramState->Err.FaultCtx);
63  for (size_t i = 8; i < sizeof(port_extctx) / sizeof(uintptr_t); i++) {
64  efiPrintf("Fault ctx %d: %x", i, data[i]);
65  }
66  }
67 
68  break;
69  }
70  default:
71  // No cookie stored or invalid cookie (ie, backup RAM contains random garbage)
72  break;
73  }
74 
75  // Reset cookie so we don't print it again.
76  sramState->Err.Cookie = ErrorCookie::None;
77 
78  if (sramState->Err.BootCountCookie != 0xdeadbeef) {
79  sramState->Err.BootCountCookie = 0xdeadbeef;
80  sramState->Err.BootCount = 0;
81  }
82 
83  efiPrintf("Power cycle count: %d", sramState->Err.BootCount);
84  sramState->Err.BootCount++;
85 #endif // EFI_BACKUP_SRAM
86 }
engine_configuration_s * engineConfiguration

Referenced by runRusEfi().

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

◆ firmwareError()

void firmwareError ( ObdCode  code,
const char *  fmt,
  ... 
)

Something really bad had happened - firmware cannot function, we cannot run the engine We definitely use this critical error approach in case of invalid configuration. If user sets a self-contradicting configuration we have to just put a hard stop on this.

see also warning()

in case of simple error message let's reduce stack usage chvsnprintf could cause an overflow if we're already low

Definition at line 265 of file error_handling.cpp.

265  {
266 #if EFI_PROD_CODE
268  return;
269  hasFirmwareErrorFlag = true;
270 #if EFI_ENGINE_CONTROL
272 #endif // EFI_ENGINE_CONTROL
274 #ifdef EFI_PRINT_ERRORS_AS_WARNINGS
275  {
276  va_list ap;
277  va_start(ap, fmt);
278  chvsnprintf(warningBuffer, sizeof(warningBuffer), fmt, ap);
279  va_end(ap);
280  }
281 #endif // EFI_PRINT_ERRORS_AS_WARNINGS
282  criticalShutdown();
283  enginePins.communicationLedPin.setValue(1, /*force*/true);
284 
285  if (indexOf(fmt, '%') == -1) {
286  /**
287  * in case of simple error message let's reduce stack usage
288  * chvsnprintf could cause an overflow if we're already low
289  */
290  strncpy((char*) criticalErrorMessageBuffer, fmt, sizeof(criticalErrorMessageBuffer) - 1);
291  criticalErrorMessageBuffer[sizeof(criticalErrorMessageBuffer) - 1] = 0; // just to be sure
292  } else {
293  va_list ap;
294  va_start(ap, fmt);
295  chvsnprintf(criticalErrorMessageBuffer, sizeof(criticalErrorMessageBuffer), fmt, ap);
296  va_end(ap);
297  }
298 
299  int errorMessageSize = strlen((char*)criticalErrorMessageBuffer);
300  static char versionBuffer[32];
301  chsnprintf(versionBuffer, sizeof(versionBuffer), " %d@%s", getRusEfiVersion(), FIRMWARE_ID);
302 
303  if (errorMessageSize + strlen(versionBuffer) < sizeof(criticalErrorMessageBuffer)) {
304  strcpy((char*)(criticalErrorMessageBuffer) + errorMessageSize, versionBuffer);
305  }
306 
307 #if EFI_BACKUP_SRAM
308  auto sramState = getBackupSram();
309  strncpy(sramState->Err.ErrorString, criticalErrorMessageBuffer, efi::size(sramState->Err.ErrorString));
310  sramState->Err.Cookie = ErrorCookie::FirmwareError;
311 #endif // EFI_BACKUP_SRAM
312 #else
313 
314  // large buffer on stack is risky we better use normal memory
315  static char errorBuffer[200];
316 
317  va_list ap;
318  va_start(ap, fmt);
319  vsnprintf(errorBuffer, sizeof(errorBuffer), fmt, ap);
320  va_end(ap);
321 
322  printf("\x1B[31m>>>>>>>>>> firmwareError [%s]\r\n\x1B[0m\r\n", errorBuffer);
323 
324 #if EFI_SIMULATOR || EFI_UNIT_TEST
325  throw std::logic_error(errorBuffer);
326 #endif /* EFI_SIMULATOR */
327 #endif
328 }
uint8_t code
Definition: bluetooth.cpp:39
EngineState engineState
Definition: engine.h:305
OutputPin communicationLedPin
Definition: efi_gpio.h:101
WarningCodeState warnings
Definition: engine_state.h:41
void fatalError()
void setValue(const char *msg, int logicValue, bool isForce=false)
Definition: efi_gpio.cpp:583
void addWarningCode(ObdCode code)
Definition: engine2.cpp:40
EnginePins enginePins
Definition: efi_gpio.cpp:24
LimpManager * getLimpManager()
Definition: engine.cpp:595
Engine * engine
bool hasFirmwareErrorFlag
static critical_msg_t warningBuffer
static critical_msg_t criticalErrorMessageBuffer
int getRusEfiVersion(void)

Referenced by TriggerWaveform::addEvent(), assertTimeIsLinear(), TriggerWaveform::calculateExpectedEventCounts(), calculateTriggerSynchPoint(), checkLastResetCause(), MultiChannelStateSequence::checkSwitchTimes(), AemXSeriesWideband::decodeRusefiStandard(), TriggerDecoderBase::decodeTriggerEvent(), doInitElectronicThrottle(), efiExtiEnablePin(), ensureArrayIsAscending(), SingleTimerExecutor::executeAllPendingActions(), fatalErrorForPresetApply(), findIndexMsg(), TriggerStimulatorHelper::findTriggerSyncPoint(), getAdcChannelBrainPin(), getAirmassModel(), getFiringOrderCylinderId(), getFiringOrderLength(), getFiringOrderTable(), getHwPin(), getIgnitionPinForIndex(), getInjectionModeDurationMultiplier(), getMapCfg(), getNumberOfInjections(), getNumberOfSparks(), getPortIndex(), getSpiDevice(), gpio_pin_markUsed(), PwmConfig::handleCycleStart(), TriggerCentral::handleShaftSignal(), EtbController::init(), initAuxValves(), initEgoSensor(), initHistogram(), initializeSkippedToothTrigger(), OutputPin::initPin(), look_up_rpm_can_id(), look_up_vss_can_id(), myerror(), onCliCaseError(), onCliDuplicateError(), onCliOverflowError(), FLStack< T, MAXSIZE >::pop(), portSetHardwareSchedulerTimer(), FLStack< T, MAXSIZE >::push(), recalculateAuxValveTiming(), EventQueue::remove(), resetConfigurationExt(), runBench(), SingleTimerExecutor::scheduleByTimestampNt(), setHardwareSchedulerTimer(), GppwmChannel::setOutput(), startCanPins(), swapOutputBuffers(), tachUpdate(), timerCallback(), timerValidationCallback(), turnOnTriggerInputPin(), InjectionEvent::update(), validateHardwareTimer(), validateThermistorConfig(), and wrapAngle().

Here is the call graph for this function:

◆ getCriticalErrorMessage()

const char* getCriticalErrorMessage ( void  )

Definition at line 25 of file error_handling.cpp.

25  {
27 }

Referenced by TunerStudio::handleCrcCommand(), handleTestCommand(), and updateDevConsoleState().

Here is the caller graph for this function:

◆ getWarningMessage()

const char* getWarningMessage ( void  )

Definition at line 211 of file error_handling.cpp.

211  {
212  return warningBuffer;
213 }

◆ logHardFault()

void logHardFault ( uint32_t  type,
uintptr_t  faultAddress,
port_extctx *  ctx,
uint32_t  csfr 
)

Definition at line 88 of file error_handling.cpp.

88  {
89  criticalShutdown();
90 #if EFI_BACKUP_SRAM
91  auto sramState = getBackupSram();
92  sramState->Err.Cookie = ErrorCookie::HardFault;
93  sramState->Err.check = 321;
94  sramState->Err.FaultType = type;
95  sramState->Err.FaultAddress = faultAddress;
96  sramState->Err.Csfr = csfr;
97  memcpy(&sramState->Err.FaultCtx, ctx, sizeof(port_extctx));
98 #endif // EFI_BACKUP_SRAM
99 }

Referenced by HardFault_Handler_C(), MemManage_Handler_C(), and UsageFault_Handler_C().

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

◆ onLockHook()

void onLockHook ( void  )

this depends on chdebug.h patch #if CH_DBG_SYSTEM_STATE_CHECK == TRUE -#define _dbg_enter_lock() (ch.dbg.lock_cnt = (cnt_t)1) -#define _dbg_leave_lock() (ch.dbg.lock_cnt = (cnt_t)0) +#define _dbg_enter_lock() {(ch.dbg.lock_cnt = (cnt_t)1); ON_LOCK_HOOK;} +#define _dbg_leave_lock() {ON_UNLOCK_HOOK;(ch.dbg.lock_cnt = (cnt_t)0);} #endif

Definition at line 234 of file error_handling.cpp.

234  {
235 #if ENABLE_PERF_TRACE
237 #endif /* ENABLE_PERF_TRACE */
238 
239 #if EFI_CLOCK_LOCKS
241 #endif /* EFI_CLOCK_LOCKS */
242 }
uint32_t lastLockTime
uint32_t getTimeNowLowerNt()
void perfEventInstantGlobal(PE event)
Definition: perf_trace.cpp:115
@ GlobalLock
Here is the call graph for this function:

◆ onUnlockHook()

void onUnlockHook ( void  )

Definition at line 244 of file error_handling.cpp.

244  {
245 #if EFI_CLOCK_LOCKS
246  uint32_t lockedDuration = getTimeNowLowerNt() - lastLockTime;
247  if (lockedDuration > maxLockedDuration) {
248  maxLockedDuration = lockedDuration;
249  }
250 // if (lockedDuration > 2800) {
251 // // un-comment this if you want a nice stop for a breakpoint
252 // maxLockedDuration = lockedDuration + 1;
253 // }
254 #endif /* EFI_CLOCK_LOCKS */
255 
256 #if ENABLE_PERF_TRACE
258 #endif /* ENABLE_PERF_TRACE */
259 }
uint32_t maxLockedDuration
@ GlobalUnlock
Here is the call graph for this function:

◆ warning()

bool warning ( ObdCode  code,
const char *  fmt,
  ... 
)

ObdCode::OBD_PCM_Processor_Fault is the general error code for now

Returns
TRUE in case there were warnings recently

Definition at line 165 of file error_handling.cpp.

165  {
167  return true;
168 
169 #if EFI_SIMULATOR || EFI_PROD_CODE
171 
172  // if known - just reset timer
174 
175  // we just had this same warning, let's not spam
176  if (known) {
177  return true;
178  }
179 
180  // print Pxxxx (for standard OBD) or Cxxxx (for custom) prefix
181  size_t size = snprintf(warningBuffer, sizeof(warningBuffer), "%s%04d: ",
182  code < ObdCode::CUSTOM_NAN_ENGINE_LOAD ? "P" : "C", (int) code);
183 
184  va_list ap;
185  va_start(ap, fmt);
186  chvsnprintf(warningBuffer + size, sizeof(warningBuffer) - size, fmt, ap);
187  va_end(ap);
188 
190 #if EFI_TUNER_STUDIO
191  // TODO: does this work? Fix or remove
193 #endif /* EFI_TUNER_STUDIO */
194  }
195 
196  efiPrintf("WARNING: %s", warningBuffer);
197 #else
198  // todo: we need access to 'engine' here so that we can migrate to real 'engine->engineState.warnings'
200  printf("unit_test_warning: ");
201  va_list ap;
202  va_start(ap, fmt);
203  vprintf(fmt, ap);
204  va_end(ap);
205  printf("\r\n");
206 
207 #endif /* EFI_SIMULATOR || EFI_PROD_CODE */
208  return false;
209 }
bool isWarningNow() const
Definition: engine2.cpp:65
persistent_config_container_s persistentState
WarningCodeState unitTestWarningCodeState
@ CUSTOM_NAN_ENGINE_LOAD

Referenced by TriggerWaveform::addEvent(), assertPinAssigned(), TriggerStimulatorHelper::assertSyncPosition(), buildTimingMap(), check(), createLogFile(), CanTsListener::decodeFrame(), AemXSeriesWideband::decodeRusefiDiag(), Engine::efiWatchdog(), findIndexMsg(), fireSparkBySettingPinLow(), flexCallback(), getAdvance(), SpeedDensityAirmass::getAirmass(), getBaroCorrection(), getCrankingFuel3(), getFiringOrderCylinderId(), getInjectionOffset(), getInternalAdcValue(), getRunningAdvance(), IgnitionState::getSparkDwell(), IFuelComputer::getTCharge(), Pid::getUnclampedOutput(), TriggerCentral::handleShaftSignal(), handleVvtCamSignal(), hip_init(), hipThread(), TriggerWaveform::initializeTriggerWaveform(), interpolateMsg(), TriggerCentral::isToothExpectedNow(), mainTriggerCallback(), mapAveragingAdcCallback(), mapAveragingTriggerCallback(), PrimaryTriggerDecoder::onNotEnoughTeeth(), VvtTriggerDecoder::onNotEnoughTeeth(), SensorChecker::onSlowCallback(), PrimaryTriggerDecoder::onTooManyTeeth(), VvtTriggerDecoder::onTooManyTeeth(), onTriggerEventSparkLogic(), InjectionEvent::onTriggerTooth(), EngineState::periodicFastCallback(), prepareIgnitionSchedule(), readFromFlash(), scheduleSparkEvent(), HIP9011::setAngleWindowWidth(), setGlobalTriggerAngleOffset(), setHardwareSchedulerTimer(), OutputPin::setOnchipValue(), SimplePwm::setSimplePwmDutyCycle(), startDwellByTurningSparkPinHigh(), startSimplePwm(), MapAverager::stop(), InjectionEvent::update(), LimpManager::updateState(), validateBaroMap(), TriggerCentral::validateCamVvtCounters(), and CanTxMessage::~CanTxMessage().

Here is the call graph for this function:

Variable Documentation

◆ criticalErrorMessageBuffer

critical_msg_t criticalErrorMessageBuffer
static

Definition at line 16 of file error_handling.cpp.

Referenced by firmwareError(), and getCriticalErrorMessage().

◆ dbg_panic_file

const char* dbg_panic_file

Definition at line 22 of file error_handling.cpp.

Referenced by chDbgPanic3().

◆ dbg_panic_line

int dbg_panic_line

Definition at line 23 of file error_handling.cpp.

Referenced by chDbgPanic3().

◆ hasFirmwareErrorFlag

bool hasFirmwareErrorFlag = false

Definition at line 20 of file error_handling.cpp.

Referenced by firmwareError(), and warning().

◆ lastLockTime

uint32_t lastLockTime

Definition at line 217 of file error_handling.cpp.

Referenced by onLockHook(), and onUnlockHook().

◆ maxLockedDuration

uint32_t maxLockedDuration = 0

Maximum time before requesting lock and releasing lock at the end of critical section

Definition at line 221 of file error_handling.cpp.

Referenced by onUnlockHook(), printRuntimeStats(), resetMaxValues(), and updateTunerStudioState().

◆ unitTestWarningCodeState

WarningCodeState unitTestWarningCodeState

Definition at line 156 of file error_handling.cpp.

Referenced by warning().

◆ warningBuffer

critical_msg_t warningBuffer
static

Definition at line 15 of file error_handling.cpp.

Referenced by firmwareError(), getWarningMessage(), and warning().

◆ warningEnabled

int warningEnabled
extern

Go to the source code of this file.