supla-device
Loading...
Searching...
No Matches
state_wear_leveling_byte.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_BYTE_H_
20#define SRC_SUPLA_STORAGE_STATE_WEAR_LEVELING_BYTE_H_
21
22/*
23 Class used for writing state data storage with wear leveling in byte mode.
24 "Byte mode" should be used for random access memory types (like EEPROM), where
25 memory allows to write data to any byte without clearing whole sector of
26 memory.
27
28 Storage is organized in following way:
29 1. Preamble (8 B)
30 2. State storage section preamble (7 B)
31 3. StateEntryAddress with address of current element state slot and its own
32 crc (8 B)
33 4. Copy of StateEntryAddress (8 B)
34 5. State data with:
35 - StateWlByteHeader (4 B)
36 - State data (size depends on used Element configuration)
37
38 State data is saved always at slot pointed by StateEntryAddress and to
39 followin slot (next one). It is done in order to ensure that state data
40 will have backup copy.
41 writeCount is incremented each time slot is written.
42 On storage init, state is read from slot pointed by StateEntryAddress
43 or from next slot after it (depending on which writeCount is higher).
44 StateEndryAddress is incremented each time when writeCount is higher
45 than repeatBeforeSwitchToAnotherSlot. Then next slot use writeCount == 1.
46 Slot with writeCount == 1 is considered as newer than slot with
47 writeCount == repeatBeforeSwitchToAnotherSlot.
48
49 repeatBeforeSwitchToAnotherSlot is configured to be equal to number of
50 slots in state storage, rounded up to the next odd number.
51
52 Slots are used in round-robin way.
53
54 Exact sequnce of writes is done in a way that there will be always correct
55 copy of data stored.
56 */
57
58#include "state_storage_interface.h"
59
60namespace Supla {
61
62#pragma pack(push, 1)
63// StateEntryAddress is stored after section preamble in two copies.
64// It contain address of current element state slot and its own crc.
66 uint32_t address;
67 uint16_t elementStateSize;
68 uint16_t crc;
69};
70
71// StateWlByteHeader is stored at the begining of each state data slot.
72// It contain information how many times slot was used for writing and
73// crc of state data that follows it.
75 uint16_t writeCount;
76 uint16_t crc;
77};
78#pragma pack(pop)
79
80struct SectionPreamble;
81
82class StateWearLevelingByte : public StateStorageInterface {
83 public:
84 explicit StateWearLevelingByte(Storage *storage,
85 uint32_t offset);
86 ~StateWearLevelingByte();
87
88 void initSectionPreamble(SectionPreamble *preamble) override;
89 bool writeSectionPreamble() override;
90 bool initFromStorage() override;
91 void deleteAll() override;
92 bool prepareSaveState() override;
93 bool prepareSizeCheck() override;
94 bool prepareLoadState() override;
95 bool readState(unsigned char *, int) override;
96 bool writeState(const unsigned char *, int) override;
97 bool finalizeSaveState() override;
98 bool finalizeSizeCheck() override;
99 bool finalizeLoadState() override;
100 void notifyUpdate() override;
101
102 private:
103 uint16_t getSizeValue(uint16_t availableSize) override;
104 void checkIfIsEnoughSpaceForState();
105 uint32_t getFirstSlotAddress() const;
106 uint32_t getNextSlotAddress(uint32_t slotAddress) const;
107 uint32_t slotSize() const;
108 uint32_t updateStateEntryAddress();
109 bool isDataDifferent(uint32_t firstAddress, uint32_t secondAddress, int size);
110 uint32_t sectionOffset = 0;
111 uint32_t reservedSize;
112 uint32_t elementStateSize = 0;
113 uint32_t stateSlotNewSize = 0;
114 uint32_t currentStateOffset = 0;
115 uint16_t crc = 0; // value calculated on each save/read
116 bool elementStateCrcCValid = false;
117 bool dryRun = false;
118 bool storageStateOk = false;
119 bool initDone = false;
120 bool dataChanged = false;
121 int repeatBeforeSwitchToAnotherSlot = 0;
122
123 uint16_t writeCount = 0;
124 uint32_t currentSlotAddress = 0;
125};
126
127} // namespace Supla
128#endif // SRC_SUPLA_STORAGE_STATE_WEAR_LEVELING_BYTE_H_
Definition storage.h:142
Definition state_wear_leveling_byte.h:65
Definition state_wear_leveling_byte.h:74