components/
dynamic_binary_storage.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component for dynamic binary storage.
6//!
7//! This provides one component, SequentialBinaryStorageComponent, which provides
8//! a system call interface to SequentialDynamicBinaryStorage.
9//!
10//!```rust, ignore
11//! # use kernel::static_init;
12//!
13//! let dynamic_binary_storage = components::dyn_binary_storage::SequentialBinaryStorageComponent::new(
14//!     &base_peripherals.nvmc,
15//!     &loader,
16//! )
17//! .finalize(components::sequential_binary_storage_component_static!(
18//!     nrf52840::nvmc::Nvmc,
19//!     nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
20//!     kernel::process::ProcessStandardDebugFull,
21//! ));
22//! ```
23
24use capsules_extra::nonvolatile_to_pages::NonvolatileToPages;
25use core::mem::MaybeUninit;
26use kernel::component::Component;
27use kernel::deferred_call::DeferredCallClient;
28use kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage;
29use kernel::hil;
30use kernel::platform::chip::Chip;
31use kernel::process::ProcessStandardDebug;
32use kernel::process::SequentialProcessLoaderMachine;
33
34pub type NVPages<F> = capsules_extra::nonvolatile_to_pages::NonvolatileToPages<'static, F>;
35
36// Setup static space for the objects.
37#[macro_export]
38macro_rules! sequential_binary_storage_component_static {
39    ($F:ty, $C:ty, $D:ty $(,)?) => {{
40        let page = kernel::static_buf!(<$F as kernel::hil::flash::Flash>::Page);
41        let ntp = kernel::static_buf!(
42            capsules_extra::nonvolatile_to_pages::NonvolatileToPages<'static, $F>
43        );
44        let pl = kernel::static_buf!(
45            kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
46                'static,
47                'static,
48                $C,
49                $D,
50                capsules_extra::nonvolatile_to_pages::NonvolatileToPages<'static, $F>,
51            >
52        );
53        let buffer = kernel::static_buf!([u8; kernel::dynamic_binary_storage::BUF_LEN]);
54
55        (page, ntp, pl, buffer)
56    };};
57}
58
59pub struct SequentialBinaryStorageComponent<
60    F: 'static + hil::flash::Flash + hil::flash::HasClient<'static, NonvolatileToPages<'static, F>>,
61    C: Chip + 'static,
62    D: ProcessStandardDebug + 'static,
63> {
64    nv_flash: &'static F,
65    loader_driver: &'static SequentialProcessLoaderMachine<'static, C, D>,
66}
67
68impl<
69        F: 'static
70            + hil::flash::Flash
71            + hil::flash::HasClient<'static, NonvolatileToPages<'static, F>>,
72        C: 'static + Chip,
73        D: 'static + ProcessStandardDebug,
74    > SequentialBinaryStorageComponent<F, C, D>
75{
76    pub fn new(
77        nv_flash: &'static F,
78        loader_driver: &'static SequentialProcessLoaderMachine<'static, C, D>,
79    ) -> Self {
80        Self {
81            nv_flash,
82            loader_driver,
83        }
84    }
85}
86
87impl<
88        F: 'static
89            + hil::flash::Flash
90            + hil::flash::HasClient<'static, NonvolatileToPages<'static, F>>,
91        C: 'static + Chip,
92        D: 'static + ProcessStandardDebug,
93    > Component for SequentialBinaryStorageComponent<F, C, D>
94{
95    type StaticInput = (
96        &'static mut MaybeUninit<<F as hil::flash::Flash>::Page>,
97        &'static mut MaybeUninit<NonvolatileToPages<'static, F>>,
98        &'static mut MaybeUninit<
99            SequentialDynamicBinaryStorage<'static, 'static, C, D, NonvolatileToPages<'static, F>>,
100        >,
101        &'static mut MaybeUninit<[u8; kernel::dynamic_binary_storage::BUF_LEN]>,
102    );
103    type Output = &'static SequentialDynamicBinaryStorage<
104        'static,
105        'static,
106        C,
107        D,
108        NonvolatileToPages<'static, F>,
109    >;
110
111    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
112        let buffer = static_buffer
113            .3
114            .write([0; kernel::dynamic_binary_storage::BUF_LEN]);
115
116        let flash_pagebuffer = static_buffer
117            .0
118            .write(<F as hil::flash::Flash>::Page::default());
119
120        let nv_to_page = static_buffer
121            .1
122            .write(NonvolatileToPages::new(self.nv_flash, flash_pagebuffer));
123        hil::flash::HasClient::set_client(self.nv_flash, nv_to_page);
124
125        let dynamic_binary_storage = static_buffer.2.write(SequentialDynamicBinaryStorage::new(
126            nv_to_page,
127            self.loader_driver,
128            buffer,
129        ));
130        hil::nonvolatile_storage::NonvolatileStorage::set_client(
131            nv_to_page,
132            dynamic_binary_storage,
133        );
134        self.loader_driver
135            .set_runtime_client(dynamic_binary_storage);
136        dynamic_binary_storage.register();
137        dynamic_binary_storage
138    }
139}