libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::DatabaseRawSequential Class Reference

适用于不支持逆序写入的 Flash 存储的数据库实现 (Database implementation for Flash storage that does not support reverse writing). More...

#include <raw_sequential.hpp>

Inheritance diagram for LibXR::DatabaseRawSequential:
[legend]
Collaboration diagram for LibXR::DatabaseRawSequential:
[legend]

Data Structures

struct  FlashInfo
 Flash 存储的块信息结构 (Structure representing a Flash storage block). More...
 
struct  KeyInfo
 键信息结构,存储键的元数据 (Structure containing key metadata). More...
 

Public Member Functions

 DatabaseRawSequential (Flash &flash, size_t max_buffer_size=256)
 构造函数,初始化 Flash 存储和缓冲区 (Constructor initializing Flash storage and buffer).
 
void Init ()
 初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).
 
void Save ()
 保存当前缓冲区内容到 Flash (Save the current buffer content to Flash).
 
void Load ()
 Flash 加载数据到缓冲区 (Load data from Flash into the buffer).
 
void Restore ()
 还原存储数据,清空 Flash 区域 (Restore storage data, clearing Flash memory area).
 
ErrorCode Get (Database::KeyBase &key) override
 获取数据库中的键值 (Retrieve the key's value from the database).
 
ErrorCode Set (KeyBase &key, RawData data) override
 设置数据库中的键值 (Set the key's value in the database).
 
ErrorCode Add (KeyBase &key) override
 添加新键到数据库 (Add a new key to the database).
 

Private Types

enum class  BlockType : uint8_t { MAIN = 0 , BACKUP = 1 }
 存储块类型 (Storage block type). More...
 

Private Member Functions

ErrorCode AddKey (const char *name, const void *data, size_t size)
 
ErrorCode SetKey (const char *name, const void *data, size_t size)
 
ErrorCode SetKey (size_t offset, const void *data, size_t size)
 
ErrorCode GetKeyData (size_t offset, RawData data)
 
void InitBlock (BlockType block)
 
void ReadFlashOrExit (size_t offset, RawData data)
 
void WriteFlashOrExit (size_t offset, ConstRawData data)
 
void EraseFlashOrExit (size_t offset, size_t size)
 
bool IsBlockInited (BlockType block)
 判断块是否已初始化 (Check if block is initialized).
 
bool IsBlockEmpty (BlockType block)
 判断块是否为空 (Check if block is empty).
 
bool IsBlockError (BlockType block)
 判断块是否损坏 (Check if block has an error).
 
bool HasLastKey (size_t offset)
 
size_t GetKeySize (size_t offset)
 
size_t GetNextKey (size_t offset)
 
size_t GetLastKey (BlockType block)
 
void SetNestKeyExist (size_t offset, bool exist)
 
bool KeyDataCompare (size_t offset, const void *data, size_t size)
 
bool KeyNameCompare (size_t offset, const char *name)
 
size_t SearchKey (const char *name)
 

Private Attributes

Flashflash_
 目标 Flash 存储设备 (Target Flash storage device).
 
uint8_t * buffer_
 数据缓冲区 (Data buffer).
 
uint32_t block_size_
 Flash 块大小 (Flash block size).
 
uint32_t max_buffer_size_
 最大缓冲区大小 (Maximum buffer size).
 

Static Private Attributes

static constexpr uint32_t FLASH_HEADER
 Flash 头部标识 (Flash header identifier).
 
static constexpr uint8_t CHECKSUM_BYTE = 0x56
 校验字节 (Checksum byte).
 

Detailed Description

适用于不支持逆序写入的 Flash 存储的数据库实现 (Database implementation for Flash storage that does not support reverse writing).

This class manages key-value storage in a Flash memory region where data can only be written sequentially. It maintains a backup system to prevent data corruption. 此类管理 Flash 内存区域中的键值存储,其中数据只能顺序写入。 它维护一个备份系统,以防止数据损坏。

Note
若底层 Flash 读写擦失败,当前实现视为不可恢复故障并直接触发 REQUIRE。 If the underlying Flash read, write, or erase operation fails, the current implementation treats it as an unrecoverable fault and triggers REQUIRE immediately.

Definition at line 28 of file raw_sequential.hpp.

Member Enumeration Documentation

◆ BlockType

enum class LibXR::DatabaseRawSequential::BlockType : uint8_t
strongprivate

存储块类型 (Storage block type).

Enumerator
MAIN 

主块 (Main block).

BACKUP 

备份块 (Backup block).

Definition at line 107 of file raw_sequential.hpp.

108 {
109 MAIN = 0,
110 BACKUP = 1
111 };
@ BACKUP
备份块 (Backup block).

Constructor & Destructor Documentation

◆ DatabaseRawSequential()

DatabaseRawSequential::DatabaseRawSequential ( Flash & flash,
size_t max_buffer_size = 256 )
explicit

构造函数,初始化 Flash 存储和缓冲区 (Constructor initializing Flash storage and buffer).

Parameters
flash目标 Flash 存储设备 (Target Flash storage device).
max_buffer_size最大缓冲区大小,默认 256 字节 (Maximum buffer size, default is 256 bytes).
Note
包含动态内存分配。 Contains dynamic memory allocation.
max_buffer_size 必须不超过整片 Flash 容量的一半。 max_buffer_size must not exceed half of the total flash capacity.

Definition at line 11 of file raw_sequential.cpp.

12 : flash_(flash), max_buffer_size_(max_buffer_size)
13{
14 ASSERT(flash.MinEraseSize() * 2 <= flash.Size());
15 ASSERT(max_buffer_size <= flash.Size() / 2);
16 auto block_num = static_cast<size_t>(flash.Size() / flash.MinEraseSize());
17 block_size_ = block_num / 2 * flash.MinEraseSize();
18 buffer_ = new uint8_t[max_buffer_size];
19
20 Init();
21}
uint32_t max_buffer_size_
最大缓冲区大小 (Maximum buffer size).
void Init()
初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).
uint8_t * buffer_
数据缓冲区 (Data buffer).
uint32_t block_size_
Flash 块大小 (Flash block size).
Flash & flash_
目标 Flash 存储设备 (Target Flash storage device).
size_t Size() const
Returns the size of the flash memory area. 获取闪存存储区域的大小。
Definition flash.hpp:82
size_t MinEraseSize() const
Returns the minimum erasable block size in bytes. 获取最小可擦除块大小(字节)。
Definition flash.hpp:64

Member Function Documentation

◆ Add()

ErrorCode LibXR::DatabaseRawSequential::Add ( KeyBase & key)
inlineoverridevirtual

添加新键到数据库 (Add a new key to the database).

Parameters
key需要添加的键 (Key to add).
Returns
操作结果 (Operation result).

Implements LibXR::Database.

Definition at line 98 of file raw_sequential.hpp.

99 {
100 return AddKey(key.name_, key.raw_data_.addr_, key.raw_data_.size_);
101 }

◆ AddKey()

ErrorCode DatabaseRawSequential::AddKey ( const char * name,
const void * data,
size_t size )
private

Definition at line 293 of file raw_sequential.cpp.

294{
295 if (auto ans = SearchKey(name))
296 {
297 return SetKey(ans, data, size);
298 }
299
300 const uint32_t NAME_LEN = strlen(name) + 1;
301 size_t last_key_offset = GetLastKey(BlockType::MAIN);
302 size_t key_buf_offset =
303 last_key_offset ? GetNextKey(last_key_offset) : LibXR::OffsetOf(&FlashInfo::key);
304
305 size_t end_pos_offset = key_buf_offset + sizeof(KeyInfo) + NAME_LEN + size;
306 if (end_pos_offset > max_buffer_size_ - 1)
307 {
308 return ErrorCode::FULL;
309 }
310
311 size_t data_ptr_offset = key_buf_offset + sizeof(KeyInfo);
312 LibXR::Memory::FastCopy(buffer_ + data_ptr_offset, name, NAME_LEN);
313 LibXR::Memory::FastCopy(buffer_ + data_ptr_offset + NAME_LEN, data, size);
314
315 KeyInfo key_buf = {0, static_cast<uint8_t>(NAME_LEN), static_cast<uint32_t>(size)};
316 LibXR::Memory::FastCopy(buffer_ + key_buf_offset, &key_buf, sizeof(KeyInfo));
317 if (last_key_offset)
318 {
319 SetNestKeyExist(last_key_offset, 1);
320 }
321
322 Save();
323 return ErrorCode::OK;
324}
void Save()
保存当前缓冲区内容到 Flash (Save the current buffer content to Flash).
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
LibXR 命名空间
Definition ch32_can.hpp:14
@ FULL
已满 | Full
@ OK
操作成功 | Operation successful
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量
Definition libxr_def.hpp:98
Flash 存储的块信息结构 (Structure representing a Flash storage block).
Definition layout.hpp:164
键信息结构,存储键的元数据 (Structure containing key metadata).
Definition layout.hpp:106

◆ EraseFlashOrExit()

void DatabaseRawSequential::EraseFlashOrExit ( size_t offset,
size_t size )
private

Definition at line 74 of file raw_sequential.cpp.

75{
76 REQUIRE(flash_.Erase(offset, size) == ErrorCode::OK);
77}
virtual ErrorCode Erase(size_t offset, size_t size)=0
Erases a section of the flash memory. 擦除闪存的指定区域。

◆ Get()

ErrorCode DatabaseRawSequential::Get ( Database::KeyBase & key)
overridevirtual

获取数据库中的键值 (Retrieve the key's value from the database).

Parameters
key需要获取的键 (Key to retrieve).
Returns
操作结果,如果找到则返回 ErrorCode::OK,否则返回 ErrorCode::NOT_FOUND (Operation result, returns ErrorCode::OK if found, otherwise ErrorCode::NOT_FOUND).

Implements LibXR::Database.

Definition at line 133 of file raw_sequential.cpp.

134{
135 auto ans = SearchKey(key.name_);
136 if (!ans)
137 {
139 }
140
141 KeyInfo key_buffer;
142 ReadFlashOrExit(ans, key_buffer);
143
144 if (key.raw_data_.size_ != key_buffer.GetDataSize())
145 {
146 return ErrorCode::FAILED;
147 }
148
149 GetKeyData(ans, key.raw_data_);
150
151 return ErrorCode::OK;
152}
RawData raw_data_
原始数据 (Raw data associated with the key).
Definition interface.hpp:34
const char * name_
键名 (Key name).
Definition interface.hpp:33
size_t size_
数据字节数 / Data size in bytes
@ NOT_FOUND
未找到 | Not found
@ FAILED
操作失败 | Operation failed
uint32_t GetDataSize() const
获取数据字节数 (Get the payload size in bytes).
Definition layout.hpp:154

◆ GetKeyData()

ErrorCode DatabaseRawSequential::GetKeyData ( size_t offset,
RawData data )
private

Definition at line 356 of file raw_sequential.cpp.

357{
358 KeyInfo key;
359 ReadFlashOrExit(offset, key);
360 if (key.GetDataSize() > data.size_)
361 {
362 return ErrorCode::FAILED;
363 }
364 auto data_offset = offset + sizeof(KeyInfo) + key.GetNameLength();
365 ReadFlashOrExit(data_offset, {data.addr_, key.GetDataSize()});
366 return ErrorCode::OK;
367}
void * addr_
数据起始地址 / Data start address
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).
Definition layout.hpp:139

◆ GetKeySize()

size_t DatabaseRawSequential::GetKeySize ( size_t offset)
private

Definition at line 225 of file raw_sequential.cpp.

226{
227 KeyInfo key;
228 ReadFlashOrExit(offset, key);
229 return sizeof(KeyInfo) + key.GetNameLength() + key.GetDataSize();
230}

◆ GetLastKey()

size_t DatabaseRawSequential::GetLastKey ( BlockType block)
private

Definition at line 237 of file raw_sequential.cpp.

238{
239 if (IsBlockEmpty(block))
240 {
241 return 0;
242 }
243
244 size_t offset = LibXR::OffsetOf(&FlashInfo::key);
245 while (HasLastKey(offset))
246 {
247 offset = GetNextKey(offset);
248 }
249 return offset;
250}
bool IsBlockEmpty(BlockType block)
判断块是否为空 (Check if block is empty).
KeyInfo key
该块的键信息 (Key metadata in this block).

◆ GetNextKey()

size_t DatabaseRawSequential::GetNextKey ( size_t offset)
private

Definition at line 232 of file raw_sequential.cpp.

233{
234 return offset + GetKeySize(offset);
235}

◆ HasLastKey()

bool DatabaseRawSequential::HasLastKey ( size_t offset)
private

Definition at line 218 of file raw_sequential.cpp.

219{
220 KeyInfo key;
221 ReadFlashOrExit(offset, key);
222 return key.GetNextKeyExist();
223}

◆ Init()

void DatabaseRawSequential::Init ( )

初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).

Definition at line 79 of file raw_sequential.cpp.

80{
82 FlashInfo* flash_data_ = reinterpret_cast<FlashInfo*>(buffer_);
83 flash_data_->header = FLASH_HEADER;
84 flash_data_->key = {0, 0, 0};
86
88 {
89 InitBlock(BlockType::BACKUP);
90 }
91
93 {
95 {
96 InitBlock(BlockType::MAIN);
97 }
98 else
99 {
100 ReadFlashOrExit(block_size_, {buffer_, max_buffer_size_});
101 EraseFlashOrExit(0, block_size_);
102 WriteFlashOrExit(0, {buffer_, max_buffer_size_});
103 }
104 }
105
106 Load();
107}
static constexpr uint8_t CHECKSUM_BYTE
校验字节 (Checksum byte).
static constexpr uint32_t FLASH_HEADER
Flash 头部标识 (Flash header identifier).
void Load()
从 Flash 加载数据到缓冲区 (Load data from Flash into the buffer).
bool IsBlockInited(BlockType block)
判断块是否已初始化 (Check if block is initialized).
bool IsBlockError(BlockType block)
判断块是否损坏 (Check if block has an error).
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
KeyInfo key
Definition layout.hpp:186
uint32_t header
Flash 块头签名 / Flash block-header signature.
Definition layout.hpp:182

