Skip to content

Commit

Permalink
storage subsystem improvements
Browse files Browse the repository at this point in the history
cleans up the public API for some other features and also saves some memory
  • Loading branch information
Univa committed Jan 21, 2024
1 parent 9c56e70 commit e434d7b
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 608 deletions.
17 changes: 15 additions & 2 deletions docs/src/content/docs/features/feature-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ __config_end = __config_start + LENGTH(CONFIG); /* add this */
- The value of `__config_start` and `__config_end` must be **relative to the start address of the FLASH section**.
- Note that in the above example, we subtract `ORIGIN(FLASH)` for this reason.

Finally, you can add `storage = "internal"` to your `#[keyboard]` macro invocation:
Finally, you can add `storage = "internal"` to your `#[keyboard]` macro invocation, and make sure to implement
`StorageDevice` for your keyboard:

```rust ins={5,7}
```rust ins={5,7,11-12}
#[keyboard(
// somewhere in your keyboard macro invocation ...
underglow(
Expand All @@ -78,8 +79,20 @@ Finally, you can add `storage = "internal"` to your `#[keyboard]` macro invocati
storage = "internal" // Add this
)]
struct MyKeyboard;

use rumcake::storage::StorageDevice;
impl StorageDevice for MyKeyboard {}
```

:::tip
By default, the `setup_storage_buffer()` function in the `StorageDevice` trait creates a buffer
with a size of 1024 bytes. You can override the implementation to increase the size of the
buffer to store values that may be larger, or you can decrease the size to save memory.

Keep in mind, that the size of this buffer must be large enough to store the largest possible value
that you will be reading, or writing from the storage peripheral.
:::

# Storage space considerations

The amount of space you want to allocate for storage highly depends on what features your keyboard uses.
Expand Down
35 changes: 17 additions & 18 deletions docs/src/content/docs/features/feature-via-vial.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ By default, changes you make to your keyboard in the Via app (e.g. changing your
lighting settings, etc.) will **NOT** be saved by default.

Optionally, you can add `use_storage`, and a `storage` driver to save Via data.
Be sure to also add `setup_via_storage_buffers!(<struct_name>)` to your `ViaKeyboard` implementation.

```rust del={5} ins={6-9,22-23}
use rumcake::keyboard;
Expand All @@ -82,24 +81,11 @@ use rumcake::keyboard;
// somewhere in your keyboard macro invocation ...
via,
via(
use_storage // Optional, if you want to save via configuration
use_storage // Optional, if you want to save Via configuration
),
storage = "internal" // You need to specify a storage driver if you specified `use_storage`. See feature-storage.md for more information.
)]
struct MyKeyboard;

// Via setup
use rumcake::via::ViaKeyboard;
impl ViaKeyboard for MyKeyboard {
// OPTIONAL, this example assumes you are using simple-backlight-matrix.
const BACKLIGHT_TYPE: Option<BacklightType> = Some(BacklightType::SimpleBacklightMatrix)

// OPTIONAL, include this if you want to create macros using the Via app.
rumcake::setup_macro_buffer!(512, 16) // Max number of bytes that can be taken up by macros, followed by the max number of macros that can be created.

// Required if you specify `use_storage`
rumcake::setup_via_storage_buffers!(MyKeyboard);
}
```

You will need to do additional setup for your selected storage driver as well.
Expand Down Expand Up @@ -143,13 +129,26 @@ impl VialKeyboard for MyKeyboard {
const VIAL_KEYBOARD_UID: [u8; 8] = [0; 8]; // Change this
const VIAL_UNLOCK_COMBO: &'static [(u8, u8)] = &[(0, 1), (0, 0)]; // Matrix positions used to unlock VIAL (row, col), set it to whatever you want
const KEYBOARD_DEFINITION: &'static [u8] = &GENERATED_KEYBOARD_DEFINITION;
// rumcake::setup_vial_storage_buffers!(MyKeyboard); // Optional, only required if you specify `use_storage`
}
```

:::caution
Similarly to the previous caution, if you specify `use_storage`, be sure to also add
`setup_vial_storage_buffers!(<struct_name>)` to the `VialKeyboard` implementation.
Similarly to the previous caution, you need to specify `use_storage`, to save Vial data:

```rust del={5} ins={6-9,22-23}
use rumcake::keyboard;

#[keyboard(
// somewhere in your keyboard macro invocation ...
vial,
vial(
use_storage // Optional, if you want to save Vial configuration
),
storage = "internal" // You need to specify a storage driver if you specified `use_storage`. See feature-storage.md for more information.
)]
struct MyKeyboard;
```

:::

## Compiling Vial Definitions
Expand Down
30 changes: 20 additions & 10 deletions rumcake-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,9 @@ fn setup_storage_driver(driver: &str, uses_bluetooth: bool) -> Option<TokenStrea
let config_start = unsafe { &rumcake::hw::__config_start as *const u32 as usize };
let config_end = unsafe { &rumcake::hw::__config_end as *const u32 as usize };
static mut READ_BUF: [u8; rumcake::hw::mcu::nrf_softdevice::ERASE_SIZE] = [0; rumcake::hw::mcu::nrf_softdevice::ERASE_SIZE];
static DATABASE: rumcake::storage::Database<'static, rumcake::hw::nrf_softdevice::Flash> = rumcake::storage::Database::new();
DATABASE.setup(flash, config_start, config_end, unsafe { &mut READ_BUF }).await;
static mut OP_BUF: [u8; rumcake::hw::mcu::nrf_softdevice::ERASE_SIZE] = [0; rumcake::hw::mcu::nrf_softdevice::ERASE_SIZE];
static DATABASE: rumcake::storage::StorageService<'static, rumcake::hw::nrf_softdevice::Flash> = rumcake::storage::Database::new();
unsafe { DATABASE.setup(flash, config_start, config_end, &mut read_buf, &mut op_buf).await; }
})
} else {
Some(quote! {
Expand All @@ -339,8 +340,9 @@ fn setup_storage_driver(driver: &str, uses_bluetooth: bool) -> Option<TokenStrea
let config_start = unsafe { &rumcake::hw::__config_start as *const u32 as usize };
let config_end = unsafe { &rumcake::hw::__config_end as *const u32 as usize };
static mut READ_BUF: [u8; rumcake::hw::mcu::Flash::ERASE_SIZE] = [0; rumcake::hw::mcu::Flash::ERASE_SIZE];
static DATABASE: rumcake::storage::Database<'static, rumcake::hw::mcu::Flash> = rumcake::storage::Database::new();
DATABASE.setup(flash, config_start, config_end, unsafe { &mut READ_BUF }).await;
static mut OP_BUF: [u8; rumcake::hw::mcu::Flash::ERASE_SIZE] = [0; rumcake::hw::mcu::Flash::ERASE_SIZE];
static DATABASE: rumcake::storage::StorageService<'static, rumcake::hw::mcu::Flash> = rumcake::storage::StorageService::new();
unsafe { DATABASE.setup(flash, config_start, config_end, &mut READ_BUF, &mut OP_BUF).await; }
})
}
}
Expand Down Expand Up @@ -413,8 +415,16 @@ pub fn main(
keyboard.storage.span() => compile_error!("Storage driver was specified, but rumcake's `storage` feature flag is not enabled. Please enable the feature.");
});
} else {
let driver_setup = setup_storage_driver(driver.as_str(), uses_bluetooth);
initialization.extend(driver_setup);
match setup_storage_driver(driver.as_str(), uses_bluetooth) {
Some(driver_setup) => {
initialization.extend(driver_setup);
}
None => {
initialization.extend(quote_spanned! {
driver.span() => compile_error!("Unknown storage driver.");
});
}
};
}
};

