diff options
-rw-r--r-- | pw_kvs/flash_memory.cc | 4 | ||||
-rw-r--r-- | pw_kvs/key_value_store.cc | 9 | ||||
-rw-r--r-- | pw_kvs/key_value_store_test.cc | 16 | ||||
-rw-r--r-- | pw_kvs/public/pw_kvs/flash_memory.h | 30 |
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_; }; |