Skip to content

Commit

Permalink
AP_Logger: write formats out as required rather than at start of log
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbarker authored and loki077 committed Dec 17, 2024
1 parent 9a94246 commit 002506c
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 57 deletions.
114 changes: 75 additions & 39 deletions libraries/AP_Logger/AP_Logger_Backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void AP_Logger_Backend::start_new_log_reset_variables()
_startup_messagewriter->reset();
_front.backend_starting_new_log(this);
_log_file_size_bytes = 0;
_formats_written.clearall();
}

// We may need to make sure data is loggable before starting the
Expand All @@ -123,42 +124,6 @@ void AP_Logger_Backend::push_log_blocks() {
WriteMoreStartupMessages();
}

// returns true if all format messages have been written, and thus it is OK
// for other messages to go out to the log
bool AP_Logger_Backend::WriteBlockCheckStartupMessages()
{
#if APM_BUILD_TYPE(APM_BUILD_Replay)
return true;
#endif

if (_startup_messagewriter->fmt_done()) {
return true;
}

if (_writing_startup_messages) {
// we have been called by a messagewriter, so writing is OK
return true;
}

if (!_startup_messagewriter->finished() &&
!hal.scheduler->in_main_thread()) {
// only the main thread may write startup messages out
return false;
}

// we're not writing startup messages, so this must be some random
// caller hoping to write blocks out. Push out log blocks - we
// might end up clearing the buffer.....
push_log_blocks();

// even if we did finish writing startup messages, we can't
// permit any message to go in as its timestamp will be before
// any we wrote in. Time going backwards annoys log readers.

// sorry! currently busy writing out startup messages...
return false;
}

// source more messages from the startup message writer:
void AP_Logger_Backend::WriteMoreStartupMessages()
{
Expand Down Expand Up @@ -362,6 +327,23 @@ bool AP_Logger_Backend::StartNewLogOK() const
return true;
}

// validate that pBuffer looks like a message, extract message type.
// Returns false if this doesn't look like a valid message.
bool AP_Logger_Backend::message_type_from_block(const void *pBuffer, uint16_t size, LogMessages &type) const
{
if (size < 3) {
return false;
}
if (((uint8_t*)pBuffer)[0] != HEAD_BYTE1 ||
((uint8_t*)pBuffer)[1] != HEAD_BYTE2) {
// Not passed a message
INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
return false;
}
type = LogMessages(((uint8_t*)pBuffer)[2]);
return true;
}

#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
void AP_Logger_Backend::validate_WritePrioritisedBlock(const void *pBuffer,
uint16_t size)
Expand All @@ -380,11 +362,10 @@ void AP_Logger_Backend::validate_WritePrioritisedBlock(const void *pBuffer,
if (size < 3) {
AP_HAL::panic("Short prioritised block");
}
if (((uint8_t*)pBuffer)[0] != HEAD_BYTE1 ||
((uint8_t*)pBuffer)[1] != HEAD_BYTE2) {
LogMessages type;
if (!message_type_from_block(pBuffer, size, type)) {
AP_HAL::panic("Not passed a message");
}
const uint8_t type = ((uint8_t*)pBuffer)[2];
uint8_t type_len;
const char *name_src;
const struct LogStructure *s = _front.structure_for_msg_type(type);
Expand Down Expand Up @@ -412,6 +393,57 @@ void AP_Logger_Backend::validate_WritePrioritisedBlock(const void *pBuffer,
}
#endif

bool AP_Logger_Backend::emit_format_for_type(LogMessages a_type)
{
// linearly scan the formats structure to find the format for the type:
for (uint8_t i=0; i< num_types(); i++) {
const auto &s { structure(i) };
if (s == nullptr) {
continue;
}
if (s->msg_type != a_type) {
continue;
}
// found the relevant structure. Attempt to write it:
if (!Write_Format(s)) {
return false;
}
return true;
}
// didn't find the structure. That's probably bad...
INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);
return false;
}

bool AP_Logger_Backend::ensure_format_emitted(const void *pBuffer, uint16_t size)
{
#if APM_BUILD_TYPE(APM_BUILD_Replay)
// we trust that Replay will correctly emit formats as required
return true;
#endif

// extract the ID:
LogMessages type;
if (!message_type_from_block(pBuffer, size, type)) {
return false;
}
if (have_emitted_format_for_type(type)) {
return true;
}

// make sure the FMT message has gone out!
if (type == LOG_FORMAT_MSG) {
// kind of? Our caller is just about to emit this....
return true;
}
if (!have_emitted_format_for_type(LOG_FORMAT_MSG) &&
!emit_format_for_type(LOG_FORMAT_MSG)) {
return false;
}

return emit_format_for_type(type);
}

bool AP_Logger_Backend::WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical, bool writev_streaming)
{
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL && !APM_BUILD_TYPE(APM_BUILD_Replay)
Expand All @@ -434,6 +466,10 @@ bool AP_Logger_Backend::WritePrioritisedBlock(const void *pBuffer, uint16_t size
}
}