◆ InitBlock()

void DatabaseRawSequential::InitBlock ( BlockType block)
private

Definition at line 154 of file raw_sequential.cpp.

155{
156 size_t offset = 0;
157 if (block == BlockType::BACKUP)
158 {
159 offset = block_size_;
160 }
161
162 EraseFlashOrExit(offset, block_size_);
163 WriteFlashOrExit(offset, {buffer_, max_buffer_size_});
164}

◆ IsBlockEmpty()

bool DatabaseRawSequential::IsBlockEmpty ( BlockType block)
private

判断块是否为空 (Check if block is empty).

Parameters
block需要检查的块 (Block to check).
Returns
如果为空返回 true,否则返回 false (Returns true if empty, false otherwise).

Definition at line 189 of file raw_sequential.cpp.

190{
191 size_t offset = 0;
192 if (block == BlockType::BACKUP)
193 {
194 offset = block_size_;
195 }
196 FlashInfo flash_data_;
197 ReadFlashOrExit(offset, flash_data_);
198 return flash_data_.key.GetNameLength() == 0;
199}
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).

◆ IsBlockError()

bool DatabaseRawSequential::IsBlockError ( BlockType block)
private

判断块是否损坏 (Check if block has an error).

Parameters
block需要检查的块 (Block to check).
Returns
如果损坏返回 true,否则返回 false (Returns true if corrupted, false otherwise).

