nrf52840dk_test_dynamic_app_load/
main.rs1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use kernel::component::Component;
12use kernel::hil::led::LedLow;
13use kernel::hil::time::Counter;
14use kernel::platform::{KernelResources, SyscallDriverLookup};
15use kernel::process::ProcessArray;
16use kernel::process::ProcessLoadingAsync;
17use kernel::scheduler::round_robin::RoundRobinSched;
18use kernel::{capabilities, create_capability, static_init};
19use nrf52840::gpio::Pin;
20use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
21use nrf52_components::{UartChannel, UartPins};
22
23const LED1_PIN: Pin = Pin::P0_13;
25const LED2_PIN: Pin = Pin::P0_14;
26const LED3_PIN: Pin = Pin::P0_15;
27const LED4_PIN: Pin = Pin::P0_16;
28
29const BUTTON1_PIN: Pin = Pin::P0_11;
31const BUTTON2_PIN: Pin = Pin::P0_12;
32const BUTTON3_PIN: Pin = Pin::P0_24;
33const BUTTON4_PIN: Pin = Pin::P0_25;
34const BUTTON_RST_PIN: Pin = Pin::P0_18;
35
36const UART_RTS: Option<Pin> = Some(Pin::P0_05);
37const UART_TXD: Pin = Pin::P0_06;
38const UART_CTS: Option<Pin> = Some(Pin::P0_07);
39const UART_RXD: Pin = Pin::P0_08;
40
41pub mod io;
43
44const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
47 capsules_system::process_policies::PanicFaultPolicy {};
48
49const NUM_PROCS: usize = 8;
51
52static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
54static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
55static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
57 None;
58
59kernel::stack_size! {0x2000}
60
61type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
66
67type NonVolatilePages = components::dynamic_binary_storage::NVPages<nrf52840::nvmc::Nvmc>;
68type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
69 'static,
70 'static,
71 nrf52840::chip::NRF52<'a, Nrf52840DefaultPeripherals<'a>>,
72 kernel::process::ProcessStandardDebugFull,
73 NonVolatilePages,
74>;
75
76pub struct Platform {
78 console: &'static capsules_core::console::Console<'static>,
79 button: &'static capsules_core::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
80 adc: &'static capsules_core::adc::AdcDedicated<'static, nrf52840::adc::Adc<'static>>,
81 led: &'static capsules_core::led::LedDriver<
82 'static,
83 kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
84 4,
85 >,
86 alarm: &'static AlarmDriver,
87 scheduler: &'static RoundRobinSched<'static>,
88 systick: cortexm4::systick::SysTick,
89 processes: &'static ProcessArray<NUM_PROCS>,
90 dynamic_app_loader: &'static capsules_extra::app_loader::AppLoader<
91 DynamicBinaryStorage<'static>,
92 DynamicBinaryStorage<'static>,
93 >,
94}
95
96impl SyscallDriverLookup for Platform {
97 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
98 where
99 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
100 {
101 match driver_num {
102 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
103 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
104 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
105 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
106 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
107 capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
108 _ => f(None),
109 }
110 }
111}
112
113#[inline(never)]
117unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
118 let ieee802154_ack_buf = static_init!(
119 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
120 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
121 );
122 let nrf52840_peripherals = static_init!(
124 Nrf52840DefaultPeripherals,
125 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
126 );
127
128 nrf52840_peripherals
129}
130
131impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
132 for Platform
133{
134 type SyscallDriverLookup = Self;
135 type SyscallFilter = ();
136 type ProcessFault = ();
137 type Scheduler = RoundRobinSched<'static>;
138 type SchedulerTimer = cortexm4::systick::SysTick;
139 type WatchDog = ();
140 type ContextSwitchCallback = ();
141
142 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
143 self
144 }
145 fn syscall_filter(&self) -> &Self::SyscallFilter {
146 &()
147 }
148 fn process_fault(&self) -> &Self::ProcessFault {
149 &()
150 }
151 fn scheduler(&self) -> &Self::Scheduler {
152 self.scheduler
153 }
154 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
155 &self.systick
156 }
157 fn watchdog(&self) -> &Self::WatchDog {
158 &()
159 }
160 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
161 &()
162 }
163}
164
165impl kernel::process::ProcessLoadingAsyncClient for Platform {
166 fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {}
167
168 fn process_loading_finished(&self) {
169 kernel::debug!("Processes Loaded at Main:");
170
171 for (i, proc) in self.processes.as_slice().iter().enumerate() {
172 proc.get().map(|p| {
173 kernel::debug!("[{}] {}", i, p.get_process_name());
174 kernel::debug!(" ShortId: {}", p.short_app_id());
175 });
176 }
177 }
178}
179
180#[no_mangle]
182pub unsafe fn main() {
183 nrf52840::init();
189
190 let nrf52840_peripherals = create_peripherals();
193
194 nrf52840_peripherals.init();
196 let base_peripherals = &nrf52840_peripherals.nrf52;
197
198 let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
202
203 let processes = components::process_array::ProcessArrayComponent::new()
205 .finalize(components::process_array_component_static!(NUM_PROCS));
206 PROCESSES = Some(processes);
207
208 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
210
211 let chip = static_init!(
214 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
215 nrf52840::chip::NRF52::new(nrf52840_peripherals)
216 );
217 CHIP = Some(chip);
218
219 nrf52_components::startup::NrfStartupComponent::new(
222 false,
223 BUTTON_RST_PIN,
224 nrf52840::uicr::Regulator0Output::DEFAULT,
225 &base_peripherals.nvmc,
226 )
227 .finalize(());
228
229 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
236
237 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
242 LedLow<'static, nrf52840::gpio::GPIOPin>,
243 LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
244 LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
245 LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
246 LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
247 ));
248
249 let rtc = &base_peripherals.rtc;
254 let _ = rtc.start();
255 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
256 .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc));
257 let alarm = components::alarm::AlarmDriverComponent::new(
258 board_kernel,
259 capsules_core::alarm::DRIVER_NUM,
260 mux_alarm,
261 )
262 .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc));
263
264 let uart_channel = nrf52_components::UartChannelComponent::new(
269 uart_channel,
270 mux_alarm,
271 &base_peripherals.uarte0,
272 )
273 .finalize(nrf52_components::uart_channel_component_static!(
274 nrf52840::rtc::Rtc
275 ));
276
277 let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200)
279 .finalize(components::uart_mux_component_static!());
280
281 let console = components::console::ConsoleComponent::new(
283 board_kernel,
284 capsules_core::console::DRIVER_NUM,
285 uart_mux,
286 )
287 .finalize(components::console_component_static!());
288
289 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
291 .finalize(components::process_printer_text_component_static!());
292 PROCESS_PRINTER = Some(process_printer);
293
294 let pconsole = components::process_console::ProcessConsoleComponent::new(
297 board_kernel,
298 uart_mux,
299 mux_alarm,
300 process_printer,
301 Some(cortexm4::support::reset),
302 )
303 .finalize(components::process_console_component_static!(
304 nrf52840::rtc::Rtc<'static>
305 ));
306
307 components::debug_writer::DebugWriterComponent::new(
309 uart_mux,
310 create_capability!(capabilities::SetDebugWriterCapability),
311 )
312 .finalize(components::debug_writer_component_static!());
313
314 let button = components::button::ButtonComponent::new(
319 board_kernel,
320 capsules_core::button::DRIVER_NUM,
321 components::button_component_helper!(
322 nrf52840::gpio::GPIOPin,
323 (
324 &nrf52840_peripherals.gpio_port[BUTTON1_PIN],
325 kernel::hil::gpio::ActivationMode::ActiveLow,
326 kernel::hil::gpio::FloatingState::PullUp
327 ),
328 (
329 &nrf52840_peripherals.gpio_port[BUTTON2_PIN],
330 kernel::hil::gpio::ActivationMode::ActiveLow,
331 kernel::hil::gpio::FloatingState::PullUp
332 ),
333 (
334 &nrf52840_peripherals.gpio_port[BUTTON3_PIN],
335 kernel::hil::gpio::ActivationMode::ActiveLow,
336 kernel::hil::gpio::FloatingState::PullUp
337 ),
338 (
339 &nrf52840_peripherals.gpio_port[BUTTON4_PIN],
340 kernel::hil::gpio::ActivationMode::ActiveLow,
341 kernel::hil::gpio::FloatingState::PullUp
342 )
343 ),
344 )
345 .finalize(components::button_component_static!(
346 nrf52840::gpio::GPIOPin
347 ));
348
349 let adc_channels = static_init!(
354 [nrf52840::adc::AdcChannelSetup; 6],
355 [
356 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput1),
357 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput2),
358 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput4),
359 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput5),
360 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput6),
361 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput7),
362 ]
363 );
364 let adc = components::adc::AdcDedicatedComponent::new(
365 &base_peripherals.adc,
366 adc_channels,
367 board_kernel,
368 capsules_core::adc::DRIVER_NUM,
369 )
370 .finalize(components::adc_dedicated_component_static!(
371 nrf52840::adc::Adc
372 ));
373
374 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
379
380 let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
386 .finalize(components::app_checker_null_component_static!());
387
388 let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
390 .finalize(components::appid_assigner_tbf_header_component_static!());
391
392 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
394 .finalize(components::process_checker_machine_component_static!());
395
396 let storage_permissions_policy =
401 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
402 components::storage_permissions_null_component_static!(
403 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
404 kernel::process::ProcessStandardDebugFull,
405 ),
406 );
407
408 extern "C" {
410 static _sapps: u8;
412 static _eapps: u8;
414 static mut _sappmem: u8;
416 static _eappmem: u8;
418 }
419
420 let app_flash = core::slice::from_raw_parts(
421 core::ptr::addr_of!(_sapps),
422 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
423 );
424 let app_memory = core::slice::from_raw_parts_mut(
425 core::ptr::addr_of_mut!(_sappmem),
426 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
427 );
428
429 let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
431 checker,
432 board_kernel,
433 chip,
434 &FAULT_RESPONSE,
435 assigner,
436 storage_permissions_policy,
437 app_flash,
438 app_memory,
439 )
440 .finalize(components::process_loader_sequential_component_static!(
441 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
442 kernel::process::ProcessStandardDebugFull,
443 NUM_PROCS
444 ));
445
446 let dynamic_binary_storage =
452 components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
453 &base_peripherals.nvmc,
454 loader,
455 )
456 .finalize(components::sequential_binary_storage_component_static!(
457 nrf52840::nvmc::Nvmc,
458 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
459 kernel::process::ProcessStandardDebugFull,
460 ));
461
462 let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
464 board_kernel,
465 capsules_extra::app_loader::DRIVER_NUM,
466 dynamic_binary_storage,
467 dynamic_binary_storage,
468 )
469 .finalize(components::app_loader_component_static!(
470 DynamicBinaryStorage<'static>,
471 DynamicBinaryStorage<'static>,
472 ));
473
474 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
479 .finalize(components::round_robin_component_static!(NUM_PROCS));
480
481 let platform = static_init!(
482 Platform,
483 Platform {
484 console,
485 button,
486 adc,
487 led,
488 alarm,
489 scheduler,
490 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
491 processes,
492 dynamic_app_loader,
493 }
494 );
495 loader.set_client(platform);
496
497 let _ = pconsole.start();
498
499 board_kernel.kernel_loop(
500 platform,
501 chip,
502 None::<&kernel::ipc::IPC<0>>,
503 &main_loop_capability,
504 );
505}