if (!ensure_format_emitted(pBuffer, size)) {
return false;
}

return _WritePrioritisedBlock(pBuffer, size, is_critical);
}

Expand Down
11 changes: 10 additions & 1 deletion libraries/AP_Logger/AP_Logger_Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <GCS_MAVLink/GCS_MAVLink.h>
#include <AP_Mission/AP_Mission.h>
#include <AP_Vehicle/ModeReason.h>
#include "LogStructure.h"

class LoggerMessageWriter_DFLogStart;

Expand Down Expand Up @@ -132,6 +133,9 @@ class AP_Logger_Backend
bool Write_Fence();
#endif
bool Write_Format(const struct LogStructure *structure);
bool have_emitted_format_for_type(LogMessages a_type) const {
return _formats_written.get(uint8_t(a_type));
}
bool Write_Message(const char *message);
bool Write_MessageF(const char *fmt, ...);
bool Write_Mission_Cmd(const AP_Mission &mission,
Expand Down Expand Up @@ -195,7 +199,6 @@ class AP_Logger_Backend
/*
read a block
*/
virtual bool WriteBlockCheckStartupMessages();
virtual void WriteMoreStartupMessages();
virtual void push_log_blocks();

Expand Down Expand Up @@ -262,6 +265,12 @@ class AP_Logger_Backend

void Write_AP_Logger_Stats_File(const struct df_stats &_stats);
void validate_WritePrioritisedBlock(const void *pBuffer, uint16_t size);

bool message_type_from_block(const void *pBuffer, uint16_t size, LogMessages &type) const;
bool ensure_format_emitted(const void *pBuffer, uint16_t size);
bool emit_format_for_type(LogMessages a_type);
Bitmask<256> _formats_written;

};

#endif // HAL_LOGGING_ENABLED
5 changes: 0 additions & 5 deletions libraries/AP_Logger/AP_Logger_Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,6 @@ bool AP_Logger_Block::_WritePrioritisedBlock(const void *pBuffer, uint16_t size,
return false;
}

if (!WriteBlockCheckStartupMessages()) {
_dropped++;
return false;
}

WITH_SEMAPHORE(write_sem);

const uint32_t space = writebuf.space();
Expand Down
5 changes: 0 additions & 5 deletions libraries/AP_Logger/AP_Logger_File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,6 @@ bool AP_Logger_File::_WritePrioritisedBlock(const void *pBuffer, uint16_t size,
{
WITH_SEMAPHORE(semaphore);

if (! WriteBlockCheckStartupMessages()) {
_dropped++;
return false;
}

#if APM_BUILD_TYPE(APM_BUILD_Replay)
if (AP::FS().write(_write_fd, pBuffer, size) != size) {
AP_HAL::panic("Short write");
Expand Down
5 changes: 0 additions & 5 deletions libraries/AP_Logger/AP_Logger_MAVLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,6 @@ bool AP_Logger_MAVLink::_WritePrioritisedBlock(const void *pBuffer, uint16_t siz
return false;
}

if (! WriteBlockCheckStartupMessages()) {
semaphore.give();
return false;
}

if (bufferspace_available() < size) {
if (_startup_messagewriter->finished()) {
// do not count the startup packets as being dropped...
Expand Down
6 changes: 5 additions & 1 deletion libraries/AP_Logger/LogFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ bool AP_Logger_Backend::Write_Format(const struct LogStructure *s)
{
struct log_Format pkt;
Fill_Format(s, pkt);
return WriteCriticalBlock(&pkt, sizeof(pkt));
if (!WriteCriticalBlock(&pkt, sizeof(pkt))) {
return false;
}
_formats_written.set(s->msg_type);
return true;
}

/*
Expand Down
7 changes: 6 additions & 1 deletion libraries/AP_Logger/LoggerMessageWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ void LoggerMessageWriter_DFLogStart::process()
case Stage::FORMATS:
// write log formats so the log is self-describing
while (next_format_to_send < _logger_backend->num_types()) {
if (!_logger_backend->Write_Format(_logger_backend->structure(next_format_to_send))) {
const auto &s { _logger_backend->structure(next_format_to_send) };
if (_logger_backend->have_emitted_format_for_type((LogMessages)s->msg_type)) {
next_format_to_send++;
continue;
}
if (!_logger_backend->Write_Format(s)) {
return; // call me again!
}
next_format_to_send++;
Expand Down

0 comments on commit 002506c

Please sign in to comment.