nrf52840dk_test_appid_tbf/
main.rs
1#![no_std]
8#![cfg_attr(not(doc), no_main)]
11#![deny(missing_docs)]
12
13use core::ptr::{addr_of, addr_of_mut};
14
15use kernel::component::Component;
16use kernel::hil::led::LedLow;
17use kernel::hil::time::Counter;
18use kernel::platform::{KernelResources, SyscallDriverLookup};
19use kernel::process::ProcessLoadingAsync;
20use kernel::scheduler::round_robin::RoundRobinSched;
21use kernel::{capabilities, create_capability, static_init};
22use nrf52840::gpio::Pin;
23use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
24use nrf52_components::{UartChannel, UartPins};
25
26const LED1_PIN: Pin = Pin::P0_13;
28const LED2_PIN: Pin = Pin::P0_14;
29const LED3_PIN: Pin = Pin::P0_15;
30const LED4_PIN: Pin = Pin::P0_16;
31
32const BUTTON_RST_PIN: Pin = Pin::P0_18;
33
34const UART_RTS: Option<Pin> = Some(Pin::P0_05);
35const UART_TXD: Pin = Pin::P0_06;
36const UART_CTS: Option<Pin> = Some(Pin::P0_07);
37const UART_RXD: Pin = Pin::P0_08;
38
39pub mod io;
41
42const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
45 capsules_system::process_policies::PanicFaultPolicy {};
46
47const NUM_PROCS: usize = 8;
49
50static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
51 [None; NUM_PROCS];
52
53static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
54
55#[no_mangle]
57#[link_section = ".stack_buffer"]
58pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
59
60type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
65
66pub struct Platform {
68 console: &'static capsules_core::console::Console<'static>,
69 led: &'static capsules_core::led::LedDriver<
70 'static,
71 kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
72 4,
73 >,
74 alarm: &'static AlarmDriver,
75 scheduler: &'static RoundRobinSched<'static>,
76 systick: cortexm4::systick::SysTick,
77 processes: &'static [Option<&'static dyn kernel::process::Process>],
78}
79
80impl SyscallDriverLookup for Platform {
81 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
82 where
83 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
84 {
85 match driver_num {
86 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
87 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
88 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
89 _ => f(None),
90 }
91 }
92}
93
94#[inline(never)]
98unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
99 let ieee802154_ack_buf = static_init!(
100 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
101 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
102 );
103 let nrf52840_peripherals = static_init!(
105 Nrf52840DefaultPeripherals,
106 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
107 );
108
109 nrf52840_peripherals
110}
111
112impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
113 for Platform
114{
115 type SyscallDriverLookup = Self;
116 type SyscallFilter = ();
117 type ProcessFault = ();
118 type Scheduler = RoundRobinSched<'static>;
119 type SchedulerTimer = cortexm4::systick::SysTick;
120 type WatchDog = ();
121 type ContextSwitchCallback = ();
122
123 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
124 self
125 }
126 fn syscall_filter(&self) -> &Self::SyscallFilter {
127 &()
128 }
129 fn process_fault(&self) -> &Self::ProcessFault {
130 &()
131 }
132 fn scheduler(&self) -> &Self::Scheduler {
133 self.scheduler
134 }
135 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
136 &self.systick
137 }
138 fn watchdog(&self) -> &Self::WatchDog {
139 &()
140 }
141 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
142 &()
143 }
144}
145
146impl kernel::process::ProcessLoadingAsyncClient for Platform {
147 fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {}
148
149 fn process_loading_finished(&self) {
150 kernel::debug!("Processes Loaded:");
151
152 for (i, proc) in self.processes.iter().enumerate() {
153 proc.map(|p| {
154 kernel::debug!("[{}] {}", i, p.get_process_name());
155 kernel::debug!(" ShortId: {}", p.short_app_id());
156 });
157 }
158 }
159}
160
161#[no_mangle]
163pub unsafe fn main() {
164 nrf52840::init();
170
171 let nrf52840_peripherals = create_peripherals();
174
175 nrf52840_peripherals.init();
177 let base_peripherals = &nrf52840_peripherals.nrf52;
178
179 let processes = &*addr_of!(PROCESSES);
180
181 let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
185
186 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes));
188
189 let chip = static_init!(
192 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
193 nrf52840::chip::NRF52::new(nrf52840_peripherals)
194 );
195 CHIP = Some(chip);
196
197 nrf52_components::startup::NrfStartupComponent::new(
200 false,
201 BUTTON_RST_PIN,
202 nrf52840::uicr::Regulator0Output::DEFAULT,
203 &base_peripherals.nvmc,
204 )
205 .finalize(());
206
207 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
214
215 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
220 LedLow<'static, nrf52840::gpio::GPIOPin>,
221 LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
222 LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
223 LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
224 LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
225 ));
226
227 let rtc = &base_peripherals.rtc;
232 let _ = rtc.start();
233 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
234 .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc));
235 let alarm = components::alarm::AlarmDriverComponent::new(
236 board_kernel,
237 capsules_core::alarm::DRIVER_NUM,
238 mux_alarm,
239 )
240 .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc));
241
242 let uart_channel = nrf52_components::UartChannelComponent::new(
247 uart_channel,
248 mux_alarm,
249 &base_peripherals.uarte0,
250 )
251 .finalize(nrf52_components::uart_channel_component_static!(
252 nrf52840::rtc::Rtc
253 ));
254
255 let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200)
257 .finalize(components::uart_mux_component_static!());
258
259 let console = components::console::ConsoleComponent::new(
261 board_kernel,
262 capsules_core::console::DRIVER_NUM,
263 uart_mux,
264 )
265 .finalize(components::console_component_static!());
266
267 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
269 .finalize(components::process_printer_text_component_static!());
270
271 let pconsole = components::process_console::ProcessConsoleComponent::new(
274 board_kernel,
275 uart_mux,
276 mux_alarm,
277 process_printer,
278 Some(cortexm4::support::reset),
279 )
280 .finalize(components::process_console_component_static!(
281 nrf52840::rtc::Rtc<'static>
282 ));
283
284 components::debug_writer::DebugWriterComponent::new(uart_mux)
286 .finalize(components::debug_writer_component_static!());
287
288 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
293
294 let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
300 .finalize(components::app_checker_null_component_static!());
301
302 let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
304 .finalize(components::appid_assigner_tbf_header_component_static!());
305
306 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
308 .finalize(components::process_checker_machine_component_static!());
309
310 let storage_permissions_policy =
315 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
316 components::storage_permissions_null_component_static!(
317 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
318 kernel::process::ProcessStandardDebugFull,
319 ),
320 );
321
322 let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
328 checker,
329 &mut *addr_of_mut!(PROCESSES),
330 board_kernel,
331 chip,
332 &FAULT_RESPONSE,
333 assigner,
334 storage_permissions_policy,
335 )
336 .finalize(components::process_loader_sequential_component_static!(
337 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
338 kernel::process::ProcessStandardDebugFull,
339 NUM_PROCS
340 ));
341
342 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
347 .finalize(components::round_robin_component_static!(NUM_PROCS));
348
349 let platform = static_init!(
350 Platform,
351 Platform {
352 console,
353 led,
354 alarm,
355 scheduler,
356 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
357 processes,
358 }
359 );
360 loader.set_client(platform);
361
362 let _ = pconsole.start();
363
364 board_kernel.kernel_loop(
365 platform,
366 chip,
367 None::<&kernel::ipc::IPC<0>>,
368 &main_loop_capability,
369 );
370}