flash: Add fns to store data in flash

- Writing to the wrong flash sector can cause MCU to stall
- Only 16KiB out of 128KiB in the sector is used to save RAM for compacting
This commit is contained in:
linuswck 2024-01-15 16:58:10 +08:00
parent 709eae8566
commit 74325a3cee
4 changed files with 162 additions and 8 deletions

105
Cargo.lock generated
View File

@ -8,7 +8,19 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80a21b9440a626c7fc8573a9e3d3a06b75c7c97754c2949bc7857b90353ca655"
dependencies = [
"as-slice",
"as-slice 0.2.1",
]
[[package]]
name = "as-slice"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
dependencies = [
"generic-array 0.12.4",
"generic-array 0.13.3",
"generic-array 0.14.7",
"stable_deref_trait",
]
[[package]]
@ -222,7 +234,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db9efecb57ab54fa918730f2874d7d37647169c50fa1357fecb81abee840b113"
dependencies = [
"heapless",
"heapless 0.7.17",
"nb 1.1.0",
"no-std-net",
]
@ -267,6 +279,43 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "generic-array"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "hash32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
dependencies = [
"byteorder",
]
[[package]]
name = "hash32"
version = "0.2.1"
@ -276,6 +325,19 @@ dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1"
dependencies = [
"as-slice 0.1.5",
"generic-array 0.13.3",
"hash32 0.1.1",
"serde",
"stable_deref_trait",
]
[[package]]
name = "heapless"
version = "0.7.17"
@ -283,7 +345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
dependencies = [
"atomic-polyfill",
"hash32",
"hash32 0.2.1",
"rustc_version 0.4.0",
"serde",
"spin",
@ -316,6 +378,7 @@ dependencies = [
"panic-halt",
"rtt-target",
"serde",
"sfkv",
"smoltcp",
"stm32-eth",
"stm32f4xx-hal",
@ -358,7 +421,7 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07df30ef660fa32d54836743fbdf8208747a559fc4296ec07dc12b6df65343b2"
dependencies = [
"heapless",
"heapless 0.7.17",
"log",
"miniconf_derive",
"minimq",
@ -387,7 +450,7 @@ dependencies = [
"bit_field",
"embedded-nal",
"embedded-time",
"heapless",
"heapless 0.7.17",
"num_enum",
"serde",
"smlang",
@ -505,6 +568,23 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
[[package]]
name = "postcard"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ba0d1b66f31fb374fede892eb4b0818ea819d5e7bc587345ce50a6949e782"
dependencies = [
"heapless 0.5.6",
"postcard-cobs",
"serde",
]
[[package]]
name = "postcard-cobs"
version = "0.1.5-pre"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c68cb38ed13fd7bc9dd5db8f165b7c8d9c1a315104083a2b10f11354c2af97f"
[[package]]
name = "powerfmt"
version = "0.2.0"
@ -635,7 +715,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c9e1ab533c0bc414c34920ec7e5f097101d126ed5eac1a1aac711222e0bbb33"
dependencies = [
"heapless",
"heapless 0.7.17",
"ryu",
"serde",
]
@ -651,6 +731,17 @@ dependencies = [
"syn 2.0.41",
]
[[package]]
name = "sfkv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25f5bfac3f66a7c10a6f37ee81aeaa471f4d35dc21665b59ad7c555adcb9e8aa"
dependencies = [
"byteorder",
"postcard",
"serde",
]
[[package]]
name = "smlang"
version = "0.6.0"
@ -680,7 +771,7 @@ dependencies = [
"bitflags",
"byteorder",
"cfg-if",
"heapless",
"heapless 0.7.17",
"log",
"managed",
]

View File

@ -33,7 +33,7 @@ fugit = "0.3.6"
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
miniconf = "0.6.3"
serde = { version = "1.0.158", features = ["derive"], default-features = false }
sfkv = "0.1"
[features]
semihosting = ["cortex-m-log/semihosting"]
RTT = []

62
src/device/flash_store.rs Normal file
View File

@ -0,0 +1,62 @@
use log::error;
use stm32f4xx_hal::{
flash::{Error, FlashExt},
pac::FLASH,
};
use sfkv::{Store, StoreBackend};
// Last flash sector is used to avoid overwriting the code in flash.
pub const FLASH_SECTOR: u8 = 11;
pub const FLASH_SECTOR_11_OFFSET: u32 = 0xE0000;
/// Only 16 KiB out of 128KiB in the Sector is used to save RAM
pub const RESERVED_MEMORY: usize = 0x4000;
static mut BACKUP_SPACE: [u8; RESERVED_MEMORY] = [0; RESERVED_MEMORY];
pub struct FlashBackend {
flash: FLASH,
}
fn get_offset() -> usize {
FLASH_SECTOR_11_OFFSET as usize
}
impl StoreBackend for FlashBackend {
type Data = [u8];
fn data(&self) -> &Self::Data {
&self.flash.read()[get_offset()..(get_offset() + RESERVED_MEMORY)]
}
type Error = Error;
fn erase(&mut self) -> Result<(), Self::Error> {
self.flash.unlocked().erase(FLASH_SECTOR)
}
fn program(&mut self, offset: usize, payload: &[u8]) -> Result<(), Self::Error> {
self.flash.unlocked()
.program(get_offset() + offset, payload.iter())
}
fn backup_space(&self) -> &'static mut [u8] {
unsafe { &mut BACKUP_SPACE }
}
}
pub type FlashStore = Store<FlashBackend>;
pub fn store(flash: FLASH) -> FlashStore {
let backend = FlashBackend { flash };
let mut store = FlashStore::new(backend);
match store.get_bytes_used() {
Ok(_) => {}
Err(e) => {
error!("corrupt store, erasing. error: {:?}", e);
let _ = store.erase()
.map_err(|e| error!("flash erase failed: {:?}", e));
}
}
store
}

View File

@ -4,3 +4,4 @@ pub mod log_setup;
pub mod rtt_logger;
pub mod sys_timer;
pub mod usb;
pub mod flash_store;