nrf52840dk_thread_tutorial/
main.rs1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use core::ptr::addr_of;
12
13use kernel::component::Component;
14use kernel::platform::{KernelResources, SyscallDriverLookup};
15use kernel::{capabilities, create_capability, static_init};
16use nrf52840::gpio::Pin;
17use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
18use nrf52840dk_lib::{self, NUM_PROCS};
19
20type ScreenDriver = components::screen::ScreenComponentType;
21
22const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
25 capsules_system::process_policies::PanicFaultPolicy {};
26
27type Ieee802154RawDriver =
28 components::ieee802154::Ieee802154RawComponentType<nrf52840::ieee802154_radio::Radio<'static>>;
29
30type AES128CTREncryptionOracleDriver =
31 capsules_extra::tutorials::encryption_oracle_chkpt5::EncryptionOracleDriver<
32 'static,
33 nrf52840::aes::AesECB<'static>,
34 >;
35
36struct Platform {
37 base: nrf52840dk_lib::Platform,
38 ieee802154: &'static Ieee802154RawDriver,
39 eui64: &'static nrf52840dk_lib::Eui64Driver,
40 screen: &'static ScreenDriver,
41 nonvolatile_storage:
42 &'static capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage<
43 'static,
44 {
45 components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT
46 },
47 >,
48 encryption_oracle: &'static AES128CTREncryptionOracleDriver,
49}
50
51impl SyscallDriverLookup for Platform {
52 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
53 where
54 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
55 {
56 match driver_num {
57 capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)),
58 capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)),
59 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
60 capsules_extra::tutorials::encryption_oracle_chkpt5::DRIVER_NUM => {
61 f(Some(self.encryption_oracle))
62 }
63 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => {
64 f(Some(self.nonvolatile_storage))
65 }
66 _ => self.base.with_driver(driver_num, f),
67 }
68 }
69}
70
71type Chip = nrf52840dk_lib::Chip;
72
73impl KernelResources<Chip> for Platform {
74 type SyscallDriverLookup = Self;
75 type SyscallFilter = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SyscallFilter;
76 type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
77 type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
78 type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
79 type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
80 type ContextSwitchCallback =
81 <nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;
82
83 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
84 self
85 }
86 fn syscall_filter(&self) -> &Self::SyscallFilter {
87 self.base.syscall_filter()
88 }
89 fn process_fault(&self) -> &Self::ProcessFault {
90 self.base.process_fault()
91 }
92 fn scheduler(&self) -> &Self::Scheduler {
93 self.base.scheduler()
94 }
95 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
96 self.base.scheduler_timer()
97 }
98 fn watchdog(&self) -> &Self::WatchDog {
99 self.base.watchdog()
100 }
101 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
102 self.base.context_switch_callback()
103 }
104}
105
106#[no_mangle]
108pub unsafe fn main() {
109 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
110
111 let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
113 nrf52840dk_lib::start();
114
115 let device_id = (*addr_of!(nrf52840::ficr::FICR_INSTANCE)).id();
120
121 let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id))
122 .finalize(components::eui64_component_static!());
123
124 let ieee802154 = components::ieee802154::Ieee802154RawComponent::new(
125 board_kernel,
126 capsules_extra::ieee802154::DRIVER_NUM,
127 &nrf52840_peripherals.ieee802154_radio,
128 )
129 .finalize(components::ieee802154_raw_component_static!(
130 nrf52840::ieee802154_radio::Radio,
131 ));
132
133 const CRYPT_SIZE: usize = 7 * kernel::hil::symmetric_encryption::AES128_BLOCK_SIZE;
137 let aes_src_buffer = kernel::static_init!([u8; 16], [0; 16]);
138 let aes_dst_buffer = kernel::static_init!([u8; CRYPT_SIZE], [0; CRYPT_SIZE]);
139
140 let encryption_oracle = static_init!(
141 AES128CTREncryptionOracleDriver,
142 AES128CTREncryptionOracleDriver::new(
143 &nrf52840_peripherals.nrf52.ecb,
144 aes_src_buffer,
145 aes_dst_buffer,
146 board_kernel.create_grant(
147 capsules_extra::tutorials::encryption_oracle_chkpt5::DRIVER_NUM,
148 &create_capability!(capabilities::MemoryAllocationCapability)
149 )
150 )
151 );
152
153 kernel::hil::symmetric_encryption::AES128::set_client(
154 &nrf52840_peripherals.nrf52.ecb,
155 encryption_oracle,
156 );
157 const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
162 const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
163
164 let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
165 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
166 nrf52840_peripherals.nrf52.twi1.configure(
167 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
168 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
169 );
170 nrf52840_peripherals
171 .nrf52
172 .twi1
173 .set_speed(nrf52840::i2c::Speed::K400);
174
175 let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
177 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
178
179 #[cfg(feature = "screen_ssd1306")]
181 let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
182 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
183
184 #[cfg(feature = "screen_sh1106")]
185 let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
186 .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
187
188 let screen = components::screen::ScreenComponent::new(
189 board_kernel,
190 capsules_extra::screen::DRIVER_NUM,
191 ssd1306_sh1106,
192 None,
193 )
194 .finalize(components::screen_component_static!(1032));
195
196 ssd1306_sh1106.init_screen();
197
198 kernel::storage_volume!(APP_STORAGE, 32);
204
205 let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new(
206 board_kernel,
207 capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM,
208 &nrf52840_peripherals.nrf52.nvmc,
209 core::ptr::addr_of!(APP_STORAGE) as usize,
210 APP_STORAGE.len()
211 )
212 .finalize(components::isolated_nonvolatile_storage_component_static!(
213 nrf52840::nvmc::Nvmc,
214 { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT }
215 ));
216
217 let platform = Platform {
222 base: base_platform,
223 eui64,
224 ieee802154,
225 screen,
226 nonvolatile_storage,
227 encryption_oracle,
228 };
229
230 let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
236 .finalize(components::app_checker_null_component_static!());
237
238 let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
240 .finalize(components::appid_assigner_names_component_static!());
241
242 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
244 .finalize(components::process_checker_machine_component_static!());
245
246 let storage_permissions_policy =
251 components::storage_permissions::individual::StoragePermissionsIndividualComponent::new()
252 .finalize(
253 components::storage_permissions_individual_component_static!(
254 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
255 kernel::process::ProcessStandardDebugFull,
256 ),
257 );
258
259 extern "C" {
265 static _sapps: u8;
267 static _eapps: u8;
269 static mut _sappmem: u8;
271 static _eappmem: u8;
273 }
274
275 let app_flash = core::slice::from_raw_parts(
276 core::ptr::addr_of!(_sapps),
277 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
278 );
279 let app_memory = core::slice::from_raw_parts_mut(
280 core::ptr::addr_of_mut!(_sappmem),
281 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
282 );
283
284 let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
286 checker,
287 board_kernel,
288 chip,
289 &FAULT_RESPONSE,
290 assigner,
291 storage_permissions_policy,
292 app_flash,
293 app_memory,
294 )
295 .finalize(components::process_loader_sequential_component_static!(
296 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
297 kernel::process::ProcessStandardDebugFull,
298 NUM_PROCS
299 ));
300
301 board_kernel.kernel_loop(
302 &platform,
303 chip,
304 Some(&platform.base.ipc),
305 &main_loop_capability,
306 );
307}