libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
block_ops.hpp
1
19 size_t AvailableSize()
20 {
21 return GetChecksumOffset() - GetUsedBlockSize(BlockType::MAIN);
22 }
23
29 size_t GetBlockOffset(BlockType block)
30 {
31 return block == BlockType::BACKUP ? block_size_ : 0;
32 }
33
38 size_t GetChecksumOffset() { return block_size_ - GetChecksumSize(); }
39
44 size_t GetChecksumSize() { return AlignSize(sizeof(CHECKSUM_BYTE)); }
45
54 void InitBlock(BlockType block)
55 {
56 const size_t offset = GetBlockOffset(block);
57 EraseFlashOrExit(offset, block_size_);
58
59 FlashInfo info; // padding filled with 0xFF by constructor
60 info.header = FLASH_HEADER;
61 KeyInfo& tmp_key = info.key;
65 tmp_key.SetNameLength(0);
66 tmp_key.SetDataSize(0);
67 WriteFlashOrExit(offset, {reinterpret_cast<uint8_t*>(&info), sizeof(FlashInfo)});
68 WriteFlashOrExit(offset + GetChecksumOffset(),
69 {&CHECKSUM_BYTE, sizeof(CHECKSUM_BYTE)});
70 }
71
77 bool IsBlockInited(BlockType block)
78 {
79 const size_t offset = GetBlockOffset(block);
80 FlashInfo flash_data;
81 ReadFlashOrExit(offset, flash_data);
82 return flash_data.header == FLASH_HEADER;
83 }
84
94 bool IsBlockEmpty(BlockType block)
95 {
96 const size_t offset = GetBlockOffset(block);
97 FlashInfo flash_data;
98 ReadFlashOrExit(offset, flash_data);
100 }
101
108 bool IsBlockError(BlockType block)
109 {
110 const size_t offset = GetBlockOffset(block);
111 uint32_t checksum = 0;
112 ReadFlashOrExit(offset + GetChecksumOffset(), checksum);
113 return checksum != CHECKSUM_BYTE;
114 }
115
123 bool IsBlockValid(BlockType block)
124 {
125 return IsBlockInited(block) && !IsBlockError(block);
126 }
127
132 void InvalidateBlock(BlockType block)
133 {
134 const uint32_t invalid_checksum = 0;
135 // Keep startup cleanup erase-free so same-bank MCUs only pay a single program op.
136 WriteFlashOrExit(GetBlockOffset(block) + GetChecksumOffset(),
137 {&invalid_checksum, sizeof(invalid_checksum)});
138 }
139
153 bool TryGetUsedBlockSize(BlockType block, size_t& used_size)
154 {
155 const size_t block_offset = GetBlockOffset(block);
156 const size_t checksum_offset = block_offset + GetChecksumOffset();
157 size_t key_offset = block_offset + LibXR::OffsetOf(&FlashInfo::key);
158
159 while (true)
160 {
161 if (key_offset + AlignSize(sizeof(KeyInfo)) > checksum_offset)
162 {
163 return false;
164 }
165
166 KeyInfo key;
167 ReadFlashOrExit(key_offset, key);
168
169 // Recovery cannot trust erased or half-written key metadata to bound copies.
173 {
174 return false;
175 }
176
177 const size_t next_key_offset =
178 key_offset + AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength()) +
179 AlignSize(key.GetDataSize());
180 if (next_key_offset > checksum_offset)
181 {
182 return false;
183 }
184
186 {
187 used_size = next_key_offset - block_offset;
188 return true;
189 }
190
191 key_offset = next_key_offset;
192 }
193 }
194
200 size_t GetUsedBlockSize(BlockType block)
201 {
202 const size_t block_offset = GetBlockOffset(block);
203 const size_t first_key_offset = block_offset + LibXR::OffsetOf(&FlashInfo::key);
204
205 if (IsBlockEmpty(block))
206 {
207 return GetNextKey(first_key_offset) - block_offset;
208 }
209
210 return GetNextKey(GetLastKey(block)) - block_offset;
211 }
212
222 void CopyBlockPrefixAndChecksum(BlockType dst_block, BlockType src_block,
223 size_t used_size)
224 {
225 const size_t dst_offset = GetBlockOffset(dst_block);
226 const size_t src_offset = GetBlockOffset(src_block);
227 const size_t checksum_offset = GetChecksumOffset();
228
229 ASSERT(used_size <= checksum_offset);
230 // Only the live key prefix and checksum are needed; erased tail bytes are irrelevant.
231 CopyFlashData(dst_offset, src_offset, used_size);
232 CopyFlashData(dst_offset + checksum_offset, src_offset + checksum_offset,
233 GetChecksumSize());
234 }
读写对齐布尔位图块的工具 (Helpers for reading and writing aligned boolean flag blocks).
Definition layout.hpp:36
static void SetFlag(BlockBoolData< BlockSize > &obj, bool value)
把一个布尔值编码进位图块 (Encode one boolean value into a flag block).
Definition layout.hpp:43
static bool ReadFlag(const BlockBoolData< BlockSize > &obj)
从位图块读取布尔值 (Decode one boolean value from a flag block).
Definition layout.hpp:57
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量
Definition libxr_def.hpp:88
Flash 存储的块信息结构 (Structure representing a Flash storage block).
Definition layout.hpp:163
KeyInfo key
紧跟在块头后的首个键头 / First key header stored right after the block header.
Definition layout.hpp:184
uint32_t header
Flash 块头签名 / Flash block-header signature.
Definition layout.hpp:181
键信息结构,存储键的元数据 (Structure containing key metadata).
Definition layout.hpp:106
BlockBoolData< MinWriteSize > uninit
该键是否未初始化
Definition layout.hpp:109
BlockBoolData< MinWriteSize > available_flag
该键是否有效
Definition layout.hpp:108
uint32_t GetDataSize() const
获取数据字节数 (Get the payload size in bytes).
Definition layout.hpp:153
void SetNameLength(uint8_t len)
设置键名长度 (Set the key name length).
Definition layout.hpp:129
BlockBoolData< MinWriteSize > no_next_key
是否是最后一个键
Definition layout.hpp:107
void SetDataSize(uint32_t size)
设置数据字节数 (Set the payload size in bytes).
Definition layout.hpp:144
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).
Definition layout.hpp:138