-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnvs.rs
More file actions
95 lines (82 loc) · 3.2 KB
/
Copy pathnvs.rs
File metadata and controls
95 lines (82 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use super::{OsError, OsResult};
use crate::re_esp;
use esp_idf_svc::nvs::{EspDefaultNvsPartition, EspNvs, NvsDefault};
/// Namespace used for the firmware's keys.
const NAMESPACE: &str = "pixelweather";
/// Key name for the last system error.
const LAST_OS_ERROR_KEY: &str = "last_error";
/// A high-level wrapper/driver for the Non-volatile storage driver.
///
/// Provides a simpler API for getting and storing data in the
/// NVS partition.
pub struct NonVolatileStorage(EspNvs<NvsDefault>);
impl NonVolatileStorage {
/// Initialize the driver on the default NVS partition.
pub fn new() -> OsResult<Self> {
let nvs_partition = re_esp!(EspDefaultNvsPartition::take(), NvsInit)?;
let nvs = re_esp!(EspNvs::new(nvs_partition, NAMESPACE, true), NvsInit)?;
Ok(Self(nvs))
}
/// Stores the last [`OsError`] that caused the firmware to fail.
///
/// # Errors
/// Returns an error if the underlying NVS driver fails ([`EspNvs::set_str`]).
pub fn store_last_os_error(&self, err: &OsError) -> OsResult<()> {
re_esp!(
self.0.set_str(LAST_OS_ERROR_KEY, err.to_string().as_str()),
NvsWrite
)
}
/// Gets the last system error ([`OsError`]) that caused the
/// firmware to fail stored using [`store_last_os_error()`](Self::store_last_os_error).
///
/// Returns [`Option::None`] if no error was stored previously.
///
/// # Errors
/// Returns an error if the underlying NVS driver fails.
pub fn get_last_os_error(&self) -> OsResult<Option<String>> {
self.get_key(LAST_OS_ERROR_KEY, false)
}
/// Deletes the last system error ([`OsError`]) stored using
/// [`store_last_os_error()`](Self::store_last_os_error) from the NVS.
///
/// # Errors
/// Returns an error if the underlying NVS driver fails.
pub fn clear_last_os_error(&self) -> OsResult<()> {
self.delete_key(LAST_OS_ERROR_KEY)
}
/// Deletes a value by it's key from the NVS.
///
/// # Errors
/// Returns an error if the underlying NVS driver fails, or the specified key
/// does not exist.
fn delete_key(&self, key: &str) -> OsResult<()> {
if !re_esp!(self.0.remove(key), NvsWrite)? {
return Err(OsError::InvalidNvsKey);
}
Ok(())
}
/// Get a value by it's key from the NVS.
///
/// If `delete_if_exists` is `true`, the value will be immediately deleted from the NVS
/// after reading.
///
/// Returns [`Option::None`] if the key does not exist.
///
/// # Errors
/// Returns an error if the underlying NVS driver fails ([`EspNvs::str_len`], [`EspNvs::get_str`],
/// [`EspNvs::remove`]).
fn get_key(&self, key: &str, delete_if_exists: bool) -> OsResult<Option<String>> {
let Some(length) = re_esp!(self.0.str_len(key), NvsRead)? else {
return Ok(None);
};
let mut buffer = vec![0u8; length];
re_esp!(self.0.get_str(key, &mut buffer), NvsRead)?;
buffer.pop(); // Buffer contains a NULL-terminated string
let err_string = String::from_utf8(buffer)?;
if delete_if_exists {
re_esp!(self.0.remove(key), NvsWrite)?;
}
Ok(Some(err_string))
}
}