Definition at line 206 of file raw_sequential.cpp.

207{
208 size_t offset = 0;
209 if (block == BlockType::BACKUP)
210 {
211 offset = block_size_;
212 }
213 uint8_t checksum_byte = 0;
214 ReadFlashOrExit(offset + max_buffer_size_ / sizeof(CHECKSUM_BYTE) - 1, checksum_byte);
215 return checksum_byte != CHECKSUM_BYTE;
216}

◆ IsBlockInited()

bool DatabaseRawSequential::IsBlockInited ( BlockType block)
private

判断块是否已初始化 (Check if block is initialized).

Parameters
block需要检查的块 (Block to check).
Returns
如果已初始化返回 true,否则返回 false (Returns true if initialized, false otherwise).

Definition at line 172 of file raw_sequential.cpp.

173{
174 size_t offset = 0;
175 if (block == BlockType::BACKUP)
176 {
177 offset = block_size_;
178 }
179 FlashInfo flash_data_;
180 ReadFlashOrExit(offset, flash_data_);
181 return flash_data_.header == FLASH_HEADER;
182}

◆ KeyDataCompare()

bool DatabaseRawSequential::KeyDataCompare ( size_t offset,
const void * data,
size_t size )
private

Definition at line 260 of file raw_sequential.cpp.

