aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pw_kvs/flash_memory.cc4
-rw-r--r--pw_kvs/key_value_store.cc9
-rw-r--r--pw_kvs/key_value_store_test.cc16
-rw-r--r--pw_kvs/public/pw_kvs/flash_memory.h30
4 files changed, 27 insertions, 32 deletions
diff --git a/pw_kvs/flash_memory.cc b/pw_kvs/flash_memory.cc
index b5b72ae99..ca5f5ffb6 100644
--- a/pw_kvs/flash_memory.cc
+++ b/pw_kvs/flash_memory.cc
@@ -47,7 +47,7 @@ StatusWithSize FlashPartition::Write(Address address, span<const byte> data) {
return flash_.Write(PartitionToFlashAddress(address), data);
}
-StatusWithSize FlashPartition::Write(
+StatusWithSize FlashPartition::WriteAligned(
const Address start_address, std::initializer_list<span<const byte>> data) {
byte buffer[64]; // TODO: Configure this?
@@ -89,7 +89,7 @@ StatusWithSize FlashPartition::Write(
!status.ok()) {
return StatusWithSize(status, bytes_written());
}
- address += remaining_write_size;
+ address += remaining_write_size; // Include padding bytes in the total.
}
return StatusWithSize(bytes_written());
diff --git a/pw_kvs/key_value_store.cc b/pw_kvs/key_value_store.cc
index 5f5bddc85..566309164 100644
--- a/pw_kvs/key_value_store.cc
+++ b/pw_kvs/key_value_store.cc
@@ -139,8 +139,6 @@ Status KeyValueStore::Init() {
Status KeyValueStore::LoadEntry(Address entry_address,
Address* next_entry_address) {
- const size_t alignment_bytes = partition_.alignment_bytes();
-
EntryHeader header;
TRY(ReadEntryHeader(entry_address, &header));
// TODO: Should likely add a "LogHeader" method or similar.
@@ -151,8 +149,7 @@ Status KeyValueStore::LoadEntry(Address entry_address,
DBG(" Key length = 0x%zx", size_t(header.key_length()));
DBG(" Value length = 0x%zx", size_t(header.value_length()));
DBG(" Entry size = 0x%zx", size_t(header.size()));
- DBG(" Padded size = 0x%zx",
- size_t(AlignUp(header.size(), alignment_bytes)));
+ DBG(" Alignment = 0x%zx", size_t(header.alignment_bytes()));
if (HeaderLooksLikeUnwrittenData(header)) {
return Status::NOT_FOUND;
@@ -741,8 +738,8 @@ Status KeyValueStore::AppendEntry(SectorDescriptor* sector,
// Handles writing multiple concatenated buffers, while breaking up the writes
// into alignment-sized blocks.
TRY_ASSIGN(
- size_t written,
- partition_.Write(
+ const size_t written,
+ partition_.WriteAligned(
address, {as_bytes(span(&header, 1)), as_bytes(span(key)), value}));
if (options_.verify_on_write) {
diff --git a/pw_kvs/key_value_store_test.cc b/pw_kvs/key_value_store_test.cc
index 27ce09a59..c2848d7c3 100644
--- a/pw_kvs/key_value_store_test.cc
+++ b/pw_kvs/key_value_store_test.cc
@@ -282,8 +282,7 @@ uint16_t CalcTestPartitionCrc() {
} // namespace
-TEST_F(KeyValueStoreTest,
- DISABLED_Put_SameKeySameValueRepeatedly_AlignedEntries) {
+TEST_F(KeyValueStoreTest, Put_SameKeySameValueRepeatedly_AlignedEntries) {
std::array<char, 8> value{'v', 'a', 'l', 'u', 'e', '6', '7', '\0'};
for (int i = 0; i < 1000; ++i) {
@@ -291,8 +290,7 @@ TEST_F(KeyValueStoreTest,
}
}
-TEST_F(KeyValueStoreTest,
- DISABLED_Put_SameKeySameValueRepeatedly_UnalignedEntries) {
+TEST_F(KeyValueStoreTest, Put_SameKeySameValueRepeatedly_UnalignedEntries) {
std::array<char, 7> value{'v', 'a', 'l', 'u', 'e', '6', '\0'};
for (int i = 0; i < 1000; ++i) {
@@ -300,9 +298,13 @@ TEST_F(KeyValueStoreTest,
}
}
-TEST_F(KeyValueStoreTest, DISABLED_Put_SameKeyDifferentValueRepeatedly) {
- for (uint64_t i = 0; i < 1000u; ++i) {
- ASSERT_EQ(Status::OK, kvs_.Put("The Key!", i));
+TEST_F(KeyValueStoreTest, Put_SameKeyDifferentValuesRepeatedly) {
+ std::array<char, 10> value{'v', 'a', 'l', 'u', 'e', '6', '7', '8', '9', '\0'};
+
+ for (int i = 0; i < 100; ++i) {
+ for (unsigned size = 0; size < value.size(); ++size) {
+ ASSERT_EQ(Status::OK, kvs_.Put("The Key!", i));
+ }
}
}
diff --git a/pw_kvs/public/pw_kvs/flash_memory.h b/pw_kvs/public/pw_kvs/flash_memory.h
index 01c012024..3bc2a2b4d 100644
--- a/pw_kvs/public/pw_kvs/flash_memory.h
+++ b/pw_kvs/public/pw_kvs/flash_memory.h
@@ -57,7 +57,10 @@ class FlashMemory {
alignment_(alignment),
start_address_(start_address),
start_sector_(sector_start),
- erased_memory_content_(erased_memory_content) {}
+ erased_memory_content_(erased_memory_content) {
+ // TODO: The smallest possible alignment is 1 B; 0 is invalid.
+ // DCHECK_NE(alignment_, 0);
+ }
virtual ~FlashMemory() = default;
@@ -138,24 +141,15 @@ class FlashPartition {
FlashMemory* flash,
uint32_t start_sector_index,
uint32_t sector_count,
+ uint32_t alignment_bytes = 0, // Defaults to flash alignment
PartitionPermission permission = PartitionPermission::kReadAndWrite)
: flash_(*flash),
start_sector_index_(start_sector_index),
sector_count_(sector_count),
+ alignment_bytes_(alignment_bytes == 0 ? flash_.alignment_bytes()
+ : alignment_bytes),
permission_(permission) {}
-#if 0
- constexpr FlashPartition(
- FlashMemory* flash,
- uint32_t start_sector_index,
- uint32_t end_sector_index,
- PartitionPermission permission = PartitionPermission::kReadAndWrite)
- : flash_(*flash),
- start_sector_index_(start_sector_index),
- sector_count_(end_sector_index - start_sector_index + 1),
- permission_(permission) {}
-#endif
-
virtual ~FlashPartition() = default;
// Performs any required partition or flash-level initialization.
@@ -191,8 +185,9 @@ class FlashPartition {
// UNKNOWN, on HAL error
virtual StatusWithSize Write(Address address, span<const std::byte> data);
- StatusWithSize Write(Address start_address,
- std::initializer_list<span<const std::byte>> data);
+ // Returns the total number of bytes written, including any padding.
+ StatusWithSize WriteAligned(
+ Address start_address, std::initializer_list<span<const std::byte>> data);
// Check to see if chunk of flash memory is erased. Address and len need to
// be aligned with FlashMemory.
@@ -214,9 +209,9 @@ class FlashPartition {
size_t size_bytes() const { return sector_count() * sector_size_bytes(); }
- virtual size_t alignment_bytes() const { return flash_.alignment_bytes(); }
+ size_t alignment_bytes() const { return alignment_bytes_; }
- virtual size_t sector_count() const { return sector_count_; }
+ size_t sector_count() const { return sector_count_; }
// Convert a FlashMemory::Address to an MCU pointer, this can be used for
// memory mapped reads. Return NULL if the memory is not memory mapped.
@@ -247,6 +242,7 @@ class FlashPartition {
FlashMemory& flash_;
const uint32_t start_sector_index_;
const uint32_t sector_count_;
+ const uint32_t alignment_bytes_;
const PartitionPermission permission_;
};