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 int getSlotSize() const;
109 uint32_t getFirstSlotAddress() const;
110 uint32_t getNextSlotAddress(uint32_t slotAddress) const;
111 uint16_t slotSize() const;
112 uint32_t updateStateEntryAddress();
113 uint32_t sectionOffset = 0;
114 uint32_t availableSize;
115 uint16_t elementStateSize = 0xFFFF;
116 uint16_t stateSlotNewSize = 0;
117 uint32_t currentStateBufferOffset = 0;
118 uint16_t crc = 0; // value calculated on each save/read
119 bool elementStateCrcCValid = false;
120 bool storageStateOk = false;
121 bool initDone = false;
122 int repeatBeforeSwitchToAnotherSlot = 0;
123
124 uint32_t currentSlotAddress = 0;
125 uint32_t lastStoredSlotAddress = 0;
126 uint32_t lastValidAddress = 0;
127 uint8_t *dataBuffer = nullptr;
128
129 State state = State::NONE;
130};
131
132} // namespace Supla
133
134#endif // SRC_SUPLA_STORAGE_STATE_WEAR_LEVELING_SECTOR_H_
Definition storage.h:142
Definition state_wear_leveling_sector.h:57
Definition state_wear_leveling_sector.h:63