trace all the things
This commit is contained in:
parent
f52bdecb80
commit
d76670d946
|
@ -152,6 +152,8 @@ void PwmConfig::handleCycleStart() {
|
||||||
* @return Next time for signal toggle
|
* @return Next time for signal toggle
|
||||||
*/
|
*/
|
||||||
efitimeus_t PwmConfig::togglePwmState() {
|
efitimeus_t PwmConfig::togglePwmState() {
|
||||||
|
ScopePerf perf(PE::PwmConfigTogglePwmState);
|
||||||
|
|
||||||
#if DEBUG_PWM
|
#if DEBUG_PWM
|
||||||
scheduleMsg(&logger, "togglePwmState phaseIndex=%d iteration=%d", safe.phaseIndex, safe.iteration);
|
scheduleMsg(&logger, "togglePwmState phaseIndex=%d iteration=%d", safe.phaseIndex, safe.iteration);
|
||||||
scheduleMsg(&logger, "period=%.2f safe.period=%.2f", period, safe.periodNt);
|
scheduleMsg(&logger, "period=%.2f safe.period=%.2f", period, safe.periodNt);
|
||||||
|
@ -186,7 +188,10 @@ efitimeus_t PwmConfig::togglePwmState() {
|
||||||
cbStateIndex = 1;
|
cbStateIndex = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ScopePerf perf(PE::PwmConfigStateChangeCallback);
|
||||||
stateChangeCallback(cbStateIndex, arg);
|
stateChangeCallback(cbStateIndex, arg);
|
||||||
|
}
|
||||||
|
|
||||||
efitimeus_t nextSwitchTimeUs = getNextSwitchTimeUs(this);
|
efitimeus_t nextSwitchTimeUs = getNextSwitchTimeUs(this);
|
||||||
#if DEBUG_PWM
|
#if DEBUG_PWM
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "trigger_central.h"
|
#include "trigger_central.h"
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
#include "engine_math.h"
|
#include "engine_math.h"
|
||||||
|
#include "perf_trace.h"
|
||||||
|
|
||||||
#if EFI_PROD_CODE
|
#if EFI_PROD_CODE
|
||||||
#include "os_util.h"
|
#include "os_util.h"
|
||||||
|
@ -370,6 +371,9 @@ void initRpmCalculator(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
void scheduleByAngle(int rpm, scheduling_s *timer, angle_t angle,
|
void scheduleByAngle(int rpm, scheduling_s *timer, angle_t angle,
|
||||||
schfunc_t callback, void *param, RpmCalculator *calc DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
schfunc_t callback, void *param, RpmCalculator *calc DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
UNUSED(rpm);
|
UNUSED(rpm);
|
||||||
|
|
||||||
|
ScopePerf perf(PE::ScheduleByAngle);
|
||||||
|
|
||||||
efiAssertVoid(CUSTOM_ANGLE_NAN, !cisnan(angle), "NaN angle?");
|
efiAssertVoid(CUSTOM_ANGLE_NAN, !cisnan(angle), "NaN angle?");
|
||||||
efiAssertVoid(CUSTOM_ERR_6634, isValidRpm(rpm), "RPM check expected");
|
efiAssertVoid(CUSTOM_ERR_6634, isValidRpm(rpm), "RPM check expected");
|
||||||
float delayUs = calc->oneDegreeUs * angle;
|
float delayUs = calc->oneDegreeUs * angle;
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
|
|
||||||
|
#include "efifeatures.h"
|
||||||
#include "perf_trace.h"
|
#include "perf_trace.h"
|
||||||
#include "efitime.h"
|
#include "efitime.h"
|
||||||
#include "efifeatures.h"
|
|
||||||
#include "os_util.h"
|
#include "os_util.h"
|
||||||
|
|
||||||
#define TRACE_BUFFER_LENGTH 4096
|
#define TRACE_BUFFER_LENGTH 2048
|
||||||
|
|
||||||
enum class Phase : char
|
enum class EPhase : char
|
||||||
{
|
{
|
||||||
Start,
|
Start,
|
||||||
End,
|
End,
|
||||||
InstantThread,
|
InstantThread,
|
||||||
InstantGlobal,
|
InstantGlobal,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraceEntry
|
struct TraceEntry
|
||||||
{
|
{
|
||||||
PE Event;
|
PE Event;
|
||||||
Phase Type;
|
EPhase Phase;
|
||||||
uint8_t Data;
|
uint8_t Data;
|
||||||
uint8_t ThreadId;
|
uint8_t ThreadId;
|
||||||
uint32_t Timestamp;
|
uint32_t Timestamp;
|
||||||
|
@ -29,10 +28,15 @@ static_assert(sizeof(TraceEntry) == 8);
|
||||||
static TraceEntry s_traceBuffer[TRACE_BUFFER_LENGTH];
|
static TraceEntry s_traceBuffer[TRACE_BUFFER_LENGTH];
|
||||||
static size_t s_nextIdx = 0;
|
static size_t s_nextIdx = 0;
|
||||||
|
|
||||||
void perfEventImpl(PE event, Phase type, uint8_t data)
|
static bool s_isTracing = true;
|
||||||
|
|
||||||
|
void perfEventImpl(PE event, EPhase phase, uint8_t data)
|
||||||
{
|
{
|
||||||
if constexpr (!ENABLE_PERF_TRACE)
|
if constexpr (!ENABLE_PERF_TRACE) {
|
||||||
{
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s_isTracing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +49,9 @@ void perfEventImpl(PE event, Phase type, uint8_t data)
|
||||||
bool wasLocked = lockAnyContext();
|
bool wasLocked = lockAnyContext();
|
||||||
|
|
||||||
idx = s_nextIdx++;
|
idx = s_nextIdx++;
|
||||||
if (s_nextIdx >= TRACE_BUFFER_LENGTH)
|
if (s_nextIdx >= TRACE_BUFFER_LENGTH) {
|
||||||
{
|
|
||||||
s_nextIdx = 0;
|
s_nextIdx = 0;
|
||||||
|
s_isTracing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wasLocked) {
|
if (!wasLocked) {
|
||||||
|
@ -56,31 +60,33 @@ void perfEventImpl(PE event, Phase type, uint8_t data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can safely write data out of the lock, our spot is reserved
|
// We can safely write data out of the lock, our spot is reserved
|
||||||
TraceEntry& entry = s_traceBuffer[idx];
|
volatile TraceEntry& entry = s_traceBuffer[idx];
|
||||||
|
|
||||||
entry.Event = event;
|
entry.Event = event;
|
||||||
entry.Type = type;
|
entry.Phase = phase;
|
||||||
entry.ThreadId = 0; // TODO
|
entry.ThreadId = static_cast<uint8_t>(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
|
||||||
entry.Timestamp = timestamp;
|
entry.Timestamp = timestamp;
|
||||||
entry.Data = data;
|
entry.Data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void perfEventBegin(PE event, uint8_t data)
|
void perfEventBegin(PE event, uint8_t data) {
|
||||||
{
|
perfEventImpl(event, EPhase::Start, data);
|
||||||
perfEventImpl(event, Phase::Start, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void perfEventEnd(PE event, uint8_t data)
|
void perfEventEnd(PE event, uint8_t data) {
|
||||||
{
|
perfEventImpl(event, EPhase::End, data);
|
||||||
perfEventImpl(event, Phase::End, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void perfEventInstantThread(PE event, uint8_t data)
|
void perfEventInstantGlobal(PE event, uint8_t data) {
|
||||||
{
|
perfEventImpl(event, EPhase::InstantGlobal, data);
|
||||||
perfEventImpl(event, Phase::InstantThread, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void perfEventInstantGlobal(PE event, uint8_t data)
|
size_t perfTraceEnable() {
|
||||||
{
|
s_isTracing = true;
|
||||||
perfEventImpl(event, Phase::InstantGlobal, data);
|
|
||||||
|
return sizeof(s_traceBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t* getTraceBuffer() {
|
||||||
|
return reinterpret_cast<const uint8_t*>(s_traceBuffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
// Defines different events we want to trace. These can be an interval (begin -> end), or an
|
// 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
|
// instant. Instants can be global, or specific to one thread. You probably don't want to use
|
||||||
|
@ -44,12 +45,13 @@ enum class PE : uint8_t {
|
||||||
ScheduleByAngle,
|
ScheduleByAngle,
|
||||||
EventQueueExecuteCallback,
|
EventQueueExecuteCallback,
|
||||||
PwmGeneratorCallback,
|
PwmGeneratorCallback,
|
||||||
TunerStudioHandleCrcCommand
|
TunerStudioHandleCrcCommand,
|
||||||
|
PwmConfigTogglePwmState,
|
||||||
|
PwmConfigStateChangeCallback,
|
||||||
};
|
};
|
||||||
|
|
||||||
void perfEventBegin(PE event, uint8_t data);
|
void perfEventBegin(PE event, uint8_t data);
|
||||||
void perfEventEnd(PE event, uint8_t data);
|
void perfEventEnd(PE event, uint8_t data);
|
||||||
void perfEventInstantThread(PE event, uint8_t data);
|
|
||||||
void perfEventInstantGlobal(PE event, uint8_t data);
|
void perfEventInstantGlobal(PE event, uint8_t data);
|
||||||
|
|
||||||
inline void perfEventBegin(PE event) {
|
inline void perfEventBegin(PE event) {
|
||||||
|
@ -60,14 +62,14 @@ inline void perfEventEnd(PE event) {
|
||||||
perfEventEnd(event, 0);
|
perfEventEnd(event, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void perfEventInstantThread(PE event) {
|
|
||||||
perfEventInstantThread(event, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void perfEventInstantGlobal(PE event) {
|
inline void perfEventInstantGlobal(PE event) {
|
||||||
perfEventInstantGlobal(event, 0);
|
perfEventInstantGlobal(event, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable one buffer's worth of perf tracing, and retrieve the buffer size in bytes
|
||||||
|
size_t perfTraceEnable();
|
||||||
|
// Retrieve the trace buffer
|
||||||
|
const uint8_t* getTraceBuffer();
|
||||||
|
|
||||||
class ScopePerf
|
class ScopePerf
|
||||||
{
|
{
|
||||||
|
|
|
@ -206,7 +206,7 @@ void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
|
||||||
* intermediate callback when the buffer is half full.
|
* intermediate callback when the buffer is half full.
|
||||||
* */
|
* */
|
||||||
if (adcp->state == ADC_COMPLETE) {
|
if (adcp->state == ADC_COMPLETE) {
|
||||||
perfEventEnd(PE::AdcConversionFast, 0);
|
ScopePerf perf(PE::AdcCallbackFastComplete);
|
||||||
|
|
||||||
fastAdc.invalidateSamplesCache();
|
fastAdc.invalidateSamplesCache();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue