Skip to content

Commit

Permalink
storage service refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Univa committed Mar 31, 2024
1 parent 6145070 commit 030e9a0
Show file tree
Hide file tree
Showing 15 changed files with 563 additions and 566 deletions.
33 changes: 17 additions & 16 deletions docs/src/content/docs/features/feature-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,9 @@ __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(driver = "internal")` to your `#[keyboard]` macro invocation, and make sure to implement
`StorageDevice` for your keyboard:
Finally, you can add `storage(driver = "internal")` to your `#[keyboard]` macro invocation.

```rust ins={5,7-11,16-23}
```rust ins={5,7-11,16-20}
#[keyboard(
// somewhere in your keyboard macro invocation ...
underglow(
Expand All @@ -85,9 +84,6 @@ Finally, you can add `storage(driver = "internal")` to your `#[keyboard]` macro
)]
struct MyKeyboard;

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

// Required for RP2040, omit if you are not using an RP2040
use rumcake::hw::platform::setup_dma_channel;
impl RP2040FlashSettings for MyKeyboard {
Expand All @@ -104,16 +100,21 @@ shown in the example above. If you are not using RP2040, these things can be omi
:::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:

```rust del={3} ins={4}
impl StorageDevice for MyKeyboard {
fn get_storage_buffer() -> &'static mut [u8] {
static mut STORAGE_BUFFER: [u8; 1024] = [0; 1024];
static mut STORAGE_BUFFER: [u8; 32] = [0; 32];
unsafe { &mut STORAGE_BUFFER }
}
}
buffer to store values that may be larger, or you can decrease the size to save memory. This can
be done by adding `buffer_size` to your macro invocation:

```rust ins={8}
#[keyboard(
// somewhere in your keyboard macro invocation ...
storage(
driver = "internal",
// `flash_size` below is required for RP2040, omit if you are not using an RP2040.
// Should be equal to the total size of the flash chip (not the size of your CONFIG partition)
flash_size = 2097152,
buffer_size = 512
)
)]
struct MyKeyboard;
```

Keep in mind, that the size of this buffer must be large enough to store the largest possible value
Expand Down
23 changes: 20 additions & 3 deletions docs/src/content/docs/features/feature-via-vial.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ lighting settings, etc.) will **NOT** be saved by default.

Optionally, you can add `use_storage`, and a `storage` driver to save Via data.

```rust del={5} ins={6-10,22-23}
Additionally, you will need to call `connect_storage_service` in your `ViaKeyboard` implementation.

```rust del={5} ins={6-10,18}
use rumcake::keyboard;

#[keyboard(
Expand All @@ -97,6 +99,13 @@ use rumcake::keyboard;
storage(driver = "internal") // You need to specify a storage driver if you specified `use_storage`. See feature-storage.md for more information.
)]
struct MyKeyboard;

//...
use rumcake::via::connect_storage_service;
impl ViaKeyboard for MyKeyboardVia {
//...
connect_storage_service!(MyKeyboard)
}
```

You will need to do additional setup for your selected storage driver as well.
Expand Down Expand Up @@ -150,9 +159,10 @@ impl VialKeyboard for MyKeyboard {
```

:::caution
Similarly to the previous caution, you need to specify `use_storage`, to save Vial data:
Similarly to the previous caution, you need to specify `use_storage`, to save Vial data.
`connect_storage_service!` is still implemented inside `ViaKeyboard`:

```rust del={5} ins={6-10}
```rust del={5} ins={6-10,18}
use rumcake::keyboard;

#[keyboard(
Expand All @@ -165,6 +175,13 @@ use rumcake::keyboard;
storage = "internal" // You need to specify a storage driver if you specified `use_storage`. See feature-storage.md for more information.
)]
struct MyKeyboard;

//...
use rumcake::via::connect_storage_service;
impl ViaKeyboard for MyKeyboardVia {
//...
connect_storage_service!(MyKeyboard)
}
```

:::
Expand Down
105 changes: 91 additions & 14 deletions rumcake-macros/src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub(crate) struct ViaSettings {
pub(crate) struct StorageSettings {
driver: LitStr,
flash_size: Option<LitInt>,
buffer_size: Option<LitInt>,
}

enum SplitSettings<'a> {
Expand Down Expand Up @@ -266,38 +267,91 @@ fn setup_display_driver(

fn setup_storage_driver(
initialization: &mut TokenStream,
outer: &mut TokenStream,
traits: &mut HashMap<String, TokenStream>,
kb_name: &Ident,
config: &StorageSettings,
uses_bluetooth: bool,
) -> bool {
let buffer_size = if let Some(lit) = &config.buffer_size {
lit.base10_parse::<usize>().unwrap_or_else(|_| {
abort!(
lit,
"The provided buffer size could not be parsed as a usize value."
)
})
} else {
1024
};

match config.driver.value().as_str() {
"internal" => {
if cfg!(feature = "nrf") && uses_bluetooth {
// TODO: Fix storage on nrf-ble targets
outer.extend(quote! {
use ::rumcake::storage::FlashStorage;
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::nrf_softdevice::Flash, #kb_name> = ::rumcake::storage::StorageService::new();
impl ::rumcake::storage::StorageDevice for #kb_name {
type FlashStorageType = ::rumcake::hw::platform::nrf_softdevice::Flash;

fn get_storage_buffer() -> &'static mut [u8] {
static mut STORAGE_BUFFER: [u8; #buffer_size] = [0; #buffer_size];
unsafe { &mut STORAGE_BUFFER }
}

fn get_storage_service(
) -> &'static rumcake::storage::StorageService<'static, Self::FlashStorageType, Self>
where
[(); Self::FlashStorageType::ERASE_SIZE]:,
Self: Sized,
{
&DATABASE
}
}
});
initialization.extend(quote! {
use ::rumcake::storage::FlashStorage;
let flash = ::rumcake::hw::platform::setup_internal_softdevice_flash(sd);
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::platform::nrf_softdevice::Flash::ERASE_SIZE] = [0; ::rumcake::hw::platform::nrf_softdevice::Flash::ERASE_SIZE];
static mut OP_BUF: [u8; ::rumcake::hw::platform::nrf_softdevice::Flash::ERASE_SIZE] = [0; ::rumcake::hw::platform::nrf_softdevice::Flash::ERASE_SIZE];
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::nrf_softdevice::Flash> = ::rumcake::storage::StorageService::new();
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::nrf_softdevice::Flash, #kb_name> = ::rumcake::storage::StorageService::new();
unsafe { DATABASE.setup(flash, config_start, config_end, &mut READ_BUF, &mut OP_BUF).await; }
});

return false;
}

if cfg!(any(feature = "stm32", feature = "nrf")) {
outer.extend(quote! {
use ::rumcake::storage::FlashStorage;
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::Flash, #kb_name> = ::rumcake::storage::StorageService::new();
impl ::rumcake::storage::StorageDevice for #kb_name {
type FlashStorageType = ::rumcake::hw::platform::Flash;

fn get_storage_buffer() -> &'static mut [u8] {
static mut STORAGE_BUFFER: [u8; #buffer_size] = [0; #buffer_size];
unsafe { &mut STORAGE_BUFFER }
}

fn get_storage_service(
) -> &'static rumcake::storage::StorageService<'static, Self::FlashStorageType, Self>
where
[(); Self::FlashStorageType::ERASE_SIZE]:,
Self: Sized,
{
&DATABASE
}
}
});
initialization.extend(quote! {
use ::rumcake::storage::FlashStorage;
let flash = ::rumcake::hw::platform::setup_internal_flash();
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::platform::Flash::ERASE_SIZE] = [0; ::rumcake::hw::platform::Flash::ERASE_SIZE];
static mut OP_BUF: [u8; ::rumcake::hw::platform::Flash::ERASE_SIZE] = [0; ::rumcake::hw::platform::Flash::ERASE_SIZE];
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::Flash> = ::rumcake::storage::StorageService::new();
unsafe { DATABASE.setup(flash, config_start, config_end, &mut READ_BUF, &mut OP_BUF).await; }
});

Expand All @@ -323,14 +377,33 @@ fn setup_storage_driver(
return true;
}

initialization.extend(quote! {
outer.extend(quote! {
use ::rumcake::storage::FlashStorage;
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::Flash<#size>, #kb_name> = ::rumcake::storage::StorageService::new();
impl ::rumcake::storage::StorageDevice for #kb_name {
type FlashStorageType = ::rumcake::hw::platform::Flash<'static, #size>;

fn get_storage_buffer() -> &'static mut [u8] {
static mut STORAGE_BUFFER: [u8; #buffer_size] = [0; #buffer_size];
unsafe { &mut STORAGE_BUFFER }
}

fn get_storage_service(
) -> &'static rumcake::storage::StorageService<'static, Self::FlashStorageType, Self>
where
[(); Self::FlashStorageType::ERASE_SIZE]:,
Self: Sized,
{
&DATABASE
}
}
});
initialization.extend(quote! {
let flash = ::rumcake::hw::platform::setup_internal_flash::<#size>(<#kb_name as RP2040FlashSettings>::setup_dma_channel());
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::platform::embassy_rp::flash::ERASE_SIZE] = [0; ::rumcake::hw::platform::embassy_rp::flash::ERASE_SIZE];
static mut OP_BUF: [u8; ::rumcake::hw::platform::embassy_rp::flash::ERASE_SIZE] = [0; ::rumcake::hw::platform::embassy_rp::flash::ERASE_SIZE];
static DATABASE: ::rumcake::storage::StorageService<'static, ::rumcake::hw::platform::Flash<#size>> = ::rumcake::storage::StorageService::new();
unsafe { DATABASE.setup(flash, config_start, config_end, &mut READ_BUF, &mut OP_BUF).await; }
});

Expand Down Expand Up @@ -367,6 +440,7 @@ pub(crate) fn keyboard_main(
) -> TokenStream {
let mut initialization = TokenStream::new();
let mut spawning = TokenStream::new();
let mut outer = TokenStream::new();
let mut traits: HashMap<String, TokenStream> = HashMap::new();
let mut error = false;

Expand Down Expand Up @@ -419,6 +493,7 @@ pub(crate) fn keyboard_main(
} else {
error = setup_storage_driver(
&mut initialization,
&mut outer,
&mut traits,
&kb_name,
driver,
Expand Down Expand Up @@ -508,9 +583,7 @@ pub(crate) fn keyboard_main(
} else if args.use_storage.unwrap_or_default() {
let via_device = args.id;
spawning.extend(quote! {
spawner
.spawn(::rumcake::via_storage_task!(#kb_name, #via_device, &DATABASE))
.unwrap();
::rumcake::via::initialize_via_data(#kb_name).await;
});
}

Expand All @@ -526,9 +599,7 @@ pub(crate) fn keyboard_main(
} else if args.use_storage.unwrap_or_default() {
let via_device = args.id;
spawning.extend(quote! {
spawner
.spawn(::rumcake::vial_storage_task!(#kb_name, #via_device, &DATABASE))
.unwrap();
::rumcake::vial::initialize_vial_data(#kb_name).await;
});
}

Expand Down Expand Up @@ -599,7 +670,8 @@ pub(crate) fn keyboard_main(
let underglow_animator_storage = underglow_animator.create_storage_instance();
});
spawning.extend(quote! {
spawner.spawn(::rumcake::lighting_storage_task!(#kb_name, underglow_animator_storage, &DATABASE)).unwrap();
::rumcake::lighting::initialize_lighting_data(&underglow_animator_storage, &DATABASE);
spawner.spawn(::rumcake::lighting_storage_task!(underglow_animator_storage, &DATABASE)).unwrap();
});
}
spawning.extend(quote! {
Expand Down Expand Up @@ -630,7 +702,8 @@ pub(crate) fn keyboard_main(
let simple_backlight_animator_storage = simple_backlight_animator.create_storage_instance();
});
spawning.extend(quote! {
spawner.spawn(::rumcake::lighting_storage_task!(#kb_name, simple_backlight_animator_storage, &DATABASE)).unwrap();
::rumcake::lighting::initialize_lighting_data(&simple_backlight_animator_storage, &DATABASE);
spawner.spawn(::rumcake::lighting_storage_task!(simple_backlight_animator_storage, &DATABASE)).unwrap();
});
}
spawning.extend(quote! {
Expand Down Expand Up @@ -660,7 +733,8 @@ pub(crate) fn keyboard_main(
let simple_backlight_matrix_animator_storage = simple_backlight_matrix_animator.create_storage_instance();
});
spawning.extend(quote! {
spawner.spawn(::rumcake::lighting_storage_task!(#kb_name, simple_backlight_matrix_animator_storage, &DATABASE)).unwrap();
::rumcake::lighting::initialize_lighting_data(&simple_backlight_matrix_animator_storage, &DATABASE);
spawner.spawn(::rumcake::lighting_storage_task!(simple_backlight_matrix_animator_storage, &DATABASE)).unwrap();
});
}
spawning.extend(quote! {
Expand Down Expand Up @@ -690,7 +764,8 @@ pub(crate) fn keyboard_main(
let rgb_backlight_matrix_animator_storage = rgb_backlight_matrix_animator.create_storage_instance();
});
spawning.extend(quote! {
spawner.spawn(::rumcake::lighting_storage_task!(#kb_name, rgb_backlight_matrix_animator_storage, &DATABASE)).unwrap();
::rumcake::lighting::initialize_lighting_data(&rgb_backlight_matrix_animator_storage, &DATABASE);
spawner.spawn(::rumcake::lighting_storage_task!(rgb_backlight_matrix_animator_storage, &DATABASE)).unwrap();
});
}
spawning.extend(quote! {
Expand Down Expand Up @@ -754,6 +829,8 @@ pub(crate) fn keyboard_main(

#(#final_traits)*

#outer

#str
}
}
Expand Down
6 changes: 6 additions & 0 deletions rumcake-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,12 @@ pub fn setup_macro_buffer(input: proc_macro::TokenStream) -> proc_macro::TokenSt
via::setup_macro_buffer(args).into()
}

#[proc_macro]
pub fn connect_storage_service(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ident = parse_macro_input!(input as Ident);
via::connect_storage_service(ident).into()
}

mod vial;

#[proc_macro]
Expand Down
20 changes: 19 additions & 1 deletion rumcake-macros/src/via.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use proc_macro2::{Literal, TokenStream};
use proc_macro2::{Ident, Literal, TokenStream};
use proc_macro_error::{abort, OptionExt};
use quote::quote;
use syn::punctuated::Punctuated;
Expand Down Expand Up @@ -31,3 +31,21 @@ pub fn setup_macro_buffer(args: Punctuated<Literal, Token![,]>) -> TokenStream {
}
}
}

pub fn connect_storage_service(ident: Ident) -> TokenStream {
quote! {
type StorageType = #ident;
fn get_storage_service() -> Option<
&'static ::rumcake::storage::StorageService<
'static,
<Self::StorageType as ::rumcake::storage::StorageDevice>::FlashStorageType,
Self::StorageType,
>,
>
where
[(); <<Self::StorageType as ::rumcake::storage::StorageDevice>::FlashStorageType as ::rumcake::storage::FlashStorage>::ERASE_SIZE]:,
{
Some(<Self::StorageType as ::rumcake::storage::StorageDevice>::get_storage_service())
}
}
}
4 changes: 0 additions & 4 deletions rumcake/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,9 @@ pub mod tasks {
pub use crate::usb::__usb_hid_via_write_task;
#[cfg(feature = "via")]
pub use crate::via::__via_process_task;
#[cfg(all(feature = "via", feature = "storage"))]
pub use crate::via::storage::__via_storage_task;

#[cfg(feature = "vial")]
pub use crate::vial::__vial_process_task;
#[cfg(all(feature = "vial", feature = "storage"))]
pub use crate::vial::storage::__vial_storage_task;

#[cfg(feature = "split-central")]
pub use crate::split::central::__central_task;
Expand Down
Loading

0 comments on commit 030e9a0

Please sign in to comment.