19 size_t AvailableSize()
21 return GetChecksumOffset() - GetUsedBlockSize(BlockType::MAIN);
29 size_t GetBlockOffset(BlockType block)
31 return block == BlockType::BACKUP ? block_size_ : 0;
38 size_t GetChecksumOffset() {
return block_size_ - GetChecksumSize(); }
44 size_t GetChecksumSize() {
return AlignSize(
sizeof(CHECKSUM_BYTE)); }
54 void InitBlock(BlockType block)
56 const size_t offset = GetBlockOffset(block);
57 EraseFlashOrExit(offset, block_size_);
60 info.
header = FLASH_HEADER;
67 WriteFlashOrExit(offset, {
reinterpret_cast<uint8_t*
>(&info),
sizeof(
FlashInfo)});
68 WriteFlashOrExit(offset + GetChecksumOffset(),
69 {&CHECKSUM_BYTE,
sizeof(CHECKSUM_BYTE)});
77 bool IsBlockInited(BlockType block)
79 const size_t offset = GetBlockOffset(block);
81 ReadFlashOrExit(offset, flash_data);
82 return flash_data.
header == FLASH_HEADER;
94 bool IsBlockEmpty(BlockType block)
96 const size_t offset = GetBlockOffset(block);
98 ReadFlashOrExit(offset, flash_data);
108 bool IsBlockError(BlockType block)
110 const size_t offset = GetBlockOffset(block);
111 uint32_t checksum = 0;
112 ReadFlashOrExit(offset + GetChecksumOffset(), checksum);
113 return checksum != CHECKSUM_BYTE;
123 bool IsBlockValid(BlockType block)
125 return IsBlockInited(block) && !IsBlockError(block);
132 void InvalidateBlock(BlockType block)
134 const uint32_t invalid_checksum = 0;
136 WriteFlashOrExit(GetBlockOffset(block) + GetChecksumOffset(),
137 {&invalid_checksum,
sizeof(invalid_checksum)});
153 bool TryGetUsedBlockSize(BlockType block,
size_t& used_size)
155 const size_t block_offset = GetBlockOffset(block);
156 const size_t checksum_offset = block_offset + GetChecksumOffset();
161 if (key_offset + AlignSize(
sizeof(
KeyInfo)) > checksum_offset)
167 ReadFlashOrExit(key_offset, key);
177 const size_t next_key_offset =
180 if (next_key_offset > checksum_offset)
187 used_size = next_key_offset - block_offset;
191 key_offset = next_key_offset;
200 size_t GetUsedBlockSize(BlockType block)
202 const size_t block_offset = GetBlockOffset(block);
205 if (IsBlockEmpty(block))
207 return GetNextKey(first_key_offset) - block_offset;
210 return GetNextKey(GetLastKey(block)) - block_offset;
222 void CopyBlockPrefixAndChecksum(BlockType dst_block, BlockType src_block,
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();
229 ASSERT(used_size <= checksum_offset);
231 CopyFlashData(dst_offset, src_offset, used_size);
232 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).
KeyInfo key
紧跟在块头后的首个键头 / First key header stored right after the block header.
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).