/** * @brief Register an event for digital sniffer */ void addWaveChartEvent3(WaveChart *chart, const char *name, const char * msg, const char * msg2) { efiAssertVoid(chart->isInitialized, "chart not initialized"); #if DEBUG_WAVE scheduleSimpleMsg(&debugLogging, "current", chart->counter); #endif if (isWaveChartFull(chart)) { return; } #if EFI_HISTOGRAMS && EFI_PROD_CODE int beforeCallback = hal_lld_get_counter_value(); #endif int time100 = getTimeNowUs() / 10; bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer if (chart->counter == 0) { chart->startTime = time100; } chart->counter++; if (remainingSize(&chart->logging) > 30) { /** * printf is a heavy method, append is used here as a performance optimization */ appendFast(&chart->logging, name); appendFast(&chart->logging, CHART_DELIMETER); appendFast(&chart->logging, msg); appendFast(&chart->logging, CHART_DELIMETER); /** * We want smaller times within a chart in order to reduce packet size. */ time100 -= chart->startTime; itoa10(timeBuffer, time100); appendFast(&chart->logging, timeBuffer); appendFast(&chart->logging, msg2); appendFast(&chart->logging, CHART_DELIMETER); } if (!alreadyLocked) { unlockOutputBuffer(); } #if EFI_HISTOGRAMS && EFI_PROD_CODE int64_t diff = hal_lld_get_counter_value() - beforeCallback; if (diff > 0) { hsAdd(&waveChartHisto, diff); } #endif /* EFI_HISTOGRAMS */ }
TEST(util, histogram) { print("******************************************* testHistogram\r\n"); initHistogramsModule(); ASSERT_EQ(80, histogramGetIndex(239)); ASSERT_EQ(223, histogramGetIndex(239239)); ASSERT_EQ(364, histogramGetIndex(239239239)); histogram_s h; initHistogram(&h, "test"); int result[5]; ASSERT_EQ(0, hsReport(&h, result)); hsAdd(&h, 10); ASSERT_EQ(1, hsReport(&h, result)); ASSERT_EQ(10, result[0]); // let's add same value one more time hsAdd(&h, 10); ASSERT_EQ(2, hsReport(&h, result)); ASSERT_EQ(10, result[0]); ASSERT_EQ(10, result[1]); hsAdd(&h, 10); hsAdd(&h, 10); hsAdd(&h, 10); hsAdd(&h, 1000); hsAdd(&h, 100); ASSERT_EQ(5, hsReport(&h, result)); ASSERT_EQ(5, result[0]); ASSERT_EQ(10, result[1]); ASSERT_EQ(10, result[2]); ASSERT_EQ(100, result[3]); // values are not expected to be exactly the same, it's the shape what matters ASSERT_EQ(1011, result[4]); }
/** * @brief Register an event for digital sniffer */ void WaveChart::addEvent3(const char *name, const char * msg) { #if EFI_TEXT_LOGGING if (!ENGINE(isEngineChartEnabled)) { return; } if (skipUntilEngineCycle != 0 && ENGINE(rpmCalculator.getRevolutionCounter()) < skipUntilEngineCycle) return; #if EFI_SIMULATOR // todo: add UI control to enable this for firmware if desired // CONFIG(alignEngineSnifferAtTDC) && if (!collectingData) { return; } #endif efiAssertVoid(CUSTOM_ERR_6651, name!=NULL, "WC: NULL name"); #if EFI_PROD_CODE efiAssertVoid(CUSTOM_ERR_6652, getCurrentRemainingStack() > 32, "lowstck#2c"); #endif /* EFI_PROD_CODE */ efiAssertVoid(CUSTOM_ERR_6653, isInitialized, "chart not initialized"); #if DEBUG_WAVE scheduleSimpleMsg(&debugLogging, "current", chart->counter); #endif /* DEBUG_WAVE */ if (isFull()) { return; } #if EFI_HISTOGRAMS && EFI_PROD_CODE int beforeCallback = hal_lld_get_counter_value(); #endif efitick_t nowNt = getTimeNowNt(); bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer if (counter == 0) { startTimeNt = nowNt; } counter++; /** * We want smaller times within a chart in order to reduce packet size. */ /** * todo: migrate to binary fractions in order to eliminate * this division? I do not like division * * at least that's 32 bit division now */ uint32_t diffNt = nowNt - startTimeNt; uint32_t time100 = NT2US(diffNt / 10); if (remainingSize(&logging) > 35) { /** * printf is a heavy method, append is used here as a performance optimization */ appendFast(&logging, name); appendChar(&logging, CHART_DELIMETER); appendFast(&logging, msg); appendChar(&logging, CHART_DELIMETER); // time100 -= startTime100; itoa10(timeBuffer, time100); appendFast(&logging, timeBuffer); appendChar(&logging, CHART_DELIMETER); logging.linePointer[0] = 0; } if (!alreadyLocked) { unlockOutputBuffer(); } #if EFI_HISTOGRAMS && EFI_PROD_CODE int64_t diff = hal_lld_get_counter_value() - beforeCallback; if (diff > 0) { hsAdd(&engineSnifferHisto, diff); } #endif /* EFI_HISTOGRAMS */ #endif /* EFI_TEXT_LOGGING */ }
void TriggerCentral::handleShaftSignal(trigger_event_e signal DECLARE_ENGINE_PARAMETER_S) { efiAssertVoid(engine!=NULL, "configuration"); nowNt = getTimeNowNt(); efiAssertVoid(engine->engineConfiguration!=NULL, "engineConfiguration"); efiAssertVoid(engine->engineConfiguration2!=NULL, "engineConfiguration2"); engine->onTriggerEvent(nowNt); #if EFI_HISTOGRAMS && EFI_PROD_CODE int beforeCallback = hal_lld_get_counter_value(); #endif int eventIndex = (int) signal; efiAssertVoid(eventIndex >= 0 && eventIndex < HW_EVENT_TYPES, "signal type"); hwEventCounters[eventIndex]++; if (nowNt - previousShaftEventTimeNt > US2NT(US_PER_SECOND_LL)) { /** * We are here if there is a time gap between now and previous shaft event - that means the engine is not runnig. * That means we have lost synchronization since the engine is not running :) */ triggerState.shaft_is_synchronized = false; } previousShaftEventTimeNt = nowNt; /** * This invocation changes the state of triggerState */ triggerState.decodeTriggerEvent(signal, nowNt PASS_ENGINE_PARAMETER); if (!triggerState.shaft_is_synchronized) { // we should not propagate event if we do not know where we are return; } /** * If we only have a crank position sensor, here we are extending crank revolutions with a 360 degree * cycle into a four stroke, 720 degrees cycle. TODO */ int triggerIndexForListeners; if (getOperationMode(engine->engineConfiguration) == FOUR_STROKE_CAM_SENSOR) { // That's easy - trigger cycle matches engine cycle triggerIndexForListeners = triggerState.getCurrentIndex(); } else { bool isEven = triggerState.getTotalRevolutionCounter() & 1; triggerIndexForListeners = triggerState.getCurrentIndex() + (isEven ? 0 : TRIGGER_SHAPE(size)); } reportEventToWaveChart(signal, triggerIndexForListeners); if (triggerState.current_index >= TRIGGER_SHAPE(size)) { warning(OBD_PCM_Processor_Fault, "unexpected eventIndex=%d", triggerState.current_index); } else { /** * Here we invoke all the listeners - the main engine control logic is inside these listeners */ for (int i = 0; i < triggerListeneres.currentListenersCount; i++) { ShaftPositionListener listener = (ShaftPositionListener) triggerListeneres.callbacks[i]; (listener)(signal, triggerIndexForListeners PASS_ENGINE_PARAMETER); } } #if EFI_HISTOGRAMS && EFI_PROD_CODE int afterCallback = hal_lld_get_counter_value(); int diff = afterCallback - beforeCallback; // this counter is only 32 bits so it overflows every minute, let's ignore the value in case of the overflow for simplicity if (diff > 0) { hsAdd(&triggerCallback, diff); } #endif /* EFI_HISTOGRAMS */ }