nrf52840dk_test_appid_tbf/
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, ProcessLoadingAsync};
16use kernel::scheduler::round_robin::RoundRobinSched;
17use kernel::{capabilities, create_capability, static_init};
18use nrf52840::gpio::Pin;
19use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
20use nrf52_components::{UartChannel, UartPins};
21
22const LED1_PIN: Pin = Pin::P0_13;
24const LED2_PIN: Pin = Pin::P0_14;
25const LED3_PIN: Pin = Pin::P0_15;
26const LED4_PIN: Pin = Pin::P0_16;
27
28const BUTTON_RST_PIN: Pin = Pin::P0_18;
29
30const UART_RTS: Option<Pin> = Some(Pin::P0_05);
31const UART_TXD: Pin = Pin::P0_06;
32const UART_CTS: Option<Pin> = Some(Pin::P0_07);
33const UART_RXD: Pin = Pin::P0_08;
34
35pub mod io;
37
38const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
41 capsules_system::process_policies::PanicFaultPolicy {};
42
43const NUM_PROCS: usize = 8;
45
46type ChipHw = nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>;
47
48kernel::stack_size! {0x2000}
49
50type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
55
56pub struct Platform {
58 console: &'static capsules_core::console::Console<'static>,
59 led: &'static capsules_core::led::LedDriver<
60 'static,
61 kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
62 4,
63 >,
64 alarm: &'static AlarmDriver,
65 scheduler: &'static RoundRobinSched<'static>,
66 systick: cortexm4::systick::SysTick,
67 processes: &'static ProcessArray<NUM_PROCS>,
68}
69
70impl SyscallDriverLookup for Platform {
71 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
72 where
73 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
74 {
75 match driver_num {
76 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
77 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
78 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
79 _ => f(None),
80 }
81 }
82}
83
84#[inline(never)]
88unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
89 let ieee802154_ack_buf = static_init!(
90 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
91 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
92 );
93 let nrf52840_peripherals = static_init!(
95 Nrf52840DefaultPeripherals,
96 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
97 );
98
99 nrf52840_peripherals
100}
101
102impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
103 for Platform
104{
105 type SyscallDriverLookup = Self;
106 type SyscallFilter = ();
107 type ProcessFault = ();
108 type Scheduler = RoundRobinSched<'static>;
109 type SchedulerTimer = cortexm4::systick::SysTick;
110 type WatchDog = ();
111 type ContextSwitchCallback = ();
112
113 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
114 self
115 }
116 fn syscall_filter(&self) -> &Self::SyscallFilter {
117 &()
118 }
119 fn process_fault(&self) -> &Self::ProcessFault {
120 &()
121 }
122 fn scheduler(&self) -> &Self::Scheduler {
123 self.scheduler
124 }
125 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
126 &self.systick
127 }
128 fn watchdog(&self) -> &Self::WatchDog {
129 &()
130 }
131 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
132 &()
133 }
134}
135
136impl kernel::process::ProcessLoadingAsyncClient for Platform {
137 fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {}
138
139 fn process_loading_finished(&self) {
140 kernel::debug!("Processes Loaded:");
141
142 for (i, proc) in self.processes.as_slice().iter().enumerate() {
143 proc.get().map(|p| {
144 kernel::debug!("[{}] {}", i, p.get_process_name());
145 kernel::debug!(" ShortId: {}", p.short_app_id());
146 });
147 }
148 }
149}
150
151#[no_mangle]
153pub unsafe fn main() {
154 nrf52840::init();
160
161 kernel::deferred_call::initialize_deferred_call_state::<
163 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
164 >();
165
166 let nrf52840_peripherals = create_peripherals();
169
170 nrf52840_peripherals.init();
172 let base_peripherals = &nrf52840_peripherals.nrf52;
173
174 let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
178
179 let processes = components::process_array::ProcessArrayComponent::new()
181 .finalize(components::process_array_component_static!(NUM_PROCS));
182
183 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
185
186 let chip = static_init!(
189 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
190 nrf52840::chip::NRF52::new(nrf52840_peripherals)
191 );
192
193 nrf52_components::startup::NrfStartupComponent::new(
196 false,
197 BUTTON_RST_PIN,
198 nrf52840::uicr::Regulator0Output::DEFAULT,
199 &base_peripherals.nvmc,
200 )
201 .finalize(());
202
203 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
210
211 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
216 LedLow<'static, nrf52840::gpio::GPIOPin>,
217 LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
218 LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
219 LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
220 LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
221 ));
222
223 let rtc = &base_peripherals.rtc;
228 let _ = rtc.start();
229 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
230 .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc));
231 let alarm = components::alarm::AlarmDriverComponent::new(
232 board_kernel,
233 capsules_core::alarm::DRIVER_NUM,
234 mux_alarm,
235 )
236 .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc));
237
238 let uart_channel = nrf52_components::UartChannelComponent::new(
243 uart_channel,
244 mux_alarm,
245 &base_peripherals.uarte0,
246 )
247 .finalize(nrf52_components::uart_channel_component_static!(
248 nrf52840::rtc::Rtc
249 ));
250
251 let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200)
253 .finalize(components::uart_mux_component_static!());
254
255 let console = components::console::ConsoleComponent::new(
257 board_kernel,
258 capsules_core::console::DRIVER_NUM,
259 uart_mux,
260 )
261 .finalize(components::console_component_static!());
262
263 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
265 .finalize(components::process_printer_text_component_static!());
266
267 let pconsole = components::process_console::ProcessConsoleComponent::new(
270 board_kernel,
271 uart_mux,
272 mux_alarm,
273 process_printer,
274 Some(cortexm4::support::reset),
275 )
276 .finalize(components::process_console_component_static!(
277 nrf52840::rtc::Rtc<'static>
278 ));
279
280 components::debug_writer::DebugWriterComponent::new::<
282 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
283 >(
284 uart_mux,
285 create_capability!(capabilities::SetDebugWriterCapability),
286 )
287 .finalize(components::debug_writer_component_static!());
288
289 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
294
295 let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
301 .finalize(components::app_checker_null_component_static!());
302
303 let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
305 .finalize(components::appid_assigner_tbf_header_component_static!());
306
307 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
309 .finalize(components::process_checker_machine_component_static!());
310
311 let storage_permissions_policy =
316 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
317 components::storage_permissions_null_component_static!(
318 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
319 kernel::process::ProcessStandardDebugFull,
320 ),
321 );
322
323 extern "C" {
329 static _sapps: u8;
331 static _eapps: u8;
333 static mut _sappmem: u8;
335 static _eappmem: u8;
337 }
338
339 let app_flash = core::slice::from_raw_parts(
340 core::ptr::addr_of!(_sapps),
341 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
342 );
343 let app_memory = core::slice::from_raw_parts_mut(
344 core::ptr::addr_of_mut!(_sappmem),
345 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
346 );
347
348 let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
350 checker,
351 board_kernel,
352 chip,
353 &FAULT_RESPONSE,
354 assigner,
355 storage_permissions_policy,
356 app_flash,
357 app_memory,
358 )
359 .finalize(components::process_loader_sequential_component_static!(
360 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
361 kernel::process::ProcessStandardDebugFull,
362 NUM_PROCS
363 ));
364
365 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
370 .finalize(components::round_robin_component_static!(NUM_PROCS));
371
372 let platform = static_init!(
373 Platform,
374 Platform {
375 console,
376 led,
377 alarm,
378 scheduler,
379 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
380 processes,
381 }
382 );
383 loader.set_client(platform);
384
385 let _ = pconsole.start();
386
387 board_kernel.kernel_loop(
388 platform,
389 chip,
390 None::<&kernel::ipc::IPC<0>>,
391 &main_loop_capability,
392 );
393}