19size_t AvailableSize() {
return GetChecksumOffset() - GetUsedBlockSize(BlockType::MAIN); }
26size_t GetBlockOffset(BlockType block)
28 return block == BlockType::BACKUP ? block_size_ : 0;
35size_t GetChecksumOffset() {
return block_size_ - GetChecksumSize(); }
41size_t GetChecksumSize() {
return AlignSize(
sizeof(CHECKSUM_BYTE)); }
51void InitBlock(BlockType block)
53 const size_t offset = GetBlockOffset(block);
54 EraseFlashOrExit(offset, block_size_);
57 info.
header = FLASH_HEADER;
64 WriteFlashOrExit(offset, {
reinterpret_cast<uint8_t*
>(&info),
sizeof(
FlashInfo)});
65 WriteFlashOrExit(offset + GetChecksumOffset(), {&CHECKSUM_BYTE,
sizeof(CHECKSUM_BYTE)});
73bool IsBlockInited(BlockType block)
75 const size_t offset = GetBlockOffset(block);
77 ReadFlashOrExit(offset, flash_data);
78 return flash_data.
header == FLASH_HEADER;
90bool IsBlockEmpty(BlockType block)
92 const size_t offset = GetBlockOffset(block);
94 ReadFlashOrExit(offset, flash_data);
104bool IsBlockError(BlockType block)
106 const size_t offset = GetBlockOffset(block);
107 uint32_t checksum = 0;
108 ReadFlashOrExit(offset + GetChecksumOffset(), checksum);
109 return checksum != CHECKSUM_BYTE;
119bool IsBlockValid(BlockType block)
121 return IsBlockInited(block) && !IsBlockError(block);
128void InvalidateBlock(BlockType block)
130 const uint32_t invalid_checksum = 0;
132 WriteFlashOrExit(GetBlockOffset(block) + GetChecksumOffset(),
133 {&invalid_checksum,
sizeof(invalid_checksum)});
149bool TryGetUsedBlockSize(BlockType block,
size_t& used_size)
151 const size_t block_offset = GetBlockOffset(block);
152 const size_t checksum_offset = block_offset + GetChecksumOffset();
157 if (key_offset + AlignSize(
sizeof(
KeyInfo)) > checksum_offset)
163 ReadFlashOrExit(key_offset, key);
173 const size_t next_key_offset = key_offset + AlignSize(
sizeof(
KeyInfo)) +
176 if (next_key_offset > checksum_offset)
183 used_size = next_key_offset - block_offset;
187 key_offset = next_key_offset;
197size_t GetUsedBlockSize(BlockType block)
199 const size_t block_offset = GetBlockOffset(block);
202 if (IsBlockEmpty(block))
204 return GetNextKey(first_key_offset) - block_offset;
207 return GetNextKey(GetLastKey(block)) - block_offset;
219void CopyBlockPrefixAndChecksum(BlockType dst_block, BlockType src_block,
222 const size_t dst_offset = GetBlockOffset(dst_block);
223 const size_t src_offset = GetBlockOffset(src_block);
224 const size_t checksum_offset = GetChecksumOffset();
226 ASSERT(used_size <= checksum_offset);
228 CopyFlashData(dst_offset, src_offset, used_size);
229 CopyFlashData(dst_offset + checksum_offset, src_offset + checksum_offset,
读写对齐布尔位图块的工具 (Helpers for reading and writing aligned boolean flag blocks).
static void SetFlag(BlockBoolData< BlockSize > &obj, bool value)
把一个布尔值编码进位图块 (Encode one boolean value into a flag block).
static bool ReadFlag(const BlockBoolData< BlockSize > &obj)
从位图块读取布尔值 (Decode one boolean value from a flag block).
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量
Flash 存储的块信息结构 (Structure representing a Flash storage block).
uint32_t header
Flash 块头签名 / Flash block-header signature.
键信息结构,存储键的元数据 (Structure containing key metadata).
BlockBoolData< MinWriteSize > uninit
该键是否未初始化
BlockBoolData< MinWriteSize > available_flag
该键是否有效
uint32_t GetDataSize() const
获取数据字节数 (Get the payload size in bytes).
void SetNameLength(uint8_t len)
设置键名长度 (Set the key name length).
BlockBoolData< MinWriteSize > no_next_key
是否是最后一个键
void SetDataSize(uint32_t size)
设置数据字节数 (Set the payload size in bytes).
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).