pw_kvs: Add alignment check to FlashPartition
In FlashPartition add checks to verify Write and Erase operations have
proper alignment.
Update comments in flash_memory.h to reflect current standards.
Change-Id: Iae270c2f6fdacf1fbaca135edc2472775913290e
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/15620
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: David Rogers <davidrogers@google.com>
diff --git a/pw_kvs/public/pw_kvs/flash_memory.h b/pw_kvs/public/pw_kvs/flash_memory.h
index a9ad8b2..2ba5ea1 100644
--- a/pw_kvs/public/pw_kvs/flash_memory.h
+++ b/pw_kvs/public/pw_kvs/flash_memory.h
@@ -52,38 +52,39 @@
virtual ~FlashMemory() = default;
virtual Status Enable() = 0;
+
virtual Status Disable() = 0;
+
virtual bool IsEnabled() const = 0;
+
virtual Status SelfTest() { return Status::UNIMPLEMENTED; }
// Erase num_sectors starting at a given address. Blocking call.
- // Address should be on a sector boundary.
+ // Address should be on a sector boundary. Returns:
//
- // OK: success
- // DEADLINE_EXCEEDED: timeout
- // INVALID_ARGUMENT: address is not sector-aligned
- // OUT_OF_RANGE: erases past the end of the memory
- //
+ // OK - success
+ // DEADLINE_EXCEEDED - timeout
+ // INVALID_ARGUMENT - address is not sector-aligned
+ // OUT_OF_RANGE - erases past the end of the memory
virtual Status Erase(Address flash_address, size_t num_sectors) = 0;
- // Reads bytes from flash into buffer. Blocking call.
+ // Reads bytes from flash into buffer. Blocking call. Returns:
//
- // OK: success
- // DEADLINE_EXCEEDED: timeout
- // OUT_OF_RANGE: write does not fit in the flash memory
+ // OK - success
+ // DEADLINE_EXCEEDED - timeout
+ // OUT_OF_RANGE - write does not fit in the flash memory
virtual StatusWithSize Read(Address address, std::span<std::byte> output) = 0;
StatusWithSize Read(Address address, void* buffer, size_t len) {
return Read(address, std::span(static_cast<std::byte*>(buffer), len));
}
- // Writes bytes to flash. Blocking call.
+ // Writes bytes to flash. Blocking call. Returns:
//
- // OK: success
- // DEADLINE_EXCEEDED: timeout
- // INVALID_ARGUMENT: address or data size are not aligned
- // OUT_OF_RANGE: write does not fit in the memory
- //
+ // OK - success
+ // DEADLINE_EXCEEDED - timeout
+ // INVALID_ARGUMENT - address or data size are not aligned
+ // OUT_OF_RANGE - write does not fit in the memory
virtual StatusWithSize Write(Address destination_flash_address,
std::span<const std::byte> data) = 0;
@@ -102,14 +103,20 @@
// sector start is not 0. (ex.: cases where there are portions of flash
// that should be handled independently).
constexpr uint32_t start_sector() const { return start_sector_; }
+
constexpr size_t sector_size_bytes() const { return sector_size_; }
+
constexpr size_t sector_count() const { return flash_sector_count_; }
+
constexpr size_t alignment_bytes() const { return alignment_; }
+
constexpr size_t size_bytes() const {
return sector_size_ * flash_sector_count_;
}
+
// Address of the start of flash (the address of sector 0)
constexpr uint32_t start_address() const { return start_address_; }
+
constexpr std::byte erased_memory_content() const {
return erased_memory_content_;
}
@@ -190,42 +197,47 @@
virtual Status Init() { return Status::OK; }
// Erase num_sectors starting at a given address. Blocking call.
- // Address should be on a sector boundary.
- // Returns: OK, on success.
- // TIMEOUT, on timeout.
- // INVALID_ARGUMENT, if address or sector count is invalid.
- // PERMISSION_DENIED, if partition is read only.
- // UNKNOWN, on HAL error
+ // Address must be on a sector boundary. Returns:
+ //
+ // OK - success.
+ // TIMEOUT - on timeout.
+ // INVALID_ARGUMENT - address or sector count is invalid.
+ // PERMISSION_DENIED - partition is read only.
+ // UNKNOWN - HAL error
virtual Status Erase(Address address, size_t num_sectors);
Status Erase() { return Erase(0, this->sector_count()); }
- // Reads bytes from flash into buffer. Blocking call.
- // Returns: OK, on success.
- // TIMEOUT, on timeout.
- // INVALID_ARGUMENT, if address or length is invalid.
- // UNKNOWN, on HAL error
+ // Reads bytes from flash into buffer. Blocking call. Returns:
+ //
+ // OK - success.
+ // TIMEOUT - on timeout.
+ // INVALID_ARGUMENT - address or length is invalid.
+ // UNKNOWN - HAL error
virtual StatusWithSize Read(Address address, std::span<std::byte> output);
StatusWithSize Read(Address address, size_t length, void* output) {
return Read(address, std::span(static_cast<std::byte*>(output), length));
}
- // Writes bytes to flash. Blocking call.
- // Returns: OK, on success.
- // TIMEOUT, on timeout.
- // INVALID_ARGUMENT, if address or length is invalid.
- // PERMISSION_DENIED, if partition is read only.
- // UNKNOWN, on HAL error
+ // Writes bytes to flash. Address and data.size_bytes() must both be a
+ // multiple of alignment_bytes(). Blocking call. Returns:
+ //
+ // OK - success.
+ // TIMEOUT - on timeout.
+ // INVALID_ARGUMENT - address or length is invalid.
+ // PERMISSION_DENIED - partition is read only.
+ // UNKNOWN - HAL error
virtual StatusWithSize Write(Address address,
std::span<const std::byte> data);
// Check to see if chunk of flash partition is erased. Address and len need to
- // be aligned with FlashMemory.
- // Returns: OK, on success.
- // TIMEOUT, on timeout.
- // INVALID_ARGUMENT, if address or length is invalid.
- // UNKNOWN, on HAL error
+ // be aligned with FlashMemory. Returns:
+ //
+ // OK - success.
+ // TIMEOUT - on timeout.
+ // INVALID_ARGUMENT - address or length is invalid.
+ // UNKNOWN - HAL error
// TODO: Result<bool>
virtual Status IsRegionErased(Address source_flash_address,
size_t len,
@@ -251,6 +263,7 @@
size_t size_bytes() const { return sector_count() * sector_size_bytes(); }
+ // Alignment required for write address and write size.
size_t alignment_bytes() const { return alignment_bytes_; }
size_t sector_count() const { return sector_count_; }
@@ -278,6 +291,7 @@
protected:
Status CheckBounds(Address address, size_t len) const;
+
FlashMemory& flash() const { return flash_; }
private: