2016-02-17 21:25:53 -04:00
|
|
|
#pragma once
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2023-09-05 10:08:30 -03:00
|
|
|
#include "AP_Logger_config.h"
|
|
|
|
|
|
|
|
#if HAL_LOGGING_ENABLED
|
|
|
|
|
2022-07-14 02:48:35 -03:00
|
|
|
#include <AP_Common/Bitmask.h>
|
2023-06-23 21:16:04 -03:00
|
|
|
#include <AP_Param/AP_Param.h>
|
|
|
|
#include <GCS_MAVLink/GCS_MAVLink.h>
|
|
|
|
#include <AP_Mission/AP_Mission.h>
|
|
|
|
#include <AP_Vehicle/ModeReason.h>
|
2022-07-14 02:48:35 -03:00
|
|
|
|
2019-01-18 00:23:42 -04:00
|
|
|
class LoggerMessageWriter_DFLogStart;
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2021-07-27 05:47:45 -03:00
|
|
|
// class to handle rate limiting of log messages
|
|
|
|
class AP_Logger_RateLimiter
|
|
|
|
{
|
|
|
|
public:
|
2023-06-23 21:16:04 -03:00
|
|
|
AP_Logger_RateLimiter(const class AP_Logger &_front, const AP_Float &_limit_hz, const AP_Float &_disarm_limit_hz);
|
2021-07-27 05:47:45 -03:00
|
|
|
|
|
|
|
// return true if message passes the rate limit test
|
2021-08-17 06:56:54 -03:00
|
|
|
bool should_log(uint8_t msgid, bool writev_streaming);
|
2023-04-11 07:16:41 -03:00
|
|
|
bool should_log_streaming(uint8_t msgid, float rate_hz);
|
2021-07-27 05:47:45 -03:00
|
|
|
|
|
|
|
private:
|
|
|
|
const AP_Logger &front;
|
|
|
|
const AP_Float &rate_limit_hz;
|
2023-04-11 07:16:41 -03:00
|
|
|
const AP_Float &disarm_rate_limit_hz;
|
2021-07-27 05:47:45 -03:00
|
|
|
|
|
|
|
// time in ms we last sent this message
|
|
|
|
uint16_t last_send_ms[256];
|
|
|
|
|
2021-07-28 03:39:59 -03:00
|
|
|
// the last scheduler counter when we sent a msg. this allows us
|
|
|
|
// to detect when we are sending a multi-instance message
|
|
|
|
uint16_t last_sched_count[256];
|
|
|
|
|
|
|
|
// mask of message types that are not streaming. This is a cache
|
|
|
|
// to avoid costly calls to structure_for_msg_type
|
2021-07-27 05:47:45 -03:00
|
|
|
Bitmask<256> not_streaming;
|
2021-07-28 03:39:59 -03:00
|
|
|
|
|
|
|
// result of last decision for a message. Used for multi-instance
|
|
|
|
// handling
|
|
|
|
Bitmask<256> last_return;
|
2021-07-27 05:47:45 -03:00
|
|
|
};
|
|
|
|
|
2019-01-18 00:23:42 -04:00
|
|
|
class AP_Logger_Backend
|
2015-06-25 10:53:20 -03:00
|
|
|
{
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2015-06-25 10:53:20 -03:00
|
|
|
public:
|
2019-01-18 00:24:08 -04:00
|
|
|
FUNCTOR_TYPEDEF(vehicle_startup_message_Writer, void);
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2019-01-18 00:23:42 -04:00
|
|
|
AP_Logger_Backend(AP_Logger &front,
|
|
|
|
class LoggerMessageWriter_DFLogStart *writer);
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2021-02-01 12:26:29 -04:00
|
|
|
vehicle_startup_message_Writer vehicle_message_writer() const;
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2017-06-14 22:19:54 -03:00
|
|
|
virtual bool CardInserted(void) const = 0;
|
2015-06-25 10:53:20 -03:00
|
|
|
|
|
|
|
// erase handling
|
|
|
|
virtual void EraseAll() = 0;
|
|
|
|
|
|
|
|
/* Write a block of data at current offset */
|
2015-08-06 09:18:28 -03:00
|
|
|
bool WriteBlock(const void *pBuffer, uint16_t size) {
|
|
|
|
return WritePrioritisedBlock(pBuffer, size, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WriteCriticalBlock(const void *pBuffer, uint16_t size) {
|
|
|
|
return WritePrioritisedBlock(pBuffer, size, true);
|
|
|
|
}
|
|
|
|
|
2021-08-17 06:56:54 -03:00
|
|
|
bool WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical, bool writev_streaming=false);
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
// high level interface, indexed by the position in the list of logs
|
2015-10-20 07:32:31 -03:00
|
|
|
virtual uint16_t find_last_log() = 0;
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual void get_log_boundaries(uint16_t list_entry, uint32_t & start_page, uint32_t & end_page) = 0;
|
|
|
|
virtual void get_log_info(uint16_t list_entry, uint32_t &size, uint32_t &time_utc) = 0;
|
|
|
|
virtual int16_t get_log_data(uint16_t list_entry, uint16_t page, uint32_t offset, uint16_t len, uint8_t *data) = 0;
|
2015-10-20 07:32:31 -03:00
|
|
|
virtual uint16_t get_num_logs() = 0;
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual uint16_t find_oldest_log();
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2017-07-06 22:34:31 -03:00
|
|
|
virtual bool logging_started(void) const = 0;
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual void Init() = 0;
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2016-07-30 15:13:12 -03:00
|
|
|
virtual uint32_t bufferspace_available() = 0;
|
2015-08-06 09:18:28 -03:00
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual void PrepForArming();
|
2017-07-06 22:28:42 -03:00
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual void start_new_log() { }
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2016-04-22 10:33:40 -03:00
|
|
|
/* stop logging - close output files etc etc.
|
|
|
|
*
|
|
|
|
* note that this doesn't stop logging from starting up again
|
2019-01-18 00:23:42 -04:00
|
|
|
* immediately - e.g. AP_Logger_MAVLink might get another start
|
2016-04-22 10:33:40 -03:00
|
|
|
* packet from a client.
|
|
|
|
*/
|
|
|
|
virtual void stop_logging(void) = 0;
|
2020-09-10 16:57:40 -03:00
|
|
|
// asynchronously stop logging, status can be determined through logging_started()
|
|
|
|
virtual void stop_logging_async(void) { stop_logging(); }
|
2016-04-22 10:33:40 -03:00
|
|
|
|
2019-01-18 00:24:08 -04:00
|
|
|
void Fill_Format(const struct LogStructure *structure, struct log_Format &pkt);
|
|
|
|
void Fill_Format_Units(const struct LogStructure *s, struct log_Format_Units &pkt);
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2015-06-18 22:57:01 -03:00
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL || CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
2019-01-18 00:23:42 -04:00
|
|
|
// currently only AP_Logger_File support this:
|
2015-06-18 22:57:01 -03:00
|
|
|
virtual void flush(void) { }
|
|
|
|
#endif
|
|
|
|
|
2019-02-11 04:38:01 -04:00
|
|
|
// for Logger_MAVlink
|
2023-06-23 21:16:04 -03:00
|
|
|
virtual void remote_log_block_status_msg(const class GCS_MAVLINK &link,
|
2019-04-30 07:22:48 -03:00
|
|
|
const mavlink_message_t &msg) { }
|
2019-02-11 04:38:01 -04:00
|
|
|
// end for Logger_MAVlink
|
2015-11-10 02:34:31 -04:00
|
|
|
|
2015-11-09 18:14:22 -04:00
|
|
|
virtual void periodic_tasks();
|
|
|
|
|
|
|
|
uint8_t num_types() const;
|
|
|
|
const struct LogStructure *structure(uint8_t structure) const;
|
2015-08-06 09:18:28 -03:00
|
|
|
|
2015-12-07 20:51:46 -04:00
|
|
|
uint8_t num_units() const;
|
|
|
|
const struct UnitStructure *unit(uint8_t unit) const;
|
|
|
|
|
|
|
|
uint8_t num_multipliers() const;
|
|
|
|
const struct MultiplierStructure *multiplier(uint8_t multiplier) const;
|
|
|
|
|
2020-04-13 01:20:30 -03:00
|
|
|
bool Write_EntireMission();
|
2018-12-29 00:01:46 -04:00
|
|
|
bool Write_RallyPoint(uint8_t total,
|
|
|
|
uint8_t sequence,
|
2022-07-14 02:48:35 -03:00
|
|
|
const class RallyLocation &rally_point);
|
2020-04-13 01:20:30 -03:00
|
|
|
bool Write_Rally();
|
2021-11-13 09:58:48 -04:00
|
|
|
#if HAL_LOGGER_FENCE_ENABLED
|
2023-06-23 21:03:25 -03:00
|
|
|
bool Write_FencePoint(uint8_t total, uint8_t sequence, const class AC_PolyFenceItem &fence_point);
|
2021-11-13 09:58:48 -04:00
|
|
|
bool Write_Fence();
|
|
|
|
#endif
|
2019-01-18 00:24:08 -04:00
|
|
|
bool Write_Format(const struct LogStructure *structure);
|
|
|
|
bool Write_Message(const char *message);
|
|
|
|
bool Write_MessageF(const char *fmt, ...);
|
|
|
|
bool Write_Mission_Cmd(const AP_Mission &mission,
|
2015-11-09 18:14:22 -04:00
|
|
|
const AP_Mission::Mission_Command &cmd);
|
2020-09-23 22:25:01 -03:00
|
|
|
bool Write_Mode(uint8_t mode, const ModeReason reason);
|
2022-06-13 16:02:15 -03:00
|
|
|
bool Write_Parameter(const char *name, float value, float default_val);
|
2019-01-18 00:24:08 -04:00
|
|
|
bool Write_Parameter(const AP_Param *ap,
|
2015-11-09 18:14:22 -04:00
|
|
|
const AP_Param::ParamToken &token,
|
2022-06-13 16:02:15 -03:00
|
|
|
enum ap_var_type type,
|
|
|
|
float default_val);
|
2022-02-01 20:46:06 -04:00
|
|
|
bool Write_VER();
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2016-04-21 03:11:21 -03:00
|
|
|
uint32_t num_dropped(void) const {
|
|
|
|
return _dropped;
|
|
|
|
}
|
2016-04-20 02:07:48 -03:00
|
|
|
|
|
|
|
/*
|
2019-01-18 00:24:08 -04:00
|
|
|
* Write support
|
2016-04-20 02:07:48 -03:00
|
|
|
*/
|
|
|
|
// write a FMT message out (if it hasn't been done already).
|
|
|
|
// Returns true if the FMT message has ever been written.
|
2019-01-18 00:24:08 -04:00
|
|
|
bool Write_Emit_FMT(uint8_t msg_type);
|
2016-04-20 02:07:48 -03:00
|
|
|
|
|
|
|
// write a log message out to the log of msg_type type, with
|
|
|
|
// values contained in arg_list:
|
2021-07-27 05:47:45 -03:00
|
|
|
bool Write(uint8_t msg_type, va_list arg_list, bool is_critical=false, bool is_streaming=false);
|
2016-04-20 02:07:48 -03:00
|
|
|
|
2016-07-07 04:12:27 -03:00
|
|
|
// these methods are used when reporting system status over mavlink
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual bool logging_enabled() const;
|
2016-07-07 04:12:27 -03:00
|
|
|
virtual bool logging_failed() const = 0;
|
|
|
|
|
2020-11-05 19:28:26 -04:00
|
|
|
// We may need to make sure data is loggable before starting the
|
|
|
|
// EKF; when allow_start_ekf we should be able to log that data
|
|
|
|
bool allow_start_ekf() const;
|
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
virtual void vehicle_was_disarmed();
|
2016-07-28 02:58:20 -03:00
|
|
|
|
2019-01-18 00:24:08 -04:00
|
|
|
bool Write_Unit(const struct UnitStructure *s);
|
|
|
|
bool Write_Multiplier(const struct MultiplierStructure *s);
|
|
|
|
bool Write_Format_Units(const struct LogStructure *structure);
|
2015-12-07 20:51:46 -04:00
|
|
|
|
2020-12-22 13:25:44 -04:00
|
|
|
virtual void io_timer(void) {}
|
|
|
|
|
2015-06-25 10:53:20 -03:00
|
|
|
protected:
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2019-01-18 00:23:42 -04:00
|
|
|
AP_Logger &_front;
|
2015-06-25 10:53:20 -03:00
|
|
|
|
2015-08-06 09:18:28 -03:00
|
|
|
virtual void periodic_10Hz(const uint32_t now);
|
2018-07-28 13:28:54 -03:00
|
|
|
virtual void periodic_1Hz();
|
|
|
|
virtual void periodic_fullrate();
|
2015-08-06 09:18:28 -03:00
|
|
|
|
2017-10-26 02:29:09 -03:00
|
|
|
bool ShouldLog(bool is_critical);
|
2017-07-04 13:53:20 -03:00
|
|
|
virtual bool WritesOK() const = 0;
|
2017-06-30 08:09:20 -03:00
|
|
|
virtual bool StartNewLogOK() const;
|
2017-06-08 22:36:18 -03:00
|
|
|
|
2021-06-14 22:09:24 -03:00
|
|
|
// called by PrepForArming to actually start logging
|
|
|
|
virtual void PrepForArming_start_logging(void) {
|
|
|
|
start_new_log();
|
|
|
|
}
|
2021-06-13 20:46:51 -03:00
|
|
|
|
2015-06-25 10:53:20 -03:00
|
|
|
/*
|
|
|
|
read a block
|
|
|
|
*/
|
2015-08-06 09:18:28 -03:00
|
|
|
virtual bool WriteBlockCheckStartupMessages();
|
|
|
|
virtual void WriteMoreStartupMessages();
|
|
|
|
virtual void push_log_blocks();
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2019-01-18 00:23:42 -04:00
|
|
|
LoggerMessageWriter_DFLogStart *_startup_messagewriter;
|
2015-11-09 18:14:22 -04:00
|
|
|
bool _writing_startup_messages;
|
2015-08-06 09:18:28 -03:00
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
uint16_t _cached_oldest_log;
|
|
|
|
|
2015-08-06 09:18:28 -03:00
|
|
|
uint32_t _dropped;
|
2020-05-05 14:00:54 -03:00
|
|
|
uint32_t _log_file_size_bytes;
|
|
|
|
// should we rotate when we next stop logging
|
|
|
|
bool _rotate_pending;
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2016-04-15 06:53:54 -03:00
|
|
|
// must be called when a new log is being started:
|
|
|
|
virtual void start_new_log_reset_variables();
|
2020-05-05 14:00:54 -03:00
|
|
|
// convert between log numbering in storage and normalized numbering
|
|
|
|
uint16_t log_num_from_list_entry(const uint16_t list_entry);
|
|
|
|
|
|
|
|
uint32_t critical_message_reserved_space(uint32_t bufsize) const {
|
|
|
|
// possibly make this a proportional to buffer size?
|
|
|
|
uint32_t ret = 1024;
|
|
|
|
if (ret > bufsize) {
|
|
|
|
// in this case you will only get critical messages
|
|
|
|
ret = bufsize;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
uint32_t non_messagewriter_message_reserved_space(uint32_t bufsize) const {
|
|
|
|
// possibly make this a proportional to buffer size?
|
|
|
|
uint32_t ret = 1024;
|
|
|
|
if (ret >= bufsize) {
|
|
|
|
// need to allow messages out from the messagewriters. In
|
|
|
|
// this case while you have a messagewriter you won't get
|
|
|
|
// any other messages. This should be a corner case!
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
2016-04-15 06:53:54 -03:00
|
|
|
|
2017-06-30 08:09:20 -03:00
|
|
|
virtual bool _WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical) = 0;
|
|
|
|
|
2017-06-30 01:42:31 -03:00
|
|
|
bool _initialised;
|
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
void df_stats_gather(uint16_t bytes_written, uint32_t space_remaining);
|
|
|
|
void df_stats_log();
|
|
|
|
void df_stats_clear();
|
|
|
|
|
2021-07-27 05:47:45 -03:00
|
|
|
AP_Logger_RateLimiter *rate_limiter;
|
|
|
|
|
2015-08-06 09:18:28 -03:00
|
|
|
private:
|
2020-05-05 14:00:54 -03:00
|
|
|
// statistics support
|
|
|
|
struct df_stats {
|
|
|
|
uint16_t blocks;
|
|
|
|
uint32_t bytes;
|
|
|
|
uint32_t buf_space_min;
|
|
|
|
uint32_t buf_space_max;
|
|
|
|
uint32_t buf_space_sigma;
|
|
|
|
};
|
|
|
|
struct df_stats stats;
|
2015-11-09 18:14:22 -04:00
|
|
|
|
2015-08-06 09:18:28 -03:00
|
|
|
uint32_t _last_periodic_1Hz;
|
|
|
|
uint32_t _last_periodic_10Hz;
|
2017-10-26 02:29:09 -03:00
|
|
|
bool have_logged_armed;
|
2018-08-08 23:12:18 -03:00
|
|
|
|
2020-05-05 14:00:54 -03:00
|
|
|
void Write_AP_Logger_Stats_File(const struct df_stats &_stats);
|
2018-08-08 23:12:18 -03:00
|
|
|
void validate_WritePrioritisedBlock(const void *pBuffer, uint16_t size);
|
2015-06-25 10:53:20 -03:00
|
|
|
};
|
2023-09-05 10:08:30 -03:00
|
|
|
|
|
|
|
#endif // HAL_LOGGING_ENABLED
|