Expand Down Expand Up @@ -604,7 +614,7 @@ pub fn main(

if args.use_storage {
spawning.extend(quote! {
spawner.spawn(rumcake::underglow_storage_task!(&DATABASE)).unwrap();
spawner.spawn(rumcake::underglow_storage_task!(#kb_name, &DATABASE)).unwrap();
});
}

Expand Down Expand Up @@ -642,7 +652,7 @@ pub fn main(

if args.use_storage {
spawning.extend(quote! {
spawner.spawn(rumcake::simple_backlight_storage_task!(&DATABASE)).unwrap();
spawner.spawn(rumcake::simple_backlight_storage_task!(#kb_name, &DATABASE)).unwrap();
});
}

Expand Down Expand Up @@ -679,7 +689,7 @@ pub fn main(

if args.use_storage {
spawning.extend(quote! {
spawner.spawn(rumcake::simple_backlight_matrix_storage_task!(&DATABASE)).unwrap();
spawner.spawn(rumcake::simple_backlight_matrix_storage_task!(#kb_name, &DATABASE)).unwrap();
});
}

Expand Down Expand Up @@ -716,7 +726,7 @@ pub fn main(

if args.use_storage {
spawning.extend(quote! {
spawner.spawn(rumcake::rgb_backlight_matrix_storage_task!(&DATABASE)).unwrap();
spawner.spawn(rumcake::rgb_backlight_matrix_storage_task!(#kb_name, &DATABASE)).unwrap();
});
}

Expand Down
25 changes: 9 additions & 16 deletions rumcake/src/backlight/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,40 +370,35 @@ macro_rules! storage_module {
use embassy_time::Duration;
use embassy_time::Timer;
use embedded_storage_async::nor_flash::NorFlash;
use postcard::experimental::max_size::MaxSize;

use crate::storage::StorageDevice;

use super::BacklightConfig;
use super::BACKLIGHT_CONFIG_STATE;

pub(super) static BACKLIGHT_CONFIG_STATE_LISTENER: Signal<ThreadModeRawMutex, ()> =
Signal::new();

static mut BACKLIGHT_STORAGE_STATE: crate::storage::StorageServiceState<
{ core::mem::size_of::<TypeId>() },
{ BacklightConfig::POSTCARD_MAX_SIZE },
> = crate::storage::StorageServiceState::new();

pub(super) static BACKLIGHT_SAVE_SIGNAL: Signal<ThreadModeRawMutex, ()> = Signal::new();
};
}

macro_rules! storage_task_fn {
($name:tt, $key:ident) => {
#[rumcake_macros::task]
pub async fn $name<F: NorFlash>(
database: &'static crate::storage::Database<'static, F>,
pub async fn $name<K: StorageDevice, F: NorFlash>(
_k: K,
database: &crate::storage::StorageService<'static, F>,
) where
[(); F::ERASE_SIZE]:,
{
{
let mut database = database.lock().await;

// Check stored backlight config metadata (type id) to see if it has changed
let metadata: [u8; core::mem::size_of::<TypeId>()] =
unsafe { core::mem::transmute(TypeId::of::<BacklightConfig>()) };
let _ = database
.initialize(
unsafe { &mut BACKLIGHT_STORAGE_STATE },
.check_metadata(
K::get_storage_buffer(),
crate::storage::StorageKey::$key,
&metadata,
)
Expand All @@ -412,7 +407,7 @@ macro_rules! storage_task_fn {
// Get backlight config from storage
if let Ok(config) = database
.read(
unsafe { &mut BACKLIGHT_STORAGE_STATE },
K::get_storage_buffer(),
crate::storage::StorageKey::$key,
)
.await
Expand All @@ -430,10 +425,8 @@ macro_rules! storage_task_fn {

let save = || async {
let _ = database
.lock()
.await
.write(
unsafe { &mut BACKLIGHT_STORAGE_STATE },
K::get_storage_buffer(),
crate::storage::StorageKey::$key,
BACKLIGHT_CONFIG_STATE.get().await,
)
Expand Down
Loading

0 comments on commit e434d7b

Please sign in to comment.