supla-device
Loading...
Searching...
No Matches
state_wear_leveling_sector.h
1/*
2 Copyright (C) AC SOFTWARE SP. Z O.O
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19#ifndef SRC_SUPLA_STORAGE_STATE_WEAR_LEVELING_SECTOR_H_
20#define SRC_SUPLA_STORAGE_STATE_WEAR_LEVELING_SECTOR_H_
21
22/*
23 Class used for writing state data storage with wear leveling in sector mode.
24 "Sector mode" should be used for memory where write requires earlier
25 "sector erase" operation (like flash).
26
27 Storage is organized in following way:
28 First sector 4096 B:
29 1. Preamble (8 B)
30 2. State storage section preamble (7 B)
31 3. StateWlSectorConfig with size of state data and crc (4 B)
32 4. All remmaining bytes are used as bitmap to store last written state
33 slot number.
34 Second sector 4096 B:
35 Backup copy of first sector
36 Third and next sectors:
37 Array of state data slots with:
38 - StateWlSectorHeader (2 B) (crc)
39 - State data (size depends on used Element configuration)
40
41 On each write, new state data is written to next free slot. If it will not
42 fit in current sector, the next sector is erased and data is written to
43 current sector and next one. After each save, state bitmap is updated by
44 writing bit 0 to next bit in StateBitmapAddress, and then the same is written
45 to backup copy of first sector.
46
47 Count of zeroed bits in StateBitmapAddress is a number of last written state
48 slot.
49
50 */
51
52#include "state_storage_interface.h"
53
54namespace Supla {
55
56#pragma pack(push, 1)
58 uint16_t stateSlotSize;
59 uint16_t crc;
60};
61// StateWlSectorHeader is stored at the begining of each state data slot.
62// It contain crc of state data that follows it.
64 uint16_t crc;
65};
66#pragma pack(pop)
67
68struct SectionPreamble;
69
70class StateWearLevelingSector : public StateStorageInterface {
71 public:
72 enum class State : uint8_t {
73 NONE,
74 ERROR,
75 SIZE_CHECK,
76 WRITE,
77 LOAD
78 };
79
80 explicit StateWearLevelingSector(Storage *storage,
81 uint32_t offset, // address of StateWlSectorConfig in
82 // first sector
83 uint32_t availableSize);
84 ~StateWearLevelingSector();
85
86 bool loadPreambles(uint32_t storageStartingOffset, uint16_t size) override;
87 void initSectionPreamble(SectionPreamble *preamble) override;
88 bool writeSectionPreamble() override;
89 bool initFromStorage() override;
90 void deleteAll() override;
91 bool prepareSaveState() override;
92 bool prepareSizeCheck() override;
93 bool prepareLoadState() override;
94 bool readState(unsigned char *, int) override;
95 bool writeState(const unsigned char *, int) override;
96 bool finalizeSaveState() override;
97 bool finalizeSizeCheck() override;
98 bool finalizeLoadState() override;
99 void notifyUpdate() override;
100
101 protected:
102 virtual uint16_t getSectorSize() const;
103
104 private:
105 uint16_t getSizeValue(uint16_t availableSize) override;
106 bool tryLoadPreamblesFrom(uint32_t offset);
107 bool isDataDifferent(uint32_t address, const uint8_t *data, uint32_t size);
108 bool isSlotValid(uint32_t address, uint8_t *buffer);
109 uint32_t getPhysicalSlotCount() const;
110 uint32_t getMaxBitmapSlotCount() const;
111 int getSlotSize() const;
112 uint32_t getFirstSlotAddress() const;
113 uint32_t getNextSlotAddress(uint32_t slotAddress) const;
114 uint32_t getPreviousSlotAddress(uint32_t slotAddress) const;
115 uint16_t slotSize() const;
116 uint32_t updateStateEntryAddress();
117 uint32_t sectionOffset = 0;
118 uint32_t availableSize;
119 uint16_t elementStateSize = 0xFFFF;
120 uint16_t stateSlotNewSize = 0;
121 uint32_t currentStateBufferOffset = 0;
122 uint16_t crc = 0; // value calculated on each save/read
123 bool elementStateCrcCValid = false;
124 bool storageStateOk = false;
125 bool initDone = false;
126 bool currentSlotPreparedForFirstWrite = false;
127 int repeatBeforeSwitchToAnotherSlot = 0;
128
129 uint32_t currentSlotAddress = 0;
130 uint32_t lastStoredSlotAddress = 0;
131 uint32_t lastValidAddress = 0;
132 uint8_t *dataBuffer = nullptr;
133
134 State state = State::NONE;
135};
136
137} // namespace Supla
138
139#endif // SRC_SUPLA_STORAGE_STATE_WEAR_LEVELING_SECTOR_H_
Definition storage.h:162
Definition state_wear_leveling_sector.h:57
Definition state_wear_leveling_sector.h:63