mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-24 08:45:36 +03:00
Add resume event to allow clean log decoding, add documentation
This commit is contained in:
parent
01632998a3
commit
53860e461c
5 changed files with 86 additions and 35 deletions
|
@ -256,6 +256,7 @@ typedef enum BlackboxState {
|
|||
BLACKBOX_STATE_SEND_GPS_G_HEADER,
|
||||
BLACKBOX_STATE_SEND_SLOW_HEADER,
|
||||
BLACKBOX_STATE_SEND_SYSINFO,
|
||||
BLACKBOX_STATE_PAUSED,
|
||||
BLACKBOX_STATE_RUNNING,
|
||||
BLACKBOX_STATE_SHUTTING_DOWN
|
||||
} BlackboxState;
|
||||
|
@ -456,9 +457,6 @@ static void blackboxSetState(BlackboxState newState)
|
|||
xmitState.headerIndex = 0;
|
||||
break;
|
||||
case BLACKBOX_STATE_RUNNING:
|
||||
blackboxIteration = 0;
|
||||
blackboxPFrameIndex = 0;
|
||||
blackboxIFrameIndex = 0;
|
||||
blackboxSlowFrameIterationTimer = SLOW_FRAME_INTERVAL; //Force a slow frame to be written on the first iteration
|
||||
break;
|
||||
case BLACKBOX_STATE_SHUTTING_DOWN:
|
||||
|
@ -773,7 +771,6 @@ static void validateBlackboxConfig()
|
|||
*/
|
||||
void startBlackbox(void)
|
||||
{
|
||||
blackboxModeActivationConditionPresent = isModeActivationConditionPresent(currentProfile->modeActivationConditions, BOXBLACKBOX);
|
||||
if (blackboxState == BLACKBOX_STATE_STOPPED) {
|
||||
validateBlackboxConfig();
|
||||
|
||||
|
@ -798,6 +795,12 @@ void startBlackbox(void)
|
|||
* cache those now.
|
||||
*/
|
||||
blackboxBuildConditionCache();
|
||||
|
||||
blackboxModeActivationConditionPresent = isModeActivationConditionPresent(currentProfile->modeActivationConditions, BOXBLACKBOX);
|
||||
|
||||
blackboxIteration = 0;
|
||||
blackboxPFrameIndex = 0;
|
||||
blackboxIFrameIndex = 0;
|
||||
|
||||
/*
|
||||
* Record the beeper's current idea of the last arming beep time, so that we can detect it changing when
|
||||
|
@ -814,7 +817,7 @@ void startBlackbox(void)
|
|||
*/
|
||||
void finishBlackbox(void)
|
||||
{
|
||||
if (blackboxState == BLACKBOX_STATE_RUNNING) {
|
||||
if (blackboxState == BLACKBOX_STATE_RUNNING || blackboxState == BLACKBOX_STATE_PAUSED) {
|
||||
blackboxLogEvent(FLIGHT_LOG_EVENT_LOG_END, NULL);
|
||||
|
||||
blackboxSetState(BLACKBOX_STATE_SHUTTING_DOWN);
|
||||
|
@ -1102,7 +1105,8 @@ static bool blackboxWriteSysinfo()
|
|||
*/
|
||||
void blackboxLogEvent(FlightLogEvent event, flightLogEventData_t *data)
|
||||
{
|
||||
if (blackboxState != BLACKBOX_STATE_RUNNING) {
|
||||
// Only allow events to be logged after headers have been written
|
||||
if (!(blackboxState == BLACKBOX_STATE_RUNNING || blackboxState == BLACKBOX_STATE_PAUSED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1144,6 +1148,10 @@ void blackboxLogEvent(FlightLogEvent event, flightLogEventData_t *data)
|
|||
blackboxWriteSignedVB(data->inflightAdjustment.newValue);
|
||||
}
|
||||
break;
|
||||
case FLIGHT_LOG_EVENT_LOGGING_RESUME:
|
||||
blackboxWriteUnsignedVB(data->loggingResume.logIteration);
|
||||
blackboxWriteUnsignedVB(data->loggingResume.currentTime);
|
||||
break;
|
||||
case FLIGHT_LOG_EVENT_LOG_END:
|
||||
blackboxPrint("End of log");
|
||||
blackboxWrite(0);
|
||||
|
@ -1178,34 +1186,51 @@ static bool blackboxShouldLogPFrame(uint32_t pFrameIndex)
|
|||
return (pFrameIndex + masterConfig.blackbox_rate_num - 1) % masterConfig.blackbox_rate_denom < masterConfig.blackbox_rate_num;
|
||||
}
|
||||
|
||||
static bool blackboxShouldLogIFrame() {
|
||||
return blackboxPFrameIndex == 0;
|
||||
}
|
||||
|
||||
// Called once every FC loop in order to keep track of how many FC loop iterations have passed
|
||||
static void blackboxAdvanceIterationTimers()
|
||||
{
|
||||
blackboxSlowFrameIterationTimer++;
|
||||
blackboxIteration++;
|
||||
blackboxPFrameIndex++;
|
||||
|
||||
if (blackboxPFrameIndex == BLACKBOX_I_INTERVAL) {
|
||||
blackboxPFrameIndex = 0;
|
||||
blackboxIFrameIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Called once every FC loop in order to log the current state
|
||||
static void blackboxLogIteration(bool writeFrames)
|
||||
static void blackboxLogIteration()
|
||||
{
|
||||
// Write a keyframe every BLACKBOX_I_INTERVAL frames so we can resynchronise upon missing frames
|
||||
if (blackboxPFrameIndex == 0) {
|
||||
if (blackboxShouldLogIFrame()) {
|
||||
/*
|
||||
* Don't log a slow frame if the slow data didn't change ("I" frames are already large enough without adding
|
||||
* an additional item to write at the same time)
|
||||
*/
|
||||
if (writeFrames) {
|
||||
writeSlowFrameIfNeeded(false);
|
||||
loadMainState();
|
||||
writeIntraframe();
|
||||
}
|
||||
writeSlowFrameIfNeeded(false);
|
||||
|
||||
loadMainState();
|
||||
writeIntraframe();
|
||||
} else {
|
||||
blackboxCheckAndLogArmingBeep();
|
||||
|
||||
if (blackboxShouldLogPFrame(blackboxPFrameIndex) && writeFrames) {
|
||||
/*
|
||||
if (blackboxShouldLogPFrame(blackboxPFrameIndex)) {
|
||||
/*
|
||||
* We assume that slow frames are only interesting in that they aid the interpretation of the main data stream.
|
||||
* So only log slow frames during loop iterations where we log a main frame.
|
||||
*/
|
||||
writeSlowFrameIfNeeded(true);
|
||||
|
||||
loadMainState();
|
||||
writeInterframe();
|
||||
}
|
||||
#ifdef GPS
|
||||
if (feature(FEATURE_GPS) && writeFrames) {
|
||||
if (feature(FEATURE_GPS)) {
|
||||
/*
|
||||
* If the GPS home point has been updated, or every 128 intraframes (~10 seconds), write the
|
||||
* GPS home position.
|
||||
|
@ -1229,15 +1254,6 @@ static void blackboxLogIteration(bool writeFrames)
|
|||
|
||||
//Flush every iteration so that our runtime variance is minimized
|
||||
blackboxDeviceFlush();
|
||||
|
||||
blackboxSlowFrameIterationTimer++;
|
||||
blackboxIteration++;
|
||||
blackboxPFrameIndex++;
|
||||
|
||||
if (blackboxPFrameIndex == BLACKBOX_I_INTERVAL) {
|
||||
blackboxPFrameIndex = 0;
|
||||
blackboxIFrameIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1308,18 +1324,33 @@ void handleBlackbox(void)
|
|||
blackboxSetState(BLACKBOX_STATE_RUNNING);
|
||||
}
|
||||
break;
|
||||
case BLACKBOX_STATE_PAUSED:
|
||||
// Only allow resume to occur during an I-frame iteration, so that we have an "I" base to work from
|
||||
if (IS_RC_MODE_ACTIVE(BOXBLACKBOX) && blackboxShouldLogIFrame()) {
|
||||
// Write a log entry so the decoder is aware that our large time/iteration skip is intended
|
||||
flightLogEvent_loggingResume_t resume;
|
||||
|
||||
resume.logIteration = blackboxIteration;
|
||||
resume.currentTime = currentTime;
|
||||
|
||||
blackboxLogEvent(FLIGHT_LOG_EVENT_LOGGING_RESUME, (flightLogEventData_t *) &resume);
|
||||
blackboxSetState(BLACKBOX_STATE_RUNNING);
|
||||
|
||||
blackboxLogIteration();
|
||||
}
|
||||
|
||||
// Keep the logging timers ticking so our log iteration continues to advance
|
||||
blackboxAdvanceIterationTimers();
|
||||
break;
|
||||
case BLACKBOX_STATE_RUNNING:
|
||||
// On entry to this state, blackboxIteration, blackboxPFrameIndex and blackboxIFrameIndex are reset to 0
|
||||
if (blackboxModeActivationConditionPresent) {
|
||||
if (IS_RC_MODE_ACTIVE(BOXBLACKBOX)) {
|
||||
blackboxLogIteration(true);
|
||||
} else {
|
||||
// Log only first I frame
|
||||
blackboxLogIteration(blackboxIteration == 0);
|
||||
}
|
||||
if (blackboxModeActivationConditionPresent && !IS_RC_MODE_ACTIVE(BOXBLACKBOX)) {
|
||||
blackboxSetState(BLACKBOX_STATE_PAUSED);
|
||||
} else {
|
||||
blackboxLogIteration(true);
|
||||
blackboxLogIteration();
|
||||
}
|
||||
|
||||
blackboxAdvanceIterationTimers();
|
||||
break;
|
||||
case BLACKBOX_STATE_SHUTTING_DOWN:
|
||||
//On entry of this state, startTime is set and a flush is performed
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue