LCOV - code coverage report
Current view: top level - AP_Logger - AP_Logger_Backend.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 21 27 77.8 %
Date: 2026-09-09 11:02:08 Functions: 9 12 75.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "AP_Logger_config.h"
       4             : 
       5             : #if HAL_LOGGING_ENABLED
       6             : 
       7             : #include <AP_Common/Bitmask.h>
       8             : #include <AP_Param/AP_Param.h>
       9             : #include <GCS_MAVLink/GCS_MAVLink.h>
      10             : #include <AP_Mission/AP_Mission.h>
      11             : #include <AP_Vehicle/ModeReason.h>
      12             : #include "LogStructure.h"
      13             : 
      14             : class LoggerMessageWriter_DFLogStart;
      15             : 
      16             : // class to handle rate limiting of log messages
      17             : class AP_Logger_RateLimiter
      18             : {
      19             : public:
      20             :     AP_Logger_RateLimiter(const class AP_Logger &_front, const AP_Float &_limit_hz, const AP_Float &_disarm_limit_hz);
      21             : 
      22             :     // return true if message passes the rate limit test
      23             :     bool should_log(uint8_t msgid, bool writev_streaming);
      24             :     bool should_log_streaming(uint8_t msgid, float rate_hz);
      25             : 
      26             : private:
      27             :     const AP_Logger &front;
      28             :     const AP_Float &rate_limit_hz;
      29             :     const AP_Float &disarm_rate_limit_hz;
      30             : 
      31             :     // time in ms we last sent this message
      32             :     uint16_t last_send_ms[256];
      33             : 
      34             :     // the last scheduler counter when we sent a msg.  this allows us
      35             :     // to detect when we are sending a multi-instance message
      36             :     uint16_t last_sched_count[256];
      37             : 
      38             :     // mask of message types that are not streaming. This is a cache
      39             :     // to avoid costly calls to structure_for_msg_type
      40             :     Bitmask<256> not_streaming;
      41             : 
      42             :     // result of last decision for a message. Used for multi-instance
      43             :     // handling
      44             :     Bitmask<256> last_return;
      45             : };
      46             : 
      47             : class AP_Logger_Backend
      48             : {
      49             : 
      50             : public:
      51             :     FUNCTOR_TYPEDEF(vehicle_startup_message_Writer, void);
      52             : 
      53             :     AP_Logger_Backend(AP_Logger &front,
      54             :                       class LoggerMessageWriter_DFLogStart *writer);
      55             : 
      56             :     vehicle_startup_message_Writer vehicle_message_writer() const;
      57             : 
      58             :     virtual bool CardInserted(void) const = 0;
      59             : 
      60             :     // erase handling
      61             :     virtual void EraseAll() = 0;
      62             : 
      63             :     /* Write a block of data at current offset */
      64   173548673 :     bool WriteBlock(const void *pBuffer, uint16_t size) {
      65   173548673 :         return WritePrioritisedBlock(pBuffer, size, false);
      66             :     }
      67             : 
      68     7176441 :     bool WriteCriticalBlock(const void *pBuffer, uint16_t size) {
      69     7176441 :         return WritePrioritisedBlock(pBuffer, size, true);
      70             :     }
      71             : 
      72             :     bool WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical, bool writev_streaming=false);
      73             : 
      74             :     // high level interface, indexed by the position in the list of logs
      75             :     virtual uint16_t find_last_log() = 0;
      76             :     virtual void get_log_boundaries(uint16_t list_entry, uint32_t & start_page, uint32_t & end_page) = 0;
      77             :     virtual void get_log_info(uint16_t list_entry, uint32_t &size, uint32_t &time_utc) = 0;
      78             :     virtual int16_t get_log_data(uint16_t list_entry, uint16_t page, uint32_t offset, uint16_t len, uint8_t *data) = 0;
      79             :     virtual void end_log_transfer() = 0;
      80             :     virtual uint16_t get_num_logs() = 0;
      81             :     virtual uint16_t find_oldest_log();
      82             : 
      83             :     virtual bool logging_started(void) const = 0;
      84             : 
      85             :     virtual void Init() = 0;
      86             : 
      87             :     virtual uint32_t bufferspace_available() = 0;
      88             : 
      89             :     virtual void PrepForArming();
      90             : 
      91           0 :     virtual void start_new_log() { }
      92             : 
      93             :     /* stop logging - close output files etc etc.
      94             :      *
      95             :      * note that this doesn't stop logging from starting up again
      96             :      * immediately - e.g. AP_Logger_MAVLink might get another start
      97             :      * packet from a client.
      98             :      */
      99             :     virtual void stop_logging(void) = 0;
     100             :     // asynchronously stop logging, status can be determined through logging_started()
     101          15 :     virtual void stop_logging_async(void) { stop_logging(); }
     102             : 
     103             :     void Fill_Format(const struct LogStructure *structure, struct log_Format &pkt);
     104             :     void Fill_Format_Units(const struct LogStructure *s, struct log_Format_Units &pkt);
     105             : 
     106             : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL || CONFIG_HAL_BOARD == HAL_BOARD_LINUX
     107             :     // currently only AP_Logger_File support this:
     108           0 :     virtual void flush(void) { }
     109             : #endif
     110             : 
     111             :      // for Logger_MAVlink
     112           0 :     virtual void remote_log_block_status_msg(const class GCS_MAVLINK &link,
     113           0 :                                              const mavlink_message_t &msg) { }
     114             :     // end for Logger_MAVlink
     115             : 
     116             :    virtual void periodic_tasks();
     117             : 
     118             :     uint8_t num_types() const;
     119             :     const struct LogStructure *structure(uint8_t structure) const;
     120             : 
     121             :     uint8_t num_units() const;
     122             :     const struct UnitStructure *unit(uint8_t unit) const;
     123             : 
     124             :     uint8_t num_multipliers() const;
     125             :     const struct MultiplierStructure *multiplier(uint8_t multiplier) const;
     126             : 
     127             :     bool Write_RTC();
     128             : 
     129             :     bool Write_EntireMission();
     130             :     bool Write_RallyPoint(uint8_t total,
     131             :                           uint8_t sequence,
     132             :                           const class RallyLocation &rally_point);
     133             :     bool Write_Rally();
     134             : #if HAL_LOGGER_FENCE_ENABLED
     135             :     bool Write_FencePoint(uint8_t total, uint8_t sequence, const class AC_PolyFenceItem &fence_point);
     136             :     bool Write_Fence();
     137             : #endif
     138             :     bool Write_Format(const struct LogStructure *structure);
     139   101302690 :     bool have_emitted_format_for_type(LogMessages a_type) const {
     140   101302690 :         return _formats_written.get(uint8_t(a_type));
     141             :     }
     142             :     bool Write_Message(const char *message);
     143             :     bool Write_MessageF(const char *fmt, ...);
     144             :     bool Write_MessageChunk(uint8_t id, const char *messagechunk, uint8_t chunk_seq);
     145             :     bool Write_Mission_Cmd(const AP_Mission &mission,
     146             :                            const AP_Mission::Mission_Command &cmd,
     147             :                            LogMessages id);
     148             :     bool Write_Mode(uint8_t mode, const ModeReason reason);
     149             :     bool Write_Parameter(const char *name, float value, float default_val);
     150             :     bool Write_Parameter(const AP_Param *ap,
     151             :                              const AP_Param::ParamToken &token,
     152             :                              enum ap_var_type type,
     153             :                              float default_val);
     154             :     bool Write_VER();
     155             : 
     156     1116947 :     uint32_t num_dropped(void) const {
     157     1116947 :         return _dropped;
     158             :     }
     159             : 
     160             :     /*
     161             :      * Write support
     162             :      */
     163             :     // write a FMT message out (if it hasn't been done already).
     164             :     // Returns true if the FMT message has ever been written.
     165             :     bool Write_Emit_FMT(uint8_t msg_type);
     166             : 
     167             :     // output a FMT message if not already done so
     168             :     void Safe_Write_Emit_FMT(uint8_t msg_type);
     169             : 
     170             :     // write a log message out to the log of msg_type type, with
     171             :     // values contained in arg_list:
     172             :     bool Write(uint8_t msg_type, va_list arg_list, bool is_critical=false, bool is_streaming=false);
     173             : 
     174             :     // these methods are used for mavlink system status and arming checks
     175             :     virtual bool logging_enabled() const;
     176             :     virtual bool logging_failed() const = 0;
     177             : 
     178             :     // We may need to make sure data is loggable before starting the
     179             :     // EKF; when allow_start_ekf we should be able to log that data
     180             :     bool allow_start_ekf() const;
     181             : 
     182             :     virtual void vehicle_was_disarmed();
     183             : 
     184             :     bool Write_Unit(const struct UnitStructure *s);
     185             :     bool Write_Multiplier(const struct MultiplierStructure *s);
     186             :     bool Write_Format_Units(const struct LogStructure *structure);
     187             : 
     188       23835 :     virtual void io_timer(void) {}
     189             : 
     190             : protected:
     191             : 
     192             :     AP_Logger &_front;
     193             : 
     194             :     virtual void periodic_10Hz(const uint32_t now);
     195             :     virtual void periodic_1Hz();
     196             :     virtual void periodic_fullrate();
     197             : 
     198             :     bool ShouldLog(bool is_critical);
     199             :     virtual bool WritesOK() const = 0;
     200             :     virtual bool StartNewLogOK() const;
     201             : 
     202             :     // called by PrepForArming to actually start logging
     203           5 :     virtual void PrepForArming_start_logging(void) {
     204           5 :         start_new_log();
     205           5 :     }
     206             : 
     207             :     /*
     208             :       read a block
     209             :     */
     210             :     virtual void WriteMoreStartupMessages();
     211             :     virtual void push_log_blocks();
     212             : 
     213             :     LoggerMessageWriter_DFLogStart *_startup_messagewriter;
     214             :     bool _writing_startup_messages;
     215             : 
     216             :     uint16_t _cached_oldest_log;
     217             : 
     218             :     uint32_t _dropped;
     219             :     // should we rotate when we next stop logging
     220             :     bool _rotate_pending;
     221             : 
     222             :     // must be called when a new log is being started:
     223             :     virtual void start_new_log_reset_variables();
     224             :     // convert between log numbering in storage and normalized numbering
     225             :     uint16_t log_num_from_list_entry(const uint16_t list_entry);
     226             : 
     227   178188677 :     uint32_t critical_message_reserved_space(uint32_t bufsize) const {
     228             :         // possibly make this a proportional to buffer size?
     229   178188677 :         uint32_t ret = 1024;
     230   178188677 :         if (ret > bufsize) {
     231             :             // in this case you will only get critical messages
     232           0 :             ret = bufsize;
     233             :         }
     234   178188677 :         return ret;
     235             :     };
     236     3454259 :     uint32_t non_messagewriter_message_reserved_space(uint32_t bufsize) const {
     237             :         // possibly make this a proportional to buffer size?
     238     3454259 :         uint32_t ret = 4096;
     239     3454259 :         if (ret >= bufsize) {
     240             :             // need to allow messages out from the messagewriters.  In
     241             :             // this case while you have a messagewriter you won't get
     242             :             // any other messages.  This should be a corner case!
     243           0 :             ret = 0;
     244             :         }
     245     3454259 :         return ret;
     246             :     };
     247             : 
     248             :     virtual bool _WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical) = 0;
     249             : 
     250             :     bool _initialised;
     251             : 
     252             :     void df_stats_gather(uint16_t bytes_written, uint32_t space_remaining);
     253             :     void df_stats_log();
     254             :     void df_stats_clear();
     255             : 
     256             :     AP_Logger_RateLimiter *rate_limiter;
     257             : 
     258             : private:
     259             :     // statistics support
     260             :     struct df_stats {
     261             :         uint16_t blocks;
     262             :         uint32_t bytes;
     263             :         uint32_t buf_space_min;
     264             :         uint32_t buf_space_max;
     265             :         uint32_t buf_space_sigma;
     266             :     };
     267             :     struct df_stats stats;
     268             : 
     269             :     uint32_t _last_periodic_1Hz;
     270             :     uint32_t _last_periodic_10Hz;
     271             :     bool have_logged_armed;
     272             : 
     273             :     void Write_AP_Logger_Stats_File(const struct df_stats &_stats);
     274             :     void validate_WritePrioritisedBlock(const void *pBuffer, uint16_t size);
     275             : 
     276             :     bool message_type_from_block(const void *pBuffer, uint16_t size, LogMessages &type) const;
     277             :     bool ensure_format_emitted(const void *pBuffer, uint16_t size);
     278             :     bool emit_format_for_type(LogMessages a_type);
     279             :     Bitmask<256> _formats_written;
     280             : 
     281             :     uint8_t msg_id;  // the ID of the next MSG message that will be logged
     282             : };
     283             : 
     284             : #endif  // HAL_LOGGING_ENABLED

Generated by: LCOV version 1.14