Merge remote-tracking branch 'remotes/mck1117/perf-tracing'
# Conflicts: # firmware/development/development.mk
This commit is contained in:
commit
3af49796a5
|
@ -18,12 +18,14 @@ extern "C"
|
|||
#endif /* __cplusplus */
|
||||
#ifndef __ASSEMBLER__
|
||||
void firmwareError(obd_code_e code, const char *fmt, ...);
|
||||
#if EFI_CLOCK_LOCKS
|
||||
#if ENABLE_PERF_TRACE
|
||||
void irqEnterHook(void);
|
||||
void irqExitHook(void);
|
||||
void contextSwitchHook(void);
|
||||
#else /* EFI_CLOCK_LOCKS */
|
||||
#define irqEnterHook() {}
|
||||
#define irqExitHook() {}
|
||||
#define contextSwitchHook() {}
|
||||
#endif /*EFI_CLOCK_LOCKS */
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -50,10 +50,10 @@
|
|||
|
||||
#define CHPRINTF_USE_FLOAT TRUE
|
||||
|
||||
#if !defined(EFI_CLOCK_LOCKS) || defined(__DOXYGEN__)
|
||||
#if !defined(ENABLE_PERF_TRACE) || defined(__DOXYGEN__)
|
||||
// looks like this value could not be defined in efifeatures.h - please define either externally or just change the value here
|
||||
#define EFI_CLOCK_LOCKS FALSE
|
||||
#endif /* EFI_CLOCK_LOCKS */
|
||||
#define ENABLE_PERF_TRACE TRUE
|
||||
#endif /* ENABLE_PERF_TRACE */
|
||||
|
||||
#include "chconf_common.h"
|
||||
|
||||
|
@ -565,7 +565,7 @@
|
|||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#ifndef CH_DBG_ENABLE_TRACE
|
||||
#define CH_DBG_ENABLE_TRACE TRUE
|
||||
#define CH_DBG_ENABLE_TRACE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -670,7 +670,7 @@
|
|||
* @details This hook is invoked just before switching between threads.
|
||||
*/
|
||||
#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
|
||||
/* Context switch code here.*/ \
|
||||
contextSwitchHook(); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -696,7 +696,6 @@
|
|||
* @note This macro can be used to activate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_ENTER_HOOK() { \
|
||||
/* Idle-enter code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -706,7 +705,6 @@
|
|||
* @note This macro can be used to deactivate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_LEAVE_HOOK() { \
|
||||
/* Idle-leave code here.*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
#include "loggingcentral.h"
|
||||
#include "status_loop.h"
|
||||
#include "mmc_card.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_SIMULATOR
|
||||
#include "rusEfiFunctionalTest.h"
|
||||
#endif
|
||||
|
@ -751,6 +753,8 @@ bool handlePlainCommand(ts_channel_s *tsChannel, uint8_t command) {
|
|||
|
||||
|
||||
int tunerStudioHandleCrcCommand(ts_channel_s *tsChannel, char *data, int incomingPacketSize) {
|
||||
ScopePerf perf(PE::TunerStudioHandleCrcCommand);
|
||||
|
||||
char command = data[0];
|
||||
data++;
|
||||
|
||||
|
@ -848,6 +852,14 @@ int tunerStudioHandleCrcCommand(ts_channel_s *tsChannel, char *data, int incomin
|
|||
}
|
||||
|
||||
break;
|
||||
case TS_PERF_TRACE_BEGIN:
|
||||
perfTraceEnable();
|
||||
break;
|
||||
case TS_PERF_TRACE_GET_BUFFER:
|
||||
{
|
||||
auto trace = perfTraceGetBuffer();
|
||||
sr5SendResponse(tsChannel, TS_CRC, trace.Buffer, trace.Size);
|
||||
}
|
||||
#endif /* EFI_TOOTH_LOGGER */
|
||||
default:
|
||||
tunerStudioError("ERROR: ignoring unexpected command");
|
||||
|
|
|
@ -73,6 +73,10 @@ typedef struct {
|
|||
#define TS_SET_LOGGER_MODE 'l'
|
||||
#define TS_GET_LOGGER_BUFFER 'L'
|
||||
|
||||
// Performance tracing
|
||||
#define TS_PERF_TRACE_BEGIN 'r'
|
||||
#define TS_PERF_TRACE_GET_BUFFER 'b'
|
||||
|
||||
#define TS_SINGLE_WRITE_COMMAND 'W' // 0x57 pageValueWrite
|
||||
#define TS_CHUNK_WRITE_COMMAND 'C' // 0x43 pageChunkWrite
|
||||
#define TS_BURN_COMMAND 'B' // 0x42 burnCommand
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "accel_enrichment.h"
|
||||
#include "allsensors.h"
|
||||
#include "engine_math.h"
|
||||
#include "perf_trace.h"
|
||||
#if EFI_TUNER_STUDIO
|
||||
#include "tunerstudio_configuration.h"
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
@ -53,6 +54,8 @@ floatms_t WallFuel::adjust(floatms_t desiredFuel DECLARE_ENGINE_PARAMETER_SUFFIX
|
|||
return desiredFuel;
|
||||
}
|
||||
|
||||
ScopePerf perf(PE::WallFuelAdjust);
|
||||
|
||||
/*
|
||||
this math is based on
|
||||
SAE 810494 by C. F. Aquino
|
||||
|
@ -168,6 +171,8 @@ float AccelEnrichment::getMaxDelta(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
|
||||
// todo: eliminate code duplication between these two methods! Some pointer magic would help.
|
||||
floatms_t TpsAccelEnrichment::getTpsEnrichment(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
ScopePerf perf(PE::GetTpsEnrichment);
|
||||
|
||||
int maxDeltaIndex = getMaxDeltaIndex(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
// FuelSchedule *fs = engineConfiguration->injectionEvents;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "aux_valves.h"
|
||||
#include "map_averaging.h"
|
||||
#include "fsio_impl.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#include "injector_central.h"
|
||||
|
@ -112,6 +113,8 @@ static void cylinderCleanupControl(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
static efitick_t tle8888CrankingResetTime = 0;
|
||||
|
||||
void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
ScopePerf perf(PE::EnginePeriodicSlowCallback);
|
||||
|
||||
watchdog();
|
||||
updateSlowSensors(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
checkShutdown();
|
||||
|
@ -359,6 +362,7 @@ operation_mode_e Engine::getOperationMode(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
* so that trigger event handler/IO scheduler tasks are faster.
|
||||
*/
|
||||
void Engine::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
ScopePerf pc(PE::EnginePeriodicFastCallback);
|
||||
|
||||
#if EFI_MAP_AVERAGING
|
||||
refreshMapAveragingPreCalc(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "engine_math.h"
|
||||
#include "advance_map.h"
|
||||
#include "aux_valves.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#include "svnversion.h"
|
||||
#endif
|
||||
|
@ -139,6 +141,8 @@ void EngineState::updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
}
|
||||
|
||||
void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
ScopePerf perf(PE::EngineStatePeriodicFastCallback);
|
||||
|
||||
#if EFI_ENGINE_CONTROL
|
||||
if (!engine->slowCallBackWasInvoked) {
|
||||
warning(CUSTOM_ERR_6696, "Slow not invoked yet");
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "engine_math.h"
|
||||
#include "rpm_calculator.h"
|
||||
#include "speed_density.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
EXTERN_ENGINE
|
||||
;
|
||||
|
@ -94,6 +95,8 @@ DISPLAY(DISPLAY_IF(isCrankingState)) floatms_t getCrankingFuel3(float coolantTem
|
|||
/* DISPLAY_ELSE */
|
||||
|
||||
floatms_t getRunningFuel(floatms_t baseFuel DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::GetRunningFuel);
|
||||
|
||||
DISPLAY_TEXT(Base_fuel);
|
||||
ENGINE(engineState.DISPLAY_PREFIX(running).DISPLAY_FIELD(baseFuel)) = baseFuel;
|
||||
DISPLAY_TEXT(eol);
|
||||
|
@ -161,6 +164,8 @@ float getRealMafFuel(float airSpeed, int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
* todo: rename this method since it's now base+TPSaccel
|
||||
*/
|
||||
floatms_t getBaseFuel(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::GetBaseFuel);
|
||||
|
||||
floatms_t tpsAccelEnrich = ENGINE(tpsAccelEnrichment.getTpsEnrichment(PASS_ENGINE_PARAMETER_SIGNATURE));
|
||||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(tpsAccelEnrich), "NaN tpsAccelEnrich", 0);
|
||||
ENGINE(engineState.tpsAccelEnrich) = tpsAccelEnrich;
|
||||
|
@ -235,6 +240,8 @@ percent_t getInjectorDutyCycle(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
* in case of single point injection mode the amount of fuel into all cylinders, otherwise the amount for one cylinder
|
||||
*/
|
||||
floatms_t getInjectionDuration(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::GetInjectionDuration);
|
||||
|
||||
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
|
||||
bool isCranking = ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
injection_mode_e mode = isCranking ?
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "aux_pid.h"
|
||||
#include "accelerometer.h"
|
||||
#include "counter64.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if HAL_USE_ADC
|
||||
#include "AdcConfiguration.h"
|
||||
|
@ -298,41 +299,24 @@ static void resetAccel(void) {
|
|||
|
||||
static int previousSecond;
|
||||
|
||||
#if EFI_CLOCK_LOCKS
|
||||
|
||||
typedef FLStack<int, 16> irq_enter_timestamps_t;
|
||||
|
||||
static irq_enter_timestamps_t irqEnterTimestamps;
|
||||
#if ENABLE_PERF_TRACE
|
||||
|
||||
void irqEnterHook(void) {
|
||||
irqEnterTimestamps.push(getTimeNowLowerNt());
|
||||
perfEventBegin(PE::ISR);
|
||||
}
|
||||
|
||||
static int currentIrqDurationAccumulator = 0;
|
||||
static int currentIrqCounter = 0;
|
||||
/**
|
||||
* See also maxLockedDuration
|
||||
*/
|
||||
int perSecondIrqDuration = 0;
|
||||
int perSecondIrqCounter = 0;
|
||||
void irqExitHook(void) {
|
||||
int enterTime = irqEnterTimestamps.pop();
|
||||
currentIrqDurationAccumulator += (getTimeNowLowerNt() - enterTime);
|
||||
currentIrqCounter++;
|
||||
perfEventEnd(PE::ISR);
|
||||
}
|
||||
#endif /* EFI_CLOCK_LOCKS */
|
||||
|
||||
static void invokePerSecond(void) {
|
||||
#if EFI_CLOCK_LOCKS
|
||||
// this data transfer is not atomic but should be totally good enough
|
||||
perSecondIrqDuration = currentIrqDurationAccumulator;
|
||||
perSecondIrqCounter = currentIrqCounter;
|
||||
currentIrqDurationAccumulator = currentIrqCounter = 0;
|
||||
#endif /* EFI_CLOCK_LOCKS */
|
||||
void contextSwitchHook() {
|
||||
perfEventInstantGlobal(PE::ContextSwitch);
|
||||
}
|
||||
|
||||
#endif /* ENABLE_PERF_TRACE */
|
||||
|
||||
static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
|
||||
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
|
||||
efiAssertVoid(CUSTOM_ERR_6661, getCurrentRemainingStack() > 64, "lowStckOnEv");
|
||||
#if EFI_PROD_CODE
|
||||
/**
|
||||
|
@ -343,11 +327,6 @@ static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
updateAndSet(&halTime.state, getTimeNowLowerNt());
|
||||
/* Leaving the critical zone.*/
|
||||
chSysRestoreStatusX(sts);
|
||||
int timeSeconds = getTimeNowSeconds();
|
||||
if (previousSecond != timeSeconds) {
|
||||
previousSecond = timeSeconds;
|
||||
invokePerSecond();
|
||||
}
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "interpolation.h"
|
||||
#include "engine.h"
|
||||
#include "engine_math.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_SENSOR_CHART
|
||||
#include "sensor_chart.h"
|
||||
|
@ -263,6 +264,9 @@ void refreshMapAveragingPreCalc(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
*/
|
||||
static void mapAveragingTriggerCallback(trigger_event_e ckpEventType,
|
||||
uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
|
||||
ScopePerf perf(PE::MapAveragingTriggerCallback);
|
||||
|
||||
#if EFI_ENGINE_CONTROL
|
||||
// this callback is invoked on interrupt thread
|
||||
UNUSED(ckpEventType);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "engine_math.h"
|
||||
#include "maf2map.h"
|
||||
#include "config_engine_specs.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if defined(HAS_OS_ACCESS)
|
||||
#error "Unexpected OS ACCESS HERE"
|
||||
|
@ -137,6 +138,8 @@ EXTERN_ENGINE;
|
|||
* @return per cylinder injection time, in Milliseconds
|
||||
*/
|
||||
floatms_t getSpeedDensityFuel(float map DECLARE_GLOBAL_SUFFIX) {
|
||||
ScopePerf perf(PE::GetSpeedDensityFuel);
|
||||
|
||||
/**
|
||||
* most of the values are pre-calculated for performance reasons
|
||||
*/
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "event_queue.h"
|
||||
#include "efitime.h"
|
||||
#include "os_util.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_UNIT_TEST
|
||||
extern bool verboseMode;
|
||||
|
@ -36,6 +37,8 @@ bool EventQueue::checkIfPending(scheduling_s *scheduling) {
|
|||
* @return true if inserted into the head of the list
|
||||
*/
|
||||
bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t callback, void *param) {
|
||||
ScopePerf perf(PE::EventQueueInsertTask);
|
||||
|
||||
#if EFI_UNIT_TEST
|
||||
assertListIsSorted();
|
||||
#endif /* EFI_UNIT_TEST */
|
||||
|
@ -118,6 +121,9 @@ static uint32_t lastEventCallbackDuration;
|
|||
* @return number of executed actions
|
||||
*/
|
||||
int EventQueue::executeAll(efitime_t now) {
|
||||
ScopePerf perf(PE::EventQueueExecuteAll);
|
||||
|
||||
|
||||
scheduling_s * current, *tmp;
|
||||
|
||||
scheduling_s * executionList = nullptr;
|
||||
|
@ -171,7 +177,12 @@ int EventQueue::executeAll(efitime_t now) {
|
|||
#if EFI_UNIT_TEST
|
||||
printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->param);
|
||||
#endif
|
||||
current->callback(current->param);
|
||||
|
||||
{
|
||||
ScopePerf perf2(PE::EventQueueExecuteCallback);
|
||||
current->callback(current->param);
|
||||
}
|
||||
|
||||
// even with overflow it's safe to subtract here
|
||||
lastEventCallbackDuration = getTimeNowLowerNt() - before;
|
||||
if (lastEventCallbackDuration > maxEventCallbackDuration)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "pwm_generator_logic.h"
|
||||
#include "pwm_generator.h"
|
||||
#include "error_handling.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
/**
|
||||
* We need to limit the number of iterations in order to avoid precision loss while calculating
|
||||
|
@ -159,9 +160,12 @@ void PwmConfig::handleCycleStart() {
|
|||
* @return Next time for signal toggle
|
||||
*/
|
||||
efitimeus_t PwmConfig::togglePwmState() {
|
||||
ScopePerf perf(PE::PwmConfigTogglePwmState);
|
||||
|
||||
if (isStopRequested) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DEBUG_PWM
|
||||
scheduleMsg(&logger, "togglePwmState phaseIndex=%d iteration=%d", safe.phaseIndex, safe.iteration);
|
||||
scheduleMsg(&logger, "period=%.2f safe.period=%.2f", period, safe.periodNt);
|
||||
|
@ -196,7 +200,10 @@ efitimeus_t PwmConfig::togglePwmState() {
|
|||
cbStateIndex = 1;
|
||||
}
|
||||
|
||||
stateChangeCallback(cbStateIndex, arg);
|
||||
{
|
||||
ScopePerf perf(PE::PwmConfigStateChangeCallback);
|
||||
stateChangeCallback(cbStateIndex, arg);
|
||||
}
|
||||
|
||||
efitimeus_t nextSwitchTimeUs = getNextSwitchTimeUs(this);
|
||||
#if DEBUG_PWM
|
||||
|
@ -236,6 +243,8 @@ efitimeus_t PwmConfig::togglePwmState() {
|
|||
* First invocation happens on application thread
|
||||
*/
|
||||
static void timerCallback(PwmConfig *state) {
|
||||
ScopePerf perf(PE::PwmGeneratorCallback);
|
||||
|
||||
state->dbgNestingLevel++;
|
||||
efiAssertVoid(CUSTOM_ERR_6581, state->dbgNestingLevel < 25, "PWM nesting issue");
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "os_access.h"
|
||||
#include "single_timer_executor.h"
|
||||
#include "efitime.h"
|
||||
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_SIGNAL_EXECUTOR_ONE_TIMER
|
||||
|
||||
|
@ -84,6 +84,8 @@ void SingleTimerExecutor::scheduleForLater(scheduling_s *scheduling, int delayUs
|
|||
*/
|
||||
void SingleTimerExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback,
|
||||
void *param) {
|
||||
ScopePerf perf(PE::SingleTimerExecutorScheduleByTimestamp);
|
||||
|
||||
scheduleCounter++;
|
||||
bool alreadyLocked = true;
|
||||
if (!reentrantFlag) {
|
||||
|
@ -114,6 +116,8 @@ void SingleTimerExecutor::onTimerCallback() {
|
|||
* this private method is executed under lock
|
||||
*/
|
||||
void SingleTimerExecutor::doExecute() {
|
||||
ScopePerf perf(PE::SingleTimerExecutorDoExecute);
|
||||
|
||||
doExecuteCounter++;
|
||||
/**
|
||||
* Let's execute actions we should execute at this point.
|
||||
|
@ -148,6 +152,8 @@ void SingleTimerExecutor::doExecute() {
|
|||
* This method is always invoked under a lock
|
||||
*/
|
||||
void SingleTimerExecutor::scheduleTimerCallback() {
|
||||
ScopePerf perf(PE::SingleTimerExecutorScheduleTimerCallback);
|
||||
|
||||
/**
|
||||
* Let's grab fresh time value
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "engine.h"
|
||||
#include "efi_gpio.h"
|
||||
#include "drivers/gpio/gpio_ext.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_GPIO_HARDWARE
|
||||
#include "pin_repository.h"
|
||||
|
@ -322,6 +323,8 @@ void OutputPin::toggle() {
|
|||
|
||||
}
|
||||
void OutputPin::setValue(int logicValue) {
|
||||
ScopePerf perf(PE::OutputPinSetValue);
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
efiAssertVoid(CUSTOM_ERR_6621, modePtr!=NULL, "pin mode not initialized");
|
||||
pin_output_mode_e mode = *modePtr;
|
||||
|
|
|
@ -7,10 +7,15 @@
|
|||
|
||||
#include "periodic_task.h"
|
||||
#include "os_util.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
void runAndScheduleNext(PeriodicTimerController *controller) {
|
||||
#if !EFI_UNIT_TEST
|
||||
controller->PeriodicTask();
|
||||
{
|
||||
ScopePerf perf(PE::PeriodicTimerControllerPeriodicTask);
|
||||
controller->PeriodicTask();
|
||||
}
|
||||
|
||||
chVTSetAny(&controller->timer, TIME_MS2I(controller->getPeriodMs()), (vtfunc_t) &runAndScheduleNext, controller);
|
||||
#endif /* EFI_UNIT_TEST */
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "thread_controller.h"
|
||||
#include "efitime.h"
|
||||
|
||||
#include "perf_trace.h"
|
||||
|
||||
/**
|
||||
* @brief Base class for a controller that needs to run periodically to perform work.
|
||||
|
@ -65,8 +65,12 @@ private:
|
|||
systime_t before = chVTGetSystemTime();
|
||||
efitime_t nowNt = getTimeNowNt();
|
||||
|
||||
// Run the controller's periodic work
|
||||
PeriodicTask(nowNt);
|
||||
{
|
||||
ScopePerf perf(PE::PeriodicControllerPeriodicTask);
|
||||
|
||||
// Run the controller's periodic work
|
||||
PeriodicTask(nowNt);
|
||||
}
|
||||
|
||||
// This ensures the loop _actually_ runs at the desired frequency.
|
||||
// Suppose we want a loop speed of 500hz:
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "local_version_holder.h"
|
||||
#include "event_queue.h"
|
||||
#include "engine.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#include "aux_valves.h"
|
||||
#include "backup_ram.h"
|
||||
|
@ -361,6 +362,8 @@ static void fuelClosedLoopCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
|
||||
|
||||
static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIndex, int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::HandleFuel);
|
||||
|
||||
efiAssertVoid(CUSTOM_STACK_6627, getCurrentRemainingStack() > 128, "lowstck#3");
|
||||
efiAssertVoid(CUSTOM_ERR_6628, trgEventIndex < engine->engineCycleEventCount, "handleFuel/event index");
|
||||
|
||||
|
@ -425,6 +428,8 @@ uint32_t *cyccnt = (uint32_t*) &DWT->CYCCNT;
|
|||
* Both injection and ignition are controlled from this method.
|
||||
*/
|
||||
void mainTriggerCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::MainTriggerCallback);
|
||||
|
||||
(void) ckpSignalType;
|
||||
|
||||
ENGINE(m.beforeMainTrigger) = getTimeNowLowerNt();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "trigger_central.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "engine_math.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#include "os_util.h"
|
||||
|
@ -358,6 +359,8 @@ void initRpmCalculator(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
*/
|
||||
void scheduleByAngle(float rpm, scheduling_s *timer, angle_t angle,
|
||||
schfunc_t callback, void *param DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::ScheduleByAngle);
|
||||
|
||||
efiAssertVoid(CUSTOM_ANGLE_NAN, !cisnan(angle), "NaN angle?");
|
||||
efiAssertVoid(CUSTOM_ERR_6634, isValidRpm(rpm), "RPM check expected");
|
||||
float delayUs = ENGINE(rpmCalculator.oneDegreeUs) * angle;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "utlist.h"
|
||||
#include "event_queue.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_TUNER_STUDIO
|
||||
#include "tunerstudio_configuration.h"
|
||||
|
@ -404,6 +405,8 @@ static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex D
|
|||
void onTriggerEventSparkLogic(bool limitedSpark, uint32_t trgEventIndex, int rpm
|
||||
DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
|
||||
ScopePerf perf(PE::OnTriggerEventSparkLogic);
|
||||
|
||||
if (!isValidRpm(rpm) || !CONFIG(isIgnitionEnabled)) {
|
||||
// this might happen for instance in case of a single trigger event after a pause
|
||||
return;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "rpm_calculator.h"
|
||||
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#include "pin_repository.h"
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
@ -197,6 +199,8 @@ static bool isInsideTriggerHandler = false;
|
|||
|
||||
|
||||
void hwHandleShaftSignal(trigger_event_e signal) {
|
||||
ScopePerf perf(PE::HandleShaftSignal, static_cast<uint8_t>(signal));
|
||||
|
||||
#if EFI_TOOTH_LOGGER
|
||||
// Log to the Tunerstudio tooth logger
|
||||
// We want to do this before anything else as we
|
||||
|
@ -390,6 +394,8 @@ void TriggerCentral::handleShaftSignal(trigger_event_e signal DECLARE_ENGINE_PAR
|
|||
}
|
||||
|
||||
if (triggerState.isValidIndex(PASS_ENGINE_PARAMETER_SIGNATURE)) {
|
||||
ScopePerf perf(PE::ShaftPositionListeners);
|
||||
|
||||
#if TRIGGER_EXTREME_LOGGING
|
||||
scheduleMsg(logger, "trigger %d %d %d", triggerIndexForListeners, getRevolutionCounter(), (int)getTimeNowUs());
|
||||
#endif /* FUEL_MATH_EXTREME_LOGGING */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "engine_math.h"
|
||||
#include "trigger_central.h"
|
||||
#include "trigger_simulator.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_SENSOR_CHART
|
||||
#include "sensor_chart.h"
|
||||
|
@ -416,6 +417,8 @@ void TriggerState::onShaftSynchronization(efitime_t nowNt, trigger_wheel_e trigg
|
|||
* @param nowNt current time
|
||||
*/
|
||||
void TriggerState::decodeTriggerEvent(trigger_event_e const signal, efitime_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
ScopePerf perf(PE::DecodeTriggerEvent, static_cast<uint8_t>(signal));
|
||||
|
||||
bool useOnlyRisingEdgeForTrigger = CONFIG(useOnlyRisingEdgeForTrigger);
|
||||
// todo: use 'triggerShape' instead of TRIGGER_SHAPE in order to decouple this method from engine #635
|
||||
TriggerShape *triggerShape = &ENGINE(triggerCentral.triggerShape);
|
||||
|
|
|
@ -9,6 +9,7 @@ DEV_SRC_CPP = $(DEVELOPMENT_DIR)/trigger_emulator.cpp \
|
|||
$(DEVELOPMENT_DIR)/rfi_perftest.cpp \
|
||||
$(DEVELOPMENT_DIR)/engine_emulator.cpp \
|
||||
$(DEVELOPMENT_DIR)/engine_sniffer.cpp \
|
||||
$(DEVELOPMENT_DIR)/wave_analyzer.cpp
|
||||
$(DEVELOPMENT_DIR)/wave_analyzer.cpp \
|
||||
$(DEVELOPMENT_DIR)/development/perf_trace.cpp
|
||||
|
||||
DEV_SIMULATOR_SRC_CPP = $(DEVELOPMENT_DIR)/engine_sniffer.cpp
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
#include "efifeatures.h"
|
||||
#include "perf_trace.h"
|
||||
#include "efitime.h"
|
||||
#include "os_util.h"
|
||||
|
||||
#define TRACE_BUFFER_LENGTH 2048
|
||||
|
||||
enum class EPhase : char
|
||||
{
|
||||
Start,
|
||||
End,
|
||||
InstantThread,
|
||||
InstantGlobal,
|
||||
};
|
||||
|
||||
struct TraceEntry
|
||||
{
|
||||
PE Event;
|
||||
EPhase Phase;
|
||||
uint8_t Data;
|
||||
uint8_t ThreadId;
|
||||
uint32_t Timestamp;
|
||||
};
|
||||
|
||||
static_assert(sizeof(TraceEntry) == 8);
|
||||
|
||||
static TraceEntry s_traceBuffer[TRACE_BUFFER_LENGTH];
|
||||
static size_t s_nextIdx = 0;
|
||||
|
||||
static bool s_isTracing = true;
|
||||
|
||||
void perfEventImpl(PE event, EPhase phase, uint8_t data)
|
||||
{
|
||||
if constexpr (!ENABLE_PERF_TRACE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!s_isTracing) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t timestamp = getTimeNowLowerNt();
|
||||
|
||||
size_t idx;
|
||||
|
||||
// Critical section: reserve index under lock
|
||||
{
|
||||
bool wasLocked = lockAnyContext();
|
||||
|
||||
idx = s_nextIdx++;
|
||||
if (s_nextIdx >= TRACE_BUFFER_LENGTH) {
|
||||
s_nextIdx = 0;
|
||||
s_isTracing = false;
|
||||
}
|
||||
|
||||
if (!wasLocked) {
|
||||
unlockAnyContext();
|
||||
}
|
||||
}
|
||||
|
||||
// We can safely write data out of the lock, our spot is reserved
|
||||
volatile TraceEntry& entry = s_traceBuffer[idx];
|
||||
|
||||
entry.Event = event;
|
||||
entry.Phase = phase;
|
||||
entry.ThreadId = static_cast<uint8_t>(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
|
||||
entry.Timestamp = timestamp;
|
||||
entry.Data = data;
|
||||
}
|
||||
|
||||
void perfEventBegin(PE event, uint8_t data) {
|
||||
perfEventImpl(event, EPhase::Start, data);
|
||||
}
|
||||
|
||||
void perfEventEnd(PE event, uint8_t data) {
|
||||
perfEventImpl(event, EPhase::End, data);
|
||||
}
|
||||
|
||||
void perfEventInstantGlobal(PE event, uint8_t data) {
|
||||
perfEventImpl(event, EPhase::InstantGlobal, data);
|
||||
}
|
||||
|
||||
void perfTraceEnable() {
|
||||
s_isTracing = true;
|
||||
}
|
||||
|
||||
const TraceBufferResult perfTraceGetBuffer() {
|
||||
// stop tracing if you try to get the buffer early
|
||||
s_isTracing = false;
|
||||
|
||||
return {reinterpret_cast<const uint8_t*>(s_traceBuffer), sizeof(s_traceBuffer)};
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
// Defines different events we want to trace. These can be an interval (begin -> end), or an
|
||||
// instant. Instants can be global, or specific to one thread. You probably don't want to use
|
||||
// each element in PE more than once, as they should each indicate that a specific thing began,
|
||||
// ended, or occured.
|
||||
enum class PE : uint8_t {
|
||||
INVALID,
|
||||
ISR,
|
||||
ContextSwitch,
|
||||
OutputPinSetValue,
|
||||
DecodeTriggerEvent,
|
||||
EnginePeriodicFastCallback,
|
||||
EnginePeriodicSlowCallback,
|
||||
EngineStatePeriodicFastCallback,
|
||||
HandleShaftSignal,
|
||||
EventQueueInsertTask,
|
||||
EventQueueExecuteAll,
|
||||
SingleTimerExecutorDoExecute,
|
||||
SingleTimerExecutorScheduleTimerCallback,
|
||||
PeriodicControllerPeriodicTask,
|
||||
PeriodicTimerControllerPeriodicTask,
|
||||
AdcCallbackFast,
|
||||
AdcCallbackSlow,
|
||||
AdcConversionSlow,
|
||||
AdcConversionFast,
|
||||
AdcSubscriptionUpdateSubscribers,
|
||||
GetRunningFuel,
|
||||
GetInjectionDuration,
|
||||
HandleFuel,
|
||||
MainTriggerCallback,
|
||||
OnTriggerEventSparkLogic,
|
||||
ShaftPositionListeners,
|
||||
GetBaseFuel,
|
||||
GetTpsEnrichment,
|
||||
GetSpeedDensityFuel,
|
||||
WallFuelAdjust,
|
||||
MapAveragingTriggerCallback,
|
||||
AdcCallbackFastComplete,
|
||||
SingleTimerExecutorScheduleByTimestamp,
|
||||
ScheduleByAngle,
|
||||
EventQueueExecuteCallback,
|
||||
PwmGeneratorCallback,
|
||||
TunerStudioHandleCrcCommand,
|
||||
PwmConfigTogglePwmState,
|
||||
PwmConfigStateChangeCallback,
|
||||
};
|
||||
|
||||
void perfEventBegin(PE event, uint8_t data);
|
||||
void perfEventEnd(PE event, uint8_t data);
|
||||
void perfEventInstantGlobal(PE event, uint8_t data);
|
||||
|
||||
inline void perfEventBegin(PE event) {
|
||||
perfEventBegin(event, 0);
|
||||
}
|
||||
|
||||
inline void perfEventEnd(PE event) {
|
||||
perfEventEnd(event, 0);
|
||||
}
|
||||
|
||||
inline void perfEventInstantGlobal(PE event) {
|
||||
perfEventInstantGlobal(event, 0);
|
||||
}
|
||||
|
||||
// Enable one buffer's worth of perf tracing, and retrieve the buffer size in bytes
|
||||
void perfTraceEnable();
|
||||
|
||||
struct TraceBufferResult
|
||||
{
|
||||
const uint8_t* const Buffer;
|
||||
const size_t Size;
|
||||
};
|
||||
|
||||
// Retrieve the trace buffer
|
||||
const TraceBufferResult perfTraceGetBuffer();
|
||||
|
||||
class ScopePerf
|
||||
{
|
||||
public:
|
||||
ScopePerf(PE event) : ScopePerf(event, 0) {}
|
||||
|
||||
ScopePerf(PE event, uint8_t data) : m_event(event), m_data(data)
|
||||
{
|
||||
perfEventBegin(event, data);
|
||||
}
|
||||
|
||||
~ScopePerf()
|
||||
{
|
||||
perfEventEnd(m_event, m_data);
|
||||
}
|
||||
|
||||
private:
|
||||
const PE m_event;
|
||||
const uint8_t m_data;
|
||||
};
|
|
@ -35,7 +35,7 @@
|
|||
#include "engine_math.h"
|
||||
#include "engine_controller.h"
|
||||
#include "maf.h"
|
||||
//#include "biquad.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
/* Depth of the conversion buffer, channels are sampled X times each.*/
|
||||
#define ADC_BUF_DEPTH_SLOW 8
|
||||
|
@ -228,6 +228,7 @@ void doSlowAdc(void) {
|
|||
;
|
||||
return;
|
||||
}
|
||||
|
||||
adcStartConversionI(&ADC_SLOW_DEVICE, &adcgrpcfgSlow, slowAdc.samples, ADC_BUF_DEPTH_SLOW);
|
||||
chSysUnlockFromISR()
|
||||
;
|
||||
|
@ -261,6 +262,7 @@ static void pwmpcb_fast(PWMDriver *pwmp) {
|
|||
;
|
||||
return;
|
||||
}
|
||||
|
||||
adcStartConversionI(&ADC_FAST_DEVICE, &adcgrpcfg_fast, fastAdc.samples, ADC_BUF_DEPTH_FAST);
|
||||
chSysUnlockFromISR()
|
||||
;
|
||||
|
@ -459,6 +461,8 @@ static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
|
|||
(void) buffer;
|
||||
(void) n;
|
||||
|
||||
ScopePerf perf(PE::AdcCallbackSlow);
|
||||
|
||||
/* Note, only in the ADC_COMPLETE state because the ADC driver fires
|
||||
* an intermediate callback when the buffer is half full. */
|
||||
if (adcp->state == ADC_COMPLETE) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "adc_inputs.h"
|
||||
#include "engine.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
|
@ -46,6 +47,8 @@ void AdcSubscription::SubscribeSensor(FunctionalSensor &sensor,
|
|||
}
|
||||
|
||||
void AdcSubscription::UpdateSubscribers() {
|
||||
ScopePerf perf(PE::AdcSubscriptionUpdateSubscribers);
|
||||
|
||||
for (size_t i = 0; i < s_nextEntry; i++) {
|
||||
auto &entry = s_entries[i];
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "svnversion.h"
|
||||
#include "engine_configuration.h"
|
||||
#include "aux_pid.h"
|
||||
#include "perf_trace.h"
|
||||
|
||||
#if EFI_MC33816
|
||||
#include "mc33816.h"
|
||||
|
@ -198,11 +199,16 @@ extern AdcDevice fastAdc;
|
|||
void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
|
||||
(void) buffer;
|
||||
(void) n;
|
||||
|
||||
ScopePerf perf(PE::AdcCallbackFast);
|
||||
|
||||
/**
|
||||
* Note, only in the ADC_COMPLETE state because the ADC driver fires an
|
||||
* intermediate callback when the buffer is half full.
|
||||
* */
|
||||
if (adcp->state == ADC_COMPLETE) {
|
||||
ScopePerf perf(PE::AdcCallbackFastComplete);
|
||||
|
||||
fastAdc.invalidateSamplesCache();
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue