1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use core::ptr::{addr_of, addr_of_mut};
12
13use kernel::component::Component;
14use kernel::deferred_call::DeferredCallClient;
15use kernel::hil::led::LedLow;
16use kernel::hil::time::Counter;
17use kernel::platform::{KernelResources, SyscallDriverLookup};
18use kernel::scheduler::round_robin::RoundRobinSched;
19use kernel::{capabilities, create_capability, static_init};
20use nrf52840::gpio::Pin;
21use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
22use nrf52_components::{UartChannel, UartPins};
23
24const LED1_PIN: Pin = Pin::P0_13;
26const LED2_PIN: Pin = Pin::P0_14;
27const LED3_PIN: Pin = Pin::P0_15;
28const LED4_PIN: Pin = Pin::P0_16;
29
30const BUTTON_RST_PIN: Pin = Pin::P0_18;
31
32const UART_RTS: Option<Pin> = Some(Pin::P0_05);
33const UART_TXD: Pin = Pin::P0_06;
34const UART_CTS: Option<Pin> = Some(Pin::P0_07);
35const UART_RXD: Pin = Pin::P0_08;
36
37pub mod io;
39
40const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
43 capsules_system::process_policies::PanicFaultPolicy {};
44
45const NUM_PROCS: usize = 8;
47
48static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
49 [None; NUM_PROCS];
50
51static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
52
53#[no_mangle]
55#[link_section = ".stack_buffer"]
56pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
57
58type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
63
64pub struct Platform {
66 console: &'static capsules_core::console::Console<'static>,
67 led: &'static capsules_core::led::LedDriver<
68 'static,
69 kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
70 4,
71 >,
72 alarm: &'static AlarmDriver,
73 scheduler: &'static RoundRobinSched<'static>,
74 systick: cortexm4::systick::SysTick,
75}
76
77impl SyscallDriverLookup for Platform {
78 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
79 where
80 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
81 {
82 match driver_num {
83 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
84 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
85 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
86 _ => f(None),
87 }
88 }
89}
90
91#[inline(never)]
95unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
96 let ieee802154_ack_buf = static_init!(
97 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
98 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
99 );
100 let nrf52840_peripherals = static_init!(
102 Nrf52840DefaultPeripherals,
103 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
104 );
105
106 nrf52840_peripherals
107}
108
109impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
110 for Platform
111{
112 type SyscallDriverLookup = Self;
113 type SyscallFilter = ();
114 type ProcessFault = ();
115 type Scheduler = RoundRobinSched<'static>;
116 type SchedulerTimer = cortexm4::systick::SysTick;
117 type WatchDog = ();
118 type ContextSwitchCallback = ();
119
120 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
121 self
122 }
123 fn syscall_filter(&self) -> &Self::SyscallFilter {
124 &()
125 }
126 fn process_fault(&self) -> &Self::ProcessFault {
127 &()
128 }
129 fn scheduler(&self) -> &Self::Scheduler {
130 self.scheduler
131 }
132 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
133 &self.systick
134 }
135 fn watchdog(&self) -> &Self::WatchDog {
136 &()
137 }
138 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
139 &()
140 }
141}
142
143#[no_mangle]
145pub unsafe fn main() {
146 nrf52840::init();
152
153 let nrf52840_peripherals = create_peripherals();
156
157 nrf52840_peripherals.init();
159 let base_peripherals = &nrf52840_peripherals.nrf52;
160
161 let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
165
166 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
168
169 let chip = static_init!(
172 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
173 nrf52840::chip::NRF52::new(nrf52840_peripherals)
174 );
175 CHIP = Some(chip);
176
177 nrf52_components::startup::NrfStartupComponent::new(
180 false,
181 BUTTON_RST_PIN,
182 nrf52840::uicr::Regulator0Output::DEFAULT,
183 &base_peripherals.nvmc,
184 )
185 .finalize(());
186
187 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
194
195 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
200 LedLow<'static, nrf52840::gpio::GPIOPin>,
201 LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
202 LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
203 LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
204 LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
205 ));
206
207 let rtc = &base_peripherals.rtc;
212 let _ = rtc.start();
213 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
214 .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc));
215 let alarm = components::alarm::AlarmDriverComponent::new(
216 board_kernel,
217 capsules_core::alarm::DRIVER_NUM,
218 mux_alarm,
219 )
220 .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc));
221
222 let uart_channel = nrf52_components::UartChannelComponent::new(
227 uart_channel,
228 mux_alarm,
229 &base_peripherals.uarte0,
230 )
231 .finalize(nrf52_components::uart_channel_component_static!(
232 nrf52840::rtc::Rtc
233 ));
234
235 let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200)
237 .finalize(components::uart_mux_component_static!());
238
239 let console = components::console::ConsoleComponent::new(
241 board_kernel,
242 capsules_core::console::DRIVER_NUM,
243 uart_mux,
244 )
245 .finalize(components::console_component_static!());
246
247 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
252
253 let sha = components::sha::ShaSoftware256Component::new()
259 .finalize(components::sha_software_256_component_static!());
260
261 let verifying_key = kernel::static_init!(
288 [u8; 64],
289 [
290 0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
291 0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
292 0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
293 0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
294 0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
295 ]
296 );
297
298 let ecdsa_p256_verifier = kernel::static_init!(
300 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
301 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(verifying_key)
302 );
303 ecdsa_p256_verifier.register();
304
305 let checking_policy = components::appid::checker_signature::AppCheckerSignatureComponent::new(
307 sha,
308 ecdsa_p256_verifier,
309 tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
310 )
311 .finalize(components::app_checker_signature_component_static!(
312 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
313 capsules_extra::sha256::Sha256Software<'static>,
314 32,
315 64,
316 ));
317
318 let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
320 .finalize(components::appid_assigner_names_component_static!());
321
322 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
324 .finalize(components::process_checker_machine_component_static!());
325
326 let storage_permissions_policy =
331 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
332 components::storage_permissions_null_component_static!(
333 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
334 kernel::process::ProcessStandardDebugFull,
335 ),
336 );
337
338 extern "C" {
344 static _sapps: u8;
346 static _eapps: u8;
348 static mut _sappmem: u8;
350 static _eappmem: u8;
352 }
353
354 let app_flash = core::slice::from_raw_parts(
355 core::ptr::addr_of!(_sapps),
356 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
357 );
358 let app_memory = core::slice::from_raw_parts_mut(
359 core::ptr::addr_of_mut!(_sappmem),
360 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
361 );
362
363 let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
365 checker,
366 &mut *addr_of_mut!(PROCESSES),
367 board_kernel,
368 chip,
369 &FAULT_RESPONSE,
370 assigner,
371 storage_permissions_policy,
372 app_flash,
373 app_memory,
374 )
375 .finalize(components::process_loader_sequential_component_static!(
376 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
377 kernel::process::ProcessStandardDebugFull,
378 NUM_PROCS
379 ));
380
381 let scheduler = components::sched::round_robin::RoundRobinComponent::new(&*addr_of!(PROCESSES))
386 .finalize(components::round_robin_component_static!(NUM_PROCS));
387
388 let platform = Platform {
389 console,
390 led,
391 alarm,
392 scheduler,
393 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
394 };
395
396 board_kernel.kernel_loop(
397 &platform,
398 chip,
399 None::<&kernel::ipc::IPC<0>>,
400 &main_loop_capability,
401 );
402}