261{
262 KeyInfo key;
263 ReadFlashOrExit(offset, key);
264 size_t key_data_offset = offset + sizeof(KeyInfo) + key.GetNameLength();
265 uint8_t data_buffer;
266 for (size_t i = 0; i < size; i++)
267 {
268 ReadFlashOrExit(key_data_offset + i, data_buffer);
269 if (data_buffer != ((uint8_t*)data)[i])
270 {
271 return true;
272 }
273 }
274 return false;
275}

◆ KeyNameCompare()

bool DatabaseRawSequential::KeyNameCompare ( size_t offset,
const char * name )
private

Definition at line 277 of file raw_sequential.cpp.

278{
279 KeyInfo key;
280 ReadFlashOrExit(offset, key);
281 for (size_t i = 0; i < key.GetNameLength(); i++)
282 {
283 uint8_t data_buffer;
284 ReadFlashOrExit(offset + sizeof(KeyInfo) + i, data_buffer);
285 if (data_buffer != name[i])
286 {
287 return true;
288 }
289 }
290 return false;
291}

◆ Load()

void DatabaseRawSequential::Load ( )

Flash 加载数据到缓冲区 (Load data from Flash into the buffer).

Definition at line 118 of file raw_sequential.cpp.

118{ ReadFlashOrExit(0, {buffer_, max_buffer_size_}); }

◆ ReadFlashOrExit()

void DatabaseRawSequential::ReadFlashOrExit ( size_t offset,
RawData data )
private

Definition at line 64 of file raw_sequential.cpp.

65{
66 REQUIRE(flash_.Read(offset, data) == ErrorCode::OK);
67}
virtual ErrorCode Read(size_t offset, RawData data)
Reads data from the flash memory. 从闪存中读取数据。
Definition flash.cpp:14

◆ Restore()

void DatabaseRawSequential::Restore ( )

还原存储数据,清空 Flash 区域 (Restore storage data, clearing Flash memory area).

Definition at line 120 of file raw_sequential.cpp.

121{
123 FlashInfo* flash_data_ = reinterpret_cast<FlashInfo*>(buffer_);
124 flash_data_->header = FLASH_HEADER;
125 flash_data_->key = {0, 0, 0};
127 EraseFlashOrExit(0, block_size_);
128 EraseFlashOrExit(block_size_, block_size_);
129 WriteFlashOrExit(0, {buffer_, max_buffer_size_});
130 WriteFlashOrExit(block_size_, {buffer_, max_buffer_size_});
131}

◆ Save()

void DatabaseRawSequential::Save ( )

保存当前缓冲区内容到 Flash (Save the current buffer content to Flash).

Definition at line 109 of file raw_sequential.cpp.

110{
111 EraseFlashOrExit(block_size_, block_size_);
112 WriteFlashOrExit(block_size_, {buffer_, max_buffer_size_});
113
114 EraseFlashOrExit(0, block_size_);
115 WriteFlashOrExit(0, {buffer_, max_buffer_size_});
116}

◆ SearchKey()

size_t DatabaseRawSequential::SearchKey ( const char * name)
private

Definition at line 369 of file raw_sequential.cpp.

370{
372 {
373 return 0;
374 }
375
376 size_t key_offset = LibXR::OffsetOf(&FlashInfo::key);
377 while (true)
378 {
379 if (KeyNameCompare(key_offset, name) == 0)
380 {
381 return key_offset;
382 }
383 if (!HasLastKey(key_offset))
384 {
385 break;
386 }
387 key_offset = GetNextKey(key_offset);
388 }
389 return 0;
390}

