APM:Libraries
DataFlash_File_sd.h
Go to the documentation of this file.
1 /*
2  DataFlash logging - file oriented variant
3 
4  This uses posix file IO to create log files called logNN.dat in the
5  given directory
6  */
7 #pragma once
8 
9 #include <AP_HAL/AP_HAL.h>
10 
11 #if CONFIG_HAL_BOARD == HAL_BOARD_F4LIGHT && (defined(BOARD_SDCARD_NAME) || defined(BOARD_DATAFLASH_FATFS))
12 
14 #include "DataFlash_Backend.h"
15 
16 #include <sd/SD.h>
17 
18 class DataFlash_File : public DataFlash_Backend
19 {
20 public:
21  // constructor
22  DataFlash_File(DataFlash_Class &front,
24  const char *log_directory);
25 
26  // initialisation
27  void Init() override;
28  bool CardInserted(void) const;
29 
30  // erase handling
31  void EraseAll();
32 
33  // possibly time-consuming preparation handling:
34  bool NeedPrep();
35  void Prep();
36 
37  /* Write a block of data at current offset */
38  bool _WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical);
39  uint32_t bufferspace_available();
40 
41  // high level interface
42  uint16_t find_last_log() override;
43  void get_log_boundaries(uint16_t log_num, uint16_t & start_page, uint16_t & end_page);
44  void get_log_info(uint16_t log_num, uint32_t &size, uint32_t &time_utc);
45  int16_t get_log_data(uint16_t log_num, uint16_t page, uint32_t offset, uint16_t len, uint8_t *data);
46  uint16_t get_num_logs() override;
47  uint16_t start_new_log(void) override;
48 
49  void periodic_1Hz(const uint32_t now) override;
50  void periodic_fullrate(const uint32_t now);
51 
52  // this method is used when reporting system status over mavlink
53  bool logging_enabled() const;
54  bool logging_failed() const;
55 
56  void vehicle_was_disarmed() override;
57 
58  bool logging_started(void) const override { return !(!(_write_fd)); }
59 
60  void PrepForArming();
61 
62 protected:
63  bool WritesOK() const override;
64  bool StartNewLogOK() const override;
65 
66 private:
67  File _write_fd;
68  File _read_fd;
69  uint16_t _read_fd_log_num;
70  uint32_t _read_offset;
71  uint32_t _write_offset;
72  volatile bool _open_error;
73  const char *_log_directory;
74 
75  uint32_t _io_timer_heartbeat;
76  bool io_thread_alive() const;
77 
78  uint16_t _cached_oldest_log;
79  uint16_t _last_oldest_log;
80 
81  /*
82  read a block
83  */
84  bool ReadBlock(void *pkt, uint16_t size) override;
85 
86  uint16_t _log_num_from_list_entry(const uint16_t list_entry);
87 
88  // possibly time-consuming preparations handling
89  void Prep_MinSpace();
90  uint16_t find_oldest_log();
91 
92  bool file_exists(const char *filename) const;
93  bool log_exists(const uint16_t lognum) const;
94 
95  const float min_avail_space_percent = 10.0f;
96 
97  // write buffer
98  ByteBuffer _writebuf;
99  const uint16_t _writebuf_chunk;
100  uint32_t _last_write_time;
101 
102  /* construct a file name given a log number. Caller must free. */
103  char *_log_file_name(const uint16_t log_num) const;
104  char *_lastlog_file_name() const;
105  uint32_t _get_log_size(const uint16_t log_num) const;
106  uint32_t _get_log_time(const uint16_t log_num) const;
107 
108  void stop_logging(void);
109 
110  void _io_timer(void);
111 
112  uint32_t critical_message_reserved_space() const {
113  // possibly make this a proportional to buffer size?
114  uint32_t ret = 1024;
115  if (ret > _writebuf.get_size()) {
116  // in this case you will only get critical messages
117  ret = _writebuf.get_size();
118  }
119  return ret;
120  };
121  uint32_t non_messagewriter_message_reserved_space() const {
122  // possibly make this a proportional to buffer size?
123  uint32_t ret = 1024;
124  if (ret >= _writebuf.get_size()) {
125  // need to allow messages out from the messagewriters. In
126  // this case while you have a messagewriter you won't get
127  // any other messages. This should be a corner case!
128  ret = 0;
129  }
130  return ret;
131  };
132 
133  float avail_space_percent(uint32_t *free = NULL);
134 
135  AP_HAL::Semaphore *semaphore;
136 
137  bool has_data;
138 
139 #define Daysto32(year, mon) (((year - 1) / 4) + MONTAB(year)[mon])
140 
142 
143  static uint32_t to_timestamp(const struct tm *t);
144 
145  bool _busy;
146 };
147 
148 #endif
virtual void stop_logging(void)=0
virtual bool CardInserted(void) const =0
virtual bool StartNewLogOK() const
virtual void Init()
virtual void get_log_boundaries(uint16_t log_num, uint16_t &start_page, uint16_t &end_page)=0
uint32_t get_size(void) const
Definition: RingBuffer.h:42
virtual void vehicle_was_disarmed()
virtual int16_t get_log_data(uint16_t log_num, uint16_t page, uint32_t offset, uint16_t len, uint8_t *data)=0
virtual bool _WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical)=0
virtual bool WritesOK() const =0
virtual uint16_t find_last_log()=0
virtual void EraseAll()=0
virtual void periodic_fullrate(const uint32_t now)
virtual bool logging_enabled() const =0
virtual bool logging_failed() const =0
virtual void Prep()=0
#define NULL
Definition: hal_types.h:59
virtual uint16_t get_num_logs()=0
void free(void *ptr)
Definition: malloc.c:81
static uint16_t log_num
virtual void periodic_1Hz(const uint32_t now)
virtual uint32_t bufferspace_available()=0
virtual void PrepForArming()
virtual uint16_t start_new_log(void)=0
virtual bool NeedPrep()=0
virtual void get_log_info(uint16_t log_num, uint32_t &size, uint32_t &time_utc)=0
virtual bool logging_started(void) const =0
virtual bool ReadBlock(void *pkt, uint16_t size)=0