2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file error_handling.cpp
|
|
|
|
*
|
|
|
|
* @date Apr 1, 2014
|
2015-12-31 13:02:30 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2016
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
#include "error_handling.h"
|
|
|
|
#include "io_pins.h"
|
|
|
|
#include "memstreams.h"
|
|
|
|
#include "efilib2.h"
|
2016-07-13 16:03:06 -07:00
|
|
|
#include "engine.h"
|
2016-07-23 10:03:57 -07:00
|
|
|
//todo: move into simulator global
|
|
|
|
#include <chprintf.h>
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2016-07-23 10:03:57 -07:00
|
|
|
#if EFI_HD44780_LCD || defined(__DOXYGEN__)
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "lcd_HD44780.h"
|
|
|
|
#endif /* EFI_HD44780_LCD */
|
|
|
|
|
|
|
|
static LoggingWithStorage logger("error handling");
|
|
|
|
|
2016-07-13 16:03:06 -07:00
|
|
|
EXTERN_ENGINE;
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
#define WARNING_PREFIX "WARNING: "
|
|
|
|
|
|
|
|
extern int warningEnabled;
|
2016-01-11 14:01:33 -08:00
|
|
|
extern bool main_loop_started;
|
2016-10-10 12:02:10 -07:00
|
|
|
extern bool hasFirmwareErrorFlag;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
const char *dbg_panic_file;
|
|
|
|
int dbg_panic_line;
|
|
|
|
|
|
|
|
void chDbgPanic3(const char *msg, const char * file, int line) {
|
|
|
|
if (hasFatalError())
|
|
|
|
return;
|
|
|
|
dbg_panic_file = file;
|
|
|
|
dbg_panic_line = line;
|
2016-07-23 10:03:57 -07:00
|
|
|
#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__)
|
2015-07-10 06:01:56 -07:00
|
|
|
dbg_panic_msg = msg;
|
|
|
|
#endif /* CH_DBG_SYSTEM_STATE_CHECK */
|
|
|
|
|
2016-07-23 10:03:57 -07:00
|
|
|
#if EFI_PROD_CODE || defined(__DOXYGEN__)
|
2015-07-10 06:01:56 -07:00
|
|
|
ON_FATAL_ERROR();
|
2016-07-23 10:03:57 -07:00
|
|
|
#else
|
|
|
|
printf("chDbgPanic3 %s %s%d", msg, file, line);
|
|
|
|
exit(-1);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if EFI_HD44780_LCD || defined(__DOXYGEN__)
|
2015-07-10 06:01:56 -07:00
|
|
|
lcdShowFatalMessage((char *) msg);
|
|
|
|
#endif /* EFI_HD44780_LCD */
|
|
|
|
|
|
|
|
if (!main_loop_started) {
|
|
|
|
print("fatal %s %s:%d\r\n", msg, file, line);
|
|
|
|
chThdSleepSeconds(1);
|
|
|
|
chSysHalt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define WARNING_BUFFER_SIZE 80
|
|
|
|
static char warningBuffer[WARNING_BUFFER_SIZE];
|
2016-04-03 15:02:39 -07:00
|
|
|
static bool isWarningStreamInitialized = false;
|
2015-07-10 06:01:56 -07:00
|
|
|
static MemoryStream warningStream;
|
|
|
|
|
2016-10-09 16:03:51 -07:00
|
|
|
/**
|
|
|
|
* @param forIndicator if we want to retrieving value for TS indicator, this case a minimal period is applued
|
|
|
|
*/
|
|
|
|
bool isWarningNow(efitimesec_t now, bool forIndicator) {
|
|
|
|
int period = forIndicator ? maxI(3, engineConfiguration->warningPeriod) : engineConfiguration->warningPeriod;
|
|
|
|
return absI(now - engine->engineState.timeOfPreviousWarning) < period;
|
2016-07-14 20:02:55 -07:00
|
|
|
}
|
|
|
|
|
2016-11-23 14:01:59 -08:00
|
|
|
void addWarningCode(obd_code_e code) {
|
2016-10-10 12:02:10 -07:00
|
|
|
engine->engineState.warningCounter++;
|
|
|
|
engine->engineState.lastErrorCode = code;
|
|
|
|
}
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* OBD_PCM_Processor_Fault is the general error code for now
|
|
|
|
*
|
|
|
|
* @returns TRUE in case there are too many warnings
|
|
|
|
*/
|
2016-10-10 12:02:10 -07:00
|
|
|
bool warning(obd_code_e code, const char *fmt, ...) {
|
|
|
|
if (hasFirmwareErrorFlag)
|
|
|
|
return true;
|
2016-07-23 10:03:57 -07:00
|
|
|
efiAssert(isWarningStreamInitialized, "warn stream not initialized", false);
|
2016-09-26 17:02:24 -07:00
|
|
|
|
|
|
|
#if EFI_UNIT_TEST || EFI_SIMULATOR || defined(__DOXYGEN__)
|
|
|
|
printf("warning %s\r\n", fmt);
|
|
|
|
#endif
|
|
|
|
|
2016-11-23 14:01:59 -08:00
|
|
|
addWarningCode(code);
|
|
|
|
|
2016-07-14 20:02:55 -07:00
|
|
|
efitimesec_t now = getTimeNowSeconds();
|
2016-10-09 16:03:51 -07:00
|
|
|
if (isWarningNow(now, false) || !warningEnabled)
|
2015-07-10 06:01:56 -07:00
|
|
|
return true; // we just had another warning, let's not spam
|
2016-11-23 14:01:59 -08:00
|
|
|
engine->engineState.timeOfPreviousWarning = now;
|
2016-01-30 19:03:36 -08:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
resetLogging(&logger); // todo: is 'reset' really needed here?
|
|
|
|
appendMsgPrefix(&logger);
|
|
|
|
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
append(&logger, WARNING_PREFIX);
|
|
|
|
warningStream.eos = 0; // reset
|
|
|
|
chvprintf((BaseSequentialStream *) &warningStream, fmt, ap);
|
|
|
|
warningStream.buffer[warningStream.eos] = 0;
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
append(&logger, warningBuffer);
|
|
|
|
append(&logger, DELIMETER);
|
|
|
|
scheduleLogging(&logger);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2016-10-10 12:02:10 -07:00
|
|
|
char *getWarning(void) {
|
2015-07-10 06:01:56 -07:00
|
|
|
return warningBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t lastLockTime;
|
|
|
|
uint32_t maxLockTime = 0;
|
|
|
|
|
2016-07-23 10:03:57 -07:00
|
|
|
// todo: move this field to trigger_central?
|
2015-07-10 06:01:56 -07:00
|
|
|
bool isInsideTriggerHandler = false;
|
|
|
|
|
|
|
|
void onLockHook(void) {
|
|
|
|
lastLockTime = GET_TIMESTAMP();
|
|
|
|
}
|
|
|
|
|
|
|
|
void onUnlockHook(void) {
|
|
|
|
uint32_t t = GET_TIMESTAMP() - lastLockTime;
|
|
|
|
if (t > maxLockTime) {
|
|
|
|
maxLockTime = t;
|
|
|
|
}
|
|
|
|
// if (t > 2800) {
|
|
|
|
// // un-comment this if you want a nice stop for a breakpoint
|
|
|
|
// maxLockTime = t + 1;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
void initErrorHandling(void) {
|
|
|
|
msObjectInit(&warningStream, (uint8_t *) warningBuffer, WARNING_BUFFER_SIZE, 0);
|
2016-04-03 15:02:39 -07:00
|
|
|
isWarningStreamInitialized = true;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2016-07-23 10:03:57 -07:00
|
|
|
//todo: move into simulator global
|
|
|
|
typedef VTList virtual_timers_list_t;
|
|
|
|
|
2016-02-04 12:01:45 -08:00
|
|
|
extern virtual_timers_list_t vtlist;
|
2016-01-11 14:01:33 -08:00
|
|
|
extern bool main_loop_started;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
int getVtSizeEstimate(void) {
|
2016-02-04 18:03:01 -08:00
|
|
|
virtual_timer_t *first = vtlist.vt_next;
|
|
|
|
virtual_timer_t *cur = first->vt_next;
|
2015-07-10 06:01:56 -07:00
|
|
|
int c = 0;
|
|
|
|
while (c++ < 20 && cur != first) {
|
|
|
|
cur = cur->vt_next;
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
int globalVt;
|
|
|
|
|
|
|
|
int allReady = 0;
|
|
|
|
void assertVtList(void) {
|
|
|
|
if (!main_loop_started)
|
|
|
|
return;
|
|
|
|
globalVt = getVtSizeEstimate();
|
|
|
|
//efiAssertVoid(globalVt > 3, "VT list?");
|
|
|
|
if(globalVt <=3 ) {
|
|
|
|
allReady++;
|
|
|
|
}
|
|
|
|
}
|