◆ Set()

ErrorCode LibXR::DatabaseRawSequential::Set ( KeyBase & key,
RawData data )
inlineoverridevirtual

设置数据库中的键值 (Set the key's value in the database).

Parameters
key目标键 (Target key).
data需要存储的新值 (New value to store).
Returns
操作结果 (Operation result).

Implements LibXR::Database.

Definition at line 87 of file raw_sequential.hpp.

88 {
89 return SetKey(key.name_, data.addr_, data.size_);
90 }

◆ SetKey() [1/2]

ErrorCode DatabaseRawSequential::SetKey ( const char * name,
const void * data,
size_t size )
private

Definition at line 326 of file raw_sequential.cpp.

327{
328 if (size_t key_offset = SearchKey(name))
329 {
330 return SetKey(key_offset, data, size);
331 }
332 return ErrorCode::FAILED;
333}

◆ SetKey() [2/2]

ErrorCode DatabaseRawSequential::SetKey ( size_t offset,
const void * data,
size_t size )
private

Definition at line 335 of file raw_sequential.cpp.

336{
337 ASSERT(offset != 0);
338
339 KeyInfo key;
340 ReadFlashOrExit(offset, key);
341
342 if (key.GetDataSize() == size)
343 {
344 if (KeyDataCompare(offset, data, size))
345 {
346 LibXR::Memory::FastCopy(buffer_ + offset + sizeof(KeyInfo) + key.GetNameLength(),
347 data, size);
348 Save();
349 }
350 return ErrorCode::OK;
351 }
352
353 return ErrorCode::FAILED;
354}

◆ SetNestKeyExist()

void DatabaseRawSequential::SetNestKeyExist ( size_t offset,
bool exist )
private

Definition at line 252 of file raw_sequential.cpp.

253{
254 KeyInfo key;
255 ReadFlashOrExit(offset, key);
256 key.SetNextKeyExist(exist);
257 LibXR::Memory::FastCopy(buffer_ + offset, &key, sizeof(KeyInfo));
258}

◆ WriteFlashOrExit()

void DatabaseRawSequential::WriteFlashOrExit ( size_t offset,
ConstRawData data )
private

Definition at line 69 of file raw_sequential.cpp.

70{
71 REQUIRE(flash_.Write(offset, data) == ErrorCode::OK);
72}
virtual ErrorCode Write(size_t offset, ConstRawData data)=0
Writes data to the flash memory. 向闪存写入数据。

Field Documentation

◆ block_size_

uint32_t LibXR::DatabaseRawSequential::block_size_
private

Flash 块大小 (Flash block size).

Definition at line 215 of file raw_sequential.hpp.

◆ buffer_

uint8_t* LibXR::DatabaseRawSequential::buffer_
private

数据缓冲区 (Data buffer).

Definition at line 214 of file raw_sequential.hpp.

◆ CHECKSUM_BYTE

uint8_t LibXR::DatabaseRawSequential::CHECKSUM_BYTE = 0x56
staticconstexprprivate

校验字节 (Checksum byte).

Definition at line 211 of file raw_sequential.hpp.

◆ flash_

Flash& LibXR::DatabaseRawSequential::flash_
private

目标 Flash 存储设备 (Target Flash storage device).

Definition at line 213 of file raw_sequential.hpp.

◆ FLASH_HEADER

uint32_t LibXR::DatabaseRawSequential::FLASH_HEADER
staticconstexprprivate
Initial value:
=
static constexpr uint16_t LIBXR_DATABASE_VERSION
数据库存储格式版本号 (Database storage-format version).
Definition interface.hpp:17

Flash 头部标识 (Flash header identifier).

Definition at line 209 of file raw_sequential.hpp.

◆ max_buffer_size_

uint32_t LibXR::DatabaseRawSequential::max_buffer_size_
private

最大缓冲区大小 (Maximum buffer size).

Definition at line 216 of file raw_sequential.hpp.


The documentation for this class was generated from the following files: