components/
app_loader.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 2024.
4
5//! Component for Dynamic App Loading Drivers.
6//!
7//! This provides one component, AppLoaderComponent, which provides
8//! a system call interface to the dynamic app loading capsule.
9//!
10//! Example instantiation:
11//!
12//! ```rust
13//! # use kernel::static_init;
14//!
15//! type NonVolatilePages = components::dynamic_binary_storage::NVPages<nrf52840::nvmc::Nvmc>;
16//! type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
17//! 'static,
18//! nrf52840::chip::NRF52<'a, Nrf52840DefaultPeripherals<'a>>,
19//! kernel::process::ProcessStandardDebugFull,
20//! NonVolatilePages,
21//! >;
22//!
23//! let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
24//!     board_kernel,
25//!     capsules_extra::app_loader::DRIVER_NUM,
26//!     dynamic_binary_storage,
27//!     dynamic_binary_storage,
28//!     ).finalize(components::app_loader_component_static!(
29//!     DynamicBinaryStorage<'static>,
30//!     DynamicBinaryStorage<'static>,
31//!     ));
32//! ```
33
34use capsules_extra::app_loader::AppLoader;
35use core::mem::MaybeUninit;
36use kernel::capabilities;
37use kernel::component::Component;
38use kernel::create_capability;
39use kernel::dynamic_binary_storage;
40
41// Setup static space for the objects.
42#[macro_export]
43macro_rules! app_loader_component_static {
44    ($S:ty, $L:ty $(,)?) => {{
45        let al = kernel::static_buf!(capsules_extra::app_loader::AppLoader<$S, $L>);
46        let buffer = kernel::static_buf!([u8; capsules_extra::app_loader::BUF_LEN]);
47
48        (al, buffer)
49    };};
50}
51
52pub struct AppLoaderComponent<
53    S: dynamic_binary_storage::DynamicBinaryStore + 'static,
54    L: dynamic_binary_storage::DynamicProcessLoad + 'static,
55> {
56    board_kernel: &'static kernel::Kernel,
57    driver_num: usize,
58    storage_driver: &'static S,
59    load_driver: &'static L,
60}
61
62impl<
63        S: dynamic_binary_storage::DynamicBinaryStore + 'static,
64        L: dynamic_binary_storage::DynamicProcessLoad + 'static,
65    > AppLoaderComponent<S, L>
66{
67    pub fn new(
68        board_kernel: &'static kernel::Kernel,
69        driver_num: usize,
70        storage_driver: &'static S,
71        load_driver: &'static L,
72    ) -> Self {
73        Self {
74            board_kernel,
75            driver_num,
76            storage_driver,
77            load_driver,
78        }
79    }
80}
81
82impl<
83        S: dynamic_binary_storage::DynamicBinaryStore + 'static,
84        L: dynamic_binary_storage::DynamicProcessLoad + 'static,
85    > Component for AppLoaderComponent<S, L>
86{
87    type StaticInput = (
88        &'static mut MaybeUninit<AppLoader<S, L>>,
89        &'static mut MaybeUninit<[u8; capsules_extra::app_loader::BUF_LEN]>,
90    );
91    type Output = &'static AppLoader<S, L>;
92
93    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
94        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
95
96        let buffer = static_buffer
97            .1
98            .write([0; capsules_extra::app_loader::BUF_LEN]);
99
100        let dynamic_app_loader = static_buffer.0.write(AppLoader::new(
101            self.board_kernel.create_grant(self.driver_num, &grant_cap),
102            self.storage_driver,
103            self.load_driver,
104            buffer,
105        ));
106        dynamic_binary_storage::DynamicBinaryStore::set_storage_client(
107            self.storage_driver,
108            dynamic_app_loader,
109        );
110        dynamic_binary_storage::DynamicProcessLoad::set_load_client(
111            self.load_driver,
112            dynamic_app_loader,
113        );
114        dynamic_app_loader
115    }
116}