fome-fw/firmware/controllers/algo/wave_chart.cpp

238 lines
5.9 KiB
C++
Raw Normal View History

2014-08-29 07:52:33 -07:00
/**
2014-09-11 07:04:31 -07:00
* @file wave_chart.cpp
2014-08-29 07:52:33 -07:00
* @brief Dev console wave sniffer logic
*
* Here we have our own build-in logic analyzer. The data we aggregate here is sent to the
* java UI Dev Console so that it can be displayed nicely in the Sniffer tab.
*
* Both external events (see wave_analyzer.c) and internal (see signal executors) are supported
*
* @date Jun 23, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
2014-08-30 17:05:51 -07:00
#include "wave_chart.h"
2014-08-29 07:52:33 -07:00
#if EFI_WAVE_CHART
2014-08-30 17:05:51 -07:00
#include "engine_configuration.h"
2014-08-29 07:52:33 -07:00
#include "eficonsole.h"
#include "status_loop.h"
#define CHART_DELIMETER "!"
#if EFI_HISTOGRAMS
#include "rfiutil.h"
#include "histogram.h"
static histogram_s waveChartHisto;
#endif
2014-08-30 17:05:51 -07:00
extern engine_configuration_s *engineConfiguration;
2014-08-29 07:52:33 -07:00
/**
* This is the number of events in the digital chart which would be displayed
* on the 'digital sniffer' pane
*/
#if EFI_PROD_CODE
#define WAVE_LOGGING_SIZE 5000
#else
#define WAVE_LOGGING_SIZE 35000
#endif
int waveChartUsedSize;
2014-10-02 20:03:25 -07:00
static int isChartActive = true;
//static int isChartActive = false;
2014-08-29 07:52:33 -07:00
//#define DEBUG_WAVE 1
#if DEBUG_WAVE
static Logging debugLogging;
2014-09-11 08:03:38 -07:00
#endif /* DEBUG_WAVE */
2014-08-29 07:52:33 -07:00
static Logging logger;
2014-09-11 08:03:38 -07:00
void WaveChart::resetWaveChart() {
2014-08-29 07:52:33 -07:00
#if DEBUG_WAVE
2014-09-11 08:03:38 -07:00
scheduleSimpleMsg(&debugLogging, "reset while at ", counter);
#endif /* DEBUG_WAVE */
resetLogging(&logging);
counter = 0;
2014-09-15 19:03:09 -07:00
startTimeUs = 0;
2014-09-11 08:03:38 -07:00
appendPrintf(&logging, "wave_chart%s", DELIMETER);
2014-08-29 07:52:33 -07:00
}
static char WAVE_LOGGING_BUFFER[WAVE_LOGGING_SIZE] CCM_OPTIONAL
;
2014-09-11 08:03:38 -07:00
int WaveChart::isWaveChartFull() {
2014-09-15 19:03:09 -07:00
/**
* Say at 300rpm we should get at least four events per revolution.
* That's 300/60*4=20 events per second
* digitalChartSize/20 is the longest meaningful chart.
*
*/
uint64_t chartDurationInSeconds = (getTimeNowUs() - startTimeUs) / 1000000;
bool startedTooLongAgo = startTimeUs!= 0 && chartDurationInSeconds > engineConfiguration->digitalChartSize / 20;
return startedTooLongAgo || counter >= engineConfiguration->digitalChartSize;
2014-08-29 07:52:33 -07:00
}
static void printStatus(void) {
scheduleIntValue(&logger, "chart", isChartActive);
2014-08-30 17:05:51 -07:00
scheduleIntValue(&logger, "chartsize", engineConfiguration->digitalChartSize);
2014-08-29 07:52:33 -07:00
}
static void setChartActive(int value) {
isChartActive = value;
printStatus();
}
void setChartSize(int newSize) {
2014-08-30 17:05:51 -07:00
if (newSize < 5) {
2014-08-29 07:52:33 -07:00
return;
2014-08-30 17:05:51 -07:00
}
engineConfiguration->digitalChartSize = newSize;
2014-08-29 07:52:33 -07:00
printStatus();
}
2014-09-11 08:03:38 -07:00
void WaveChart::publishChartIfFull() {
if (isWaveChartFull()) {
publishChart();
resetWaveChart();
2014-08-29 07:52:33 -07:00
}
}
2014-09-11 16:02:59 -07:00
void WaveChart::init() {
2014-09-11 08:03:38 -07:00
initLoggingExt(&logging, "wave chart", WAVE_LOGGING_BUFFER, sizeof(WAVE_LOGGING_BUFFER));
isInitialized = TRUE;
resetWaveChart();
}
void WaveChart::publishChart() {
appendPrintf(&logging, DELIMETER);
waveChartUsedSize = loggingSize(&logging);
2014-08-29 07:52:33 -07:00
#if DEBUG_WAVE
Logging *l = &chart->logging;
scheduleSimpleMsg(&debugLogging, "IT'S TIME", strlen(l->buffer));
#endif
2014-08-30 17:05:51 -07:00
bool isFullLog = getFullLog();
2014-08-29 07:52:33 -07:00
if (isChartActive && isFullLog) {
2014-09-11 08:03:38 -07:00
scheduleLogging(&logging);
2014-08-30 17:05:51 -07:00
}
2014-08-29 07:52:33 -07:00
}
static char timeBuffer[10];
/**
* @brief Register an event for digital sniffer
*/
2014-09-11 08:03:38 -07:00
void WaveChart::addWaveChartEvent3(const char *name, const char * msg, const char * msg2) {
2014-10-02 20:03:25 -07:00
if(!isChartActive) {
return;
}
2014-09-11 08:03:38 -07:00
efiAssertVoid(isInitialized, "chart not initialized");
2014-08-29 07:52:33 -07:00
#if DEBUG_WAVE
scheduleSimpleMsg(&debugLogging, "current", chart->counter);
#endif
2014-09-11 08:03:38 -07:00
if (isWaveChartFull()) {
2014-08-29 07:52:33 -07:00
return;
2014-08-30 17:05:51 -07:00
}
2014-08-29 07:52:33 -07:00
#if EFI_HISTOGRAMS && EFI_PROD_CODE
int beforeCallback = hal_lld_get_counter_value();
#endif
2014-09-14 21:06:45 -07:00
uint64_t nowUs = getTimeNowUs();
/**
* todo: migrate to binary fractions in order to eliminate
* this division? I do not like division
*/
uint64_t time100 = nowUs / 10;
2014-08-29 07:52:33 -07:00
bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer
2014-09-11 08:03:38 -07:00
if (counter == 0) {
2014-09-14 21:06:45 -07:00
startTime100 = time100;
startTimeUs = nowUs;
2014-08-30 17:05:51 -07:00
}
2014-09-11 08:03:38 -07:00
counter++;
if (remainingSize(&logging) > 30) {
2014-08-29 07:52:33 -07:00
/**
* printf is a heavy method, append is used here as a performance optimization
*/
2014-09-11 08:03:38 -07:00
appendFast(&logging, name);
appendFast(&logging, CHART_DELIMETER);
appendFast(&logging, msg);
appendFast(&logging, CHART_DELIMETER);
2014-08-29 07:52:33 -07:00
/**
* We want smaller times within a chart in order to reduce packet size.
*/
2014-09-14 21:06:45 -07:00
time100 -= startTime100;
2014-08-29 07:52:33 -07:00
itoa10(timeBuffer, time100);
2014-09-11 08:03:38 -07:00
appendFast(&logging, timeBuffer);
appendFast(&logging, msg2);
appendFast(&logging, CHART_DELIMETER);
2014-08-29 07:52:33 -07:00
}
if (!alreadyLocked) {
unlockOutputBuffer();
2014-08-30 17:05:51 -07:00
}
2014-08-29 07:52:33 -07:00
#if EFI_HISTOGRAMS && EFI_PROD_CODE
int64_t diff = hal_lld_get_counter_value() - beforeCallback;
if (diff > 0) {
2014-08-30 17:05:51 -07:00
hsAdd(&waveChartHisto, diff);
}
2014-08-29 07:52:33 -07:00
#endif /* EFI_HISTOGRAMS */
}
void showWaveChartHistogram(void) {
#if EFI_PROD_CODE
printHistogram(&logger, &waveChartHisto);
#endif
}
void initWaveChart(WaveChart *chart) {
initLogging(&logger, "wave info");
if (!isChartActive) {
printMsg(&logger, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! chart disabled");
2014-08-30 17:05:51 -07:00
}
2014-08-29 07:52:33 -07:00
2014-09-11 16:02:59 -07:00
/**
* constructor does not work because we need specific initialization order
*/
chart->init();
2014-08-29 07:52:33 -07:00
printStatus();
#if DEBUG_WAVE
initLoggingExt(&debugLogging, "wave chart debug", &debugLogging.DEFAULT_BUFFER, sizeof(debugLogging.DEFAULT_BUFFER));
#endif
#if EFI_HISTOGRAMS
initHistogram(&waveChartHisto, "wave chart");
#endif /* EFI_HISTOGRAMS */
addConsoleActionI("chartsize", setChartSize);
addConsoleActionI("chart", setChartActive);
}
#endif /* EFI_WAVE_CHART */