Line data Source code
1 : /* 2 : AP_Logger logging - block oriented variant 3 : */ 4 : #pragma once 5 : 6 : #include "AP_Logger_Backend.h" 7 : 8 : #if HAL_LOGGING_BLOCK_ENABLED 9 : 10 : #define BLOCK_LOG_VALIDATE 0 11 : 12 : class AP_Logger_Block : public AP_Logger_Backend { 13 : public: 14 : AP_Logger_Block(AP_Logger &front, LoggerMessageWriter_DFLogStart *writer); 15 : 16 : virtual void Init(void) override; 17 : virtual bool CardInserted(void) const override = 0; 18 : 19 : // erase handling 20 : void EraseAll() override; 21 : 22 : // high level interface 23 : uint16_t find_last_log() override; 24 : void get_log_boundaries(uint16_t list_entry, uint32_t & start_page, uint32_t & end_page) override; 25 : void get_log_info(uint16_t list_entry, uint32_t &size, uint32_t &time_utc) override; 26 : int16_t get_log_data(uint16_t list_entry, uint16_t page, uint32_t offset, uint16_t len, uint8_t *data) override WARN_IF_UNUSED; 27 12 : void end_log_transfer() override { } 28 : uint16_t get_num_logs() override; 29 : void start_new_log(void) override; 30 : uint32_t bufferspace_available() override; 31 : void stop_logging(void) override; 32 : void stop_logging_async(void) override; 33 : bool logging_failed() const override; 34 789173 : bool logging_started(void) const override { return log_write_started; } 35 : void io_timer(void) override; 36 : 37 : protected: 38 : /* Write a block of data at current offset */ 39 : bool _WritePrioritisedBlock(const void *pBuffer, uint16_t size, bool is_critical) override; 40 : void periodic_1Hz() override; 41 : void periodic_10Hz(const uint32_t now) override; 42 : bool WritesOK() const override; 43 : 44 : // get the current sector from the current page 45 7 : uint32_t get_sector(uint32_t current_page) const { 46 7 : return ((current_page - 1) / df_PagePerSector); 47 : } 48 : 49 : // get the current block from the current page 50 177 : uint32_t get_block(uint32_t current_page) const { 51 177 : return ((current_page - 1) / df_PagePerBlock); 52 : } 53 : 54 : // number of bytes in a page 55 : uint32_t df_PageSize; 56 : // number of pages in a (generally 64k) block 57 : uint16_t df_PagePerBlock; 58 : // number of pages in a (generally 4k) sector 59 : uint16_t df_PagePerSector; 60 : // number of pages on the chip 61 : uint32_t df_NumPages; 62 : volatile bool log_write_started; 63 : 64 : uint8_t *buffer; 65 : uint32_t last_messagewrite_message_sent; 66 : uint32_t df_Read_PageAdr; 67 : 68 : private: 69 : /* 70 : functions implemented by the board specific backends 71 : */ 72 : virtual void BufferToPage(uint32_t PageAdr) = 0; 73 : virtual void PageToBuffer(uint32_t PageAdr) = 0; 74 : virtual void SectorErase(uint32_t SectorAdr) = 0; 75 : virtual void Sector4kErase(uint32_t SectorAdr) = 0; 76 : virtual void StartErase() = 0; 77 : virtual bool InErase() = 0; 78 : void flash_test(void); 79 : 80 : struct PACKED PageHeader { 81 : uint32_t FilePage; 82 : uint16_t FileNumber; 83 : #if BLOCK_LOG_VALIDATE 84 : uint32_t crc; 85 : #endif 86 : }; 87 : 88 : struct PACKED FileHeader { 89 : uint32_t utc_secs; 90 : }; 91 : 92 : // semaphore to mediate access to the chip 93 : HAL_Semaphore sem; 94 : // semaphore to mediate access to the ring buffer 95 : HAL_Semaphore write_sem; 96 : ByteBuffer writebuf; 97 : 98 : // state variables 99 : uint16_t df_Read_BufferIdx; 100 : uint32_t df_PageAdr; // current page address for writes 101 : // file numbers 102 : uint16_t df_FileNumber; 103 : uint16_t df_Write_FileNumber; 104 : uint32_t df_FileTime; 105 : // relative page index of the current read/write file starting at 1 106 : uint32_t df_FilePage; 107 : uint32_t df_Write_FilePage; 108 : // page to wipe from in the case of corruption 109 : uint32_t df_EraseFrom; 110 : 111 : // offset from adding FMT messages to log data 112 : bool adding_fmt_headers; 113 : 114 : // are we waiting on an erase to finish? 115 : volatile bool erase_started; 116 : // were we logging before the erase started? 117 : volatile bool new_log_pending; 118 : // have we been asked to stop logging safely? 119 : volatile bool stop_log_pending; 120 : // latch to make sure we only write out the full message once 121 : volatile bool chip_full; 122 : // io thread health 123 : volatile uint32_t io_timer_heartbeat; 124 : uint8_t warning_decimation_counter; 125 : 126 : volatile enum class StatusMessage { 127 : NONE, 128 : ERASE_COMPLETE, 129 : RECOVERY_COMPLETE, 130 : } status_msg; 131 : 132 : // read size bytes of data to a page. The caller must ensure that 133 : // the data fits within the page, otherwise it will wrap to the 134 : // start of the page 135 : bool BlockRead(uint16_t IntPageAdr, void *pBuffer, uint16_t size); 136 : 137 : // erase handling 138 : bool NeedErase(void); 139 : void validate_log_structure(); 140 : 141 : // internal high level functions 142 : int16_t get_log_data_raw(uint16_t log_num, uint32_t page, uint32_t offset, uint16_t len, uint8_t *data) WARN_IF_UNUSED; 143 : // read from the page address and return the file number at that location 144 : uint16_t StartRead(uint32_t PageAdr); 145 : // read the headers at the current read point returning the file number 146 : uint16_t ReadHeaders(); 147 : uint32_t find_last_page(void); 148 : uint32_t find_last_page_of_log(uint16_t log_number); 149 : bool is_wrapped(void); 150 : void StartWrite(uint32_t PageAdr); 151 : void FinishWrite(void); 152 : 153 : // Read methods 154 : bool ReadBlock(void *pBuffer, uint16_t size); 155 : 156 : void StartLogFile(uint16_t FileNumber); 157 : // file numbers 158 : uint16_t GetFileNumber() const; 159 : 160 : void _print_log_formats(AP_HAL::BetterStream *port); 161 : 162 : // callback on IO thread 163 : bool io_thread_alive() const; 164 : void write_log_page(); 165 : }; 166 : 167 : #endif // HAL_LOGGING_BLOCK_ENABLED