POC reading and writing spectre sites
This commit is contained in:
parent
a3a95b179b
commit
0cb6209d4b
2
firmware/Cargo.lock
generated
2
firmware/Cargo.lock
generated
|
|
@ -18,6 +18,7 @@ dependencies = [
|
||||||
"ekv",
|
"ekv",
|
||||||
"embassy-embedded-hal",
|
"embassy-embedded-hal",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
|
"embassy-sync 0.6.2",
|
||||||
"embassy-sync 0.7.2",
|
"embassy-sync 0.7.2",
|
||||||
"embassy-time",
|
"embassy-time",
|
||||||
"embedded-cli",
|
"embedded-cli",
|
||||||
|
|
@ -1692,6 +1693,7 @@ dependencies = [
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"heapless 0.8.0",
|
"heapless 0.8.0",
|
||||||
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ embassy-executor = { version = "0.9", features = ["log"] }
|
||||||
embassy-time = { version = "0.5.0", features = ["log"] }
|
embassy-time = { version = "0.5.0", features = ["log"] }
|
||||||
embassy-embedded-hal = "0.5.0"
|
embassy-embedded-hal = "0.5.0"
|
||||||
embassy-sync = { version = "0.7.2", features = ["log"] }
|
embassy-sync = { version = "0.7.2", features = ["log"] }
|
||||||
|
embassy-sync-old = { package = "embassy-sync", version = "0.6.2", features = ["log"] }
|
||||||
esp-backtrace = { version = "0.18", default-features = false, features = [
|
esp-backtrace = { version = "0.18", default-features = false, features = [
|
||||||
"esp32s3",
|
"esp32s3",
|
||||||
"println",
|
"println",
|
||||||
|
|
@ -97,7 +98,8 @@ features = [
|
||||||
"crc",
|
"crc",
|
||||||
"max-page-count-2048",
|
"max-page-count-2048",
|
||||||
"max-key-size-256",
|
"max-key-size-256",
|
||||||
"max-value-size-65536",
|
# "max-value-size-65536",
|
||||||
|
"max-value-size-1024",
|
||||||
# These must adhere to `FlashStorage`'s parameters.
|
# These must adhere to `FlashStorage`'s parameters.
|
||||||
"align-4",
|
"align-4",
|
||||||
"page-size-4096",
|
"page-size-4096",
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,16 @@ use core::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::{borrow::Cow, boxed::Box, vec::Vec};
|
use alloc::{borrow::Cow, boxed::Box, vec::Vec};
|
||||||
use ekv::{Database, flash::PageID};
|
use ekv::{
|
||||||
|
Database, ReadTransaction,
|
||||||
|
flash::{Flash, PageID},
|
||||||
|
};
|
||||||
use embassy_embedded_hal::{adapter::BlockingAsync, flash::partition::Partition};
|
use embassy_embedded_hal::{adapter::BlockingAsync, flash::partition::Partition};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, RawMutex};
|
||||||
use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash};
|
||||||
use esp_hal::rng::Trng;
|
use esp_hal::rng::Trng;
|
||||||
use esp_storage::FlashStorage;
|
use esp_storage::FlashStorage;
|
||||||
use log::info;
|
use log::{debug, info};
|
||||||
|
|
||||||
pub type PartitionAcid =
|
pub type PartitionAcid =
|
||||||
Partition<'static, CriticalSectionRawMutex, BlockingAsync<FlashStorage<'static>>>;
|
Partition<'static, CriticalSectionRawMutex, BlockingAsync<FlashStorage<'static>>>;
|
||||||
|
|
@ -241,7 +244,7 @@ impl<'a> IntoIterator for DbPathSpectreUsers {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DbPathSpectreUserSites<'a> {
|
pub struct DbPathSpectreUserSites<'a> {
|
||||||
username: DbPathSegment<'a>,
|
pub username: DbPathSegment<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoIterator for DbPathSpectreUserSites<'a> {
|
impl<'a> IntoIterator for DbPathSpectreUserSites<'a> {
|
||||||
|
|
@ -260,8 +263,8 @@ impl<'a> IntoIterator for DbPathSpectreUserSites<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DbPathSpectreUserSite<'a> {
|
pub struct DbPathSpectreUserSite<'a> {
|
||||||
user_sites: DbPathSpectreUserSites<'a>,
|
pub user_sites: DbPathSpectreUserSites<'a>,
|
||||||
site: DbPathSegment<'a>,
|
pub site: DbPathSegment<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoIterator for DbPathSpectreUserSite<'a> {
|
impl<'a> IntoIterator for DbPathSpectreUserSite<'a> {
|
||||||
|
|
@ -275,3 +278,42 @@ impl<'a> IntoIterator for DbPathSpectreUserSite<'a> {
|
||||||
.chain(core::iter::once(self.site))
|
.chain(core::iter::once(self.site))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ReadTransactionExt<F>
|
||||||
|
where
|
||||||
|
F: Flash,
|
||||||
|
{
|
||||||
|
async fn read_to_vec<'b>(
|
||||||
|
&self,
|
||||||
|
key: &[u8],
|
||||||
|
buffer: &'b mut Vec<u8>,
|
||||||
|
) -> Result<&'b mut [u8], ekv::ReadError<F::Error>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, F, M> ReadTransactionExt<F> for ReadTransaction<'a, F, M>
|
||||||
|
where
|
||||||
|
F: Flash + 'a,
|
||||||
|
M: embassy_sync_old::blocking_mutex::raw::RawMutex + 'a,
|
||||||
|
{
|
||||||
|
async fn read_to_vec<'b>(
|
||||||
|
&self,
|
||||||
|
key: &[u8],
|
||||||
|
buffer: &'b mut Vec<u8>,
|
||||||
|
) -> Result<&'b mut [u8], ekv::ReadError<F::Error>> {
|
||||||
|
if buffer.len() == 0 {
|
||||||
|
buffer.resize(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match self.read(key, buffer.as_mut_slice()).await {
|
||||||
|
Ok(size) => break Ok(&mut buffer[..size]),
|
||||||
|
Err(ekv::ReadError::BufferTooSmall) => {
|
||||||
|
let new_size = buffer.len() * 2;
|
||||||
|
debug!("Resizing read buffer to {new_size} bytes.");
|
||||||
|
buffer.resize(new_size, 0)
|
||||||
|
}
|
||||||
|
Err(error) => break Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ use esp_hal::lcd_cam::LcdCam;
|
||||||
use esp_hal::lcd_cam::lcd::dpi::Dpi;
|
use esp_hal::lcd_cam::lcd::dpi::Dpi;
|
||||||
use esp_hal::mcpwm::{McPwm, PeripheralClockConfig};
|
use esp_hal::mcpwm::{McPwm, PeripheralClockConfig};
|
||||||
use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock};
|
use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock};
|
||||||
|
use esp_hal::ram;
|
||||||
use esp_hal::rng::TrngSource;
|
use esp_hal::rng::TrngSource;
|
||||||
use esp_hal::sha::{Sha, ShaBackend};
|
use esp_hal::sha::{Sha, ShaBackend};
|
||||||
use esp_hal::system::Stack;
|
use esp_hal::system::Stack;
|
||||||
|
|
@ -151,7 +152,9 @@ async fn main(_spawner: Spawner) {
|
||||||
// TODO: Can we combine the regular link section with dram2?
|
// TODO: Can we combine the regular link section with dram2?
|
||||||
// esp_alloc::heap_allocator!(size: 80 * 1024);
|
// esp_alloc::heap_allocator!(size: 80 * 1024);
|
||||||
// esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 72 * 1024);
|
// esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 72 * 1024);
|
||||||
esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 64 * 1024);
|
//esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 64 * 1024);
|
||||||
|
esp_alloc::heap_allocator!(#[ram(reclaimed)] size: 72 * 1024);
|
||||||
|
esp_alloc::heap_allocator!(size: 16 * 1024);
|
||||||
info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats());
|
info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats());
|
||||||
|
|
||||||
// Initialize the PSRAM allocator.
|
// Initialize the PSRAM allocator.
|
||||||
|
|
@ -164,10 +167,12 @@ async fn main(_spawner: Spawner) {
|
||||||
MemoryCapability::External.into(),
|
MemoryCapability::External.into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
info!(
|
||||||
|
"PSRAM allocator initialized with capacity of {} MiB!",
|
||||||
|
psram_size / 1024 / 1024
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("PSRAM allocator initialized!");
|
|
||||||
|
|
||||||
// let mut io = Io::new(peripherals.IO_MUX);
|
// let mut io = Io::new(peripherals.IO_MUX);
|
||||||
// io.set_interrupt_handler(interrupt_handler);
|
// io.set_interrupt_handler(interrupt_handler);
|
||||||
|
|
||||||
|
|
@ -376,7 +381,7 @@ async fn main(_spawner: Spawner) {
|
||||||
let window_size = [framebuffer.height, framebuffer.width];
|
let window_size = [framebuffer.height, framebuffer.width];
|
||||||
let framebuffer_ptr = FramebufferPtr(framebuffer.as_target_pixels() as _);
|
let framebuffer_ptr = FramebufferPtr(framebuffer.as_target_pixels() as _);
|
||||||
|
|
||||||
static SECOND_CORE_STACK: StaticCell<Stack<{ 8192 * 2 }>> = StaticCell::new();
|
static SECOND_CORE_STACK: StaticCell<Stack<{ 16 * 1024 }>> = StaticCell::new();
|
||||||
let second_core_stack = SECOND_CORE_STACK.init(Stack::new());
|
let second_core_stack = SECOND_CORE_STACK.init(Stack::new());
|
||||||
esp_rtos::start_second_core(
|
esp_rtos::start_second_core(
|
||||||
peripherals.CPU_CTRL,
|
peripherals.CPU_CTRL,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,10 @@ use spectre_api_sys::{
|
||||||
use crate::FRAME_DURATION_MIN;
|
use crate::FRAME_DURATION_MIN;
|
||||||
use crate::{
|
use crate::{
|
||||||
SIGNAL_LCD_SUBMIT, SIGNAL_UI_RENDER,
|
SIGNAL_LCD_SUBMIT, SIGNAL_UI_RENDER,
|
||||||
db::{AcidDatabase, DbKey, DbPathSpectreUsers, PartitionAcid},
|
db::{
|
||||||
|
AcidDatabase, DbKey, DbPathSpectreUserSite, DbPathSpectreUserSites, DbPathSpectreUsers,
|
||||||
|
PartitionAcid, ReadTransactionExt,
|
||||||
|
},
|
||||||
ui::backend::SlintBackend,
|
ui::backend::SlintBackend,
|
||||||
util::DurationExt,
|
util::DurationExt,
|
||||||
};
|
};
|
||||||
|
|
@ -123,6 +126,21 @@ struct SpectreSiteConfig {
|
||||||
last_used: NaiveDateTime,
|
last_used: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SpectreSiteConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
algorithm: SpectreAlgorithm::Current,
|
||||||
|
counter: SpectreCounter::Default,
|
||||||
|
result_type: SpectreResultType::SpectreResultDefaultResult,
|
||||||
|
password: None,
|
||||||
|
login_type: SpectreResultType::SpectreResultDefaultLogin,
|
||||||
|
login_name: None,
|
||||||
|
uses: 0,
|
||||||
|
last_used: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
struct SpectreSite {
|
struct SpectreSite {
|
||||||
username: String,
|
username: String,
|
||||||
|
|
@ -142,6 +160,30 @@ pub async fn run_renderer_task(backend: SlintBackend, flash_part_acid: Partition
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut write = db.write_transaction().await;
|
let mut write = db.write_transaction().await;
|
||||||
|
write
|
||||||
|
.write(
|
||||||
|
&DbKey::new(DbPathSpectreUserSite {
|
||||||
|
user_sites: DbPathSpectreUserSites {
|
||||||
|
username: "test".into(),
|
||||||
|
},
|
||||||
|
site: "example.org".into(),
|
||||||
|
}),
|
||||||
|
&postcard::to_allocvec(&SpectreSiteConfig::default()).unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
write
|
||||||
|
.write(
|
||||||
|
&DbKey::new(DbPathSpectreUserSite {
|
||||||
|
user_sites: DbPathSpectreUserSites {
|
||||||
|
username: "test".into(),
|
||||||
|
},
|
||||||
|
site: "sub.example.org".into(),
|
||||||
|
}),
|
||||||
|
&postcard::to_allocvec(&SpectreSiteConfig::default()).unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
write
|
write
|
||||||
.write(
|
.write(
|
||||||
&DbKey::new(DbPathSpectreUsers),
|
&DbKey::new(DbPathSpectreUsers),
|
||||||
|
|
@ -155,19 +197,42 @@ pub async fn run_renderer_task(backend: SlintBackend, flash_part_acid: Partition
|
||||||
let read_value = {
|
let read_value = {
|
||||||
let read = db.read_transaction().await;
|
let read = db.read_transaction().await;
|
||||||
// TODO: https://github.com/embassy-rs/ekv/issues/20
|
// TODO: https://github.com/embassy-rs/ekv/issues/20
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = vec![0; 256];
|
||||||
let length = read
|
let slice = read
|
||||||
.read(&DbKey::new(DbPathSpectreUsers), &mut buffer)
|
.read_to_vec(&DbKey::new(DbPathSpectreUsers), &mut buffer)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
buffer.resize(length, 0);
|
let read_value = postcard::from_bytes::<SpectreUsersConfig>(&slice).unwrap();
|
||||||
read.read(&DbKey::new(DbPathSpectreUsers), &mut buffer)
|
|
||||||
|
let key_sites = DbKey::new(DbPathSpectreUserSites {
|
||||||
|
username: "test".into(),
|
||||||
|
});
|
||||||
|
let mut key_buffer = [0_u8; ekv::config::MAX_KEY_SIZE];
|
||||||
|
let mut cursor = read
|
||||||
|
.read_range(key_sites.range_of_children())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
postcard::from_bytes::<SpectreUsersConfig>(&buffer).unwrap()
|
while let Some((key_len, value_len)) =
|
||||||
|
cursor.next(&mut key_buffer, &mut buffer).await.unwrap()
|
||||||
|
{
|
||||||
|
let key = DbKey::from_raw(key_buffer[..key_len].into());
|
||||||
|
let mut key_segments = key.segments();
|
||||||
|
let value = &buffer[..value_len];
|
||||||
|
let site_config = postcard::from_bytes::<SpectreSiteConfig>(&value).unwrap();
|
||||||
|
let site = SpectreSite {
|
||||||
|
config: site_config,
|
||||||
|
username: key_segments.nth(2).unwrap().into(),
|
||||||
|
site_name: key_segments.nth(1).unwrap().into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("site = {:#?}", site);
|
||||||
|
}
|
||||||
|
|
||||||
|
read_value
|
||||||
};
|
};
|
||||||
|
|
||||||
|
info!("read_value = {:#?}", read_value);
|
||||||
assert_eq!(value, read_value, "values do not match");
|
assert_eq!(value, read_value, "values do not match");
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue