1#![no_std]
8#![no_main]
9#![deny(missing_docs)]
10
11use kernel::component::Component;
12use kernel::deferred_call::DeferredCallClient;
13use kernel::hil::led::LedLow;
14use kernel::hil::time::Counter;
15use kernel::platform::{KernelResources, SyscallDriverLookup};
16use kernel::process::ProcessArray;
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 BUTTON_RST_PIN: Pin = Pin::P0_18;
30
31const UART_RTS: Option<Pin> = Some(Pin::P0_05);
32const UART_TXD: Pin = Pin::P0_06;
33const UART_CTS: Option<Pin> = Some(Pin::P0_07);
34const UART_RXD: Pin = Pin::P0_08;
35
36pub mod io;
38
39const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
42 capsules_system::process_policies::PanicFaultPolicy {};
43
44const NUM_PROCS: usize = 8;
46
47static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
49static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
50
51#[no_mangle]
53#[link_section = ".stack_buffer"]
54static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
55
56type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
61
62type Verifier = ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>;
63type SignatureVerifyInMemoryKeys =
64 components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponentType<
65 Verifier,
66 2,
67 64,
68 32,
69 64,
70 >;
71
72pub struct Platform {
74 console: &'static capsules_core::console::Console<'static>,
75 led: &'static capsules_core::led::LedDriver<
76 'static,
77 kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
78 4,
79 >,
80 alarm: &'static AlarmDriver,
81 scheduler: &'static RoundRobinSched<'static>,
82 systick: cortexm4::systick::SysTick,
83}
84
85impl SyscallDriverLookup for Platform {
86 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
87 where
88 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
89 {
90 match driver_num {
91 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
92 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
93 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
94 _ => f(None),
95 }
96 }
97}
98
99#[inline(never)]
103unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
104 let ieee802154_ack_buf = static_init!(
105 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
106 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
107 );
108 let nrf52840_peripherals = static_init!(
110 Nrf52840DefaultPeripherals,
111 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
112 );
113
114 nrf52840_peripherals
115}
116
117impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
118 for Platform
119{
120 type SyscallDriverLookup = Self;
121 type SyscallFilter = ();
122 type ProcessFault = ();
123 type Scheduler = RoundRobinSched<'static>;
124 type SchedulerTimer = cortexm4::systick::SysTick;
125 type WatchDog = ();
126 type ContextSwitchCallback = ();
127
128 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
129 self
130 }
131 fn syscall_filter(&self) -> &Self::SyscallFilter {
132 &()
133 }
134 fn process_fault(&self) -> &Self::ProcessFault {
135 &()
136 }
137 fn scheduler(&self) -> &Self::Scheduler {
138 self.scheduler
139 }
140 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
141 &self.systick
142 }
143 fn watchdog(&self) -> &Self::WatchDog {
144 &()
145 }
146 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
147 &()
148 }
149}
150
151#[no_mangle]
153pub unsafe fn main() {
154 nrf52840::init();
160
161 let nrf52840_peripherals = create_peripherals();
164
165 nrf52840_peripherals.init();
167 let base_peripherals = &nrf52840_peripherals.nrf52;
168
169 let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
173
174 let processes = components::process_array::ProcessArrayComponent::new()
176 .finalize(components::process_array_component_static!(NUM_PROCS));
177 PROCESSES = Some(processes);
178
179 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
181
182 let chip = static_init!(
185 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
186 nrf52840::chip::NRF52::new(nrf52840_peripherals)
187 );
188 CHIP = Some(chip);
189
190 nrf52_components::startup::NrfStartupComponent::new(
193 false,
194 BUTTON_RST_PIN,
195 nrf52840::uicr::Regulator0Output::DEFAULT,
196 &base_peripherals.nvmc,
197 )
198 .finalize(());
199
200 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
207
208 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
213 LedLow<'static, nrf52840::gpio::GPIOPin>,
214 LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]),
215 LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]),
216 LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]),
217 LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]),
218 ));
219
220 let rtc = &base_peripherals.rtc;
225 let _ = rtc.start();
226 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
227 .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc));
228 let alarm = components::alarm::AlarmDriverComponent::new(
229 board_kernel,
230 capsules_core::alarm::DRIVER_NUM,
231 mux_alarm,
232 )
233 .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc));
234
235 let uart_channel = nrf52_components::UartChannelComponent::new(
240 uart_channel,
241 mux_alarm,
242 &base_peripherals.uarte0,
243 )
244 .finalize(nrf52_components::uart_channel_component_static!(
245 nrf52840::rtc::Rtc
246 ));
247
248 let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200)
250 .finalize(components::uart_mux_component_static!());
251
252 let console = components::console::ConsoleComponent::new(
254 board_kernel,
255 capsules_core::console::DRIVER_NUM,
256 uart_mux,
257 )
258 .finalize(components::console_component_static!());
259
260 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
265
266 let sha = components::sha::ShaSoftware256Component::new()
272 .finalize(components::sha_software_256_component_static!());
273
274 let verifying_key0 = kernel::static_init!(
301 [u8; 64],
302 [
303 0xe0, 0x13, 0x3a, 0x90, 0xa7, 0x4a, 0x35, 0x61, 0x51, 0x8e, 0xe1, 0x44, 0x09, 0xf1,
304 0x69, 0xc1, 0xcf, 0x6a, 0xdb, 0x7f, 0x7e, 0x52, 0xf8, 0xb7, 0x41, 0x79, 0xe2, 0x4d,
305 0x57, 0x41, 0x23, 0x52, 0x2e, 0xb6, 0x12, 0x03, 0xb3, 0x85, 0x10, 0xe5, 0xf3, 0x25,
306 0x07, 0x62, 0x8f, 0x54, 0x95, 0x82, 0x57, 0x45, 0x50, 0xbd, 0xa3, 0xe2, 0x17, 0xe8,
307 0x34, 0x30, 0x89, 0x26, 0x4c, 0x23, 0x62, 0xb1
308 ]
309 );
310 let verifying_key1 = kernel::static_init!(
327 [u8; 64],
328 [
329 0xc9, 0x3d, 0x38, 0x79, 0xc0, 0x0b, 0x4a, 0x2f, 0x5c, 0xbf, 0xca, 0xfc, 0x03, 0x24,
330 0x14, 0x7b, 0xef, 0xa8, 0x9f, 0xe5, 0xf5, 0x2b, 0x77, 0x9c, 0xd9, 0xf3, 0x51, 0xfd,
331 0xbc, 0x37, 0xe7, 0x0c, 0x29, 0xe6, 0xee, 0xc3, 0xc4, 0xed, 0x57, 0x6d, 0x95, 0x8d,
332 0xc3, 0xc0, 0x73, 0x87, 0x4d, 0xf5, 0x8d, 0xa6, 0x3e, 0x8d, 0xef, 0xf8, 0xd3, 0xf0,
333 0xa7, 0x08, 0x22, 0xad, 0xf7, 0xf7, 0xa3, 0xaa,
334 ]
335 );
336 let verifying_keys =
337 kernel::static_init!([&'static mut [u8; 64]; 2], [verifying_key0, verifying_key1]);
338 let ecdsa_p256_verifying_key = kernel::static_init!([u8; 64], [0; 64]);
341 let ecdsa_p256_verifier = kernel::static_init!(
342 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier<'static>,
343 ecdsa_sw::p256_verifier::EcdsaP256SignatureVerifier::new(ecdsa_p256_verifying_key)
344 );
345 ecdsa_p256_verifier.register();
346
347 let verifier_multiple_keys =
349 components::signature_verify_in_memory_keys::SignatureVerifyInMemoryKeysComponent::new(
350 ecdsa_p256_verifier,
351 verifying_keys,
352 )
353 .finalize(
354 components::signature_verify_in_memory_keys_component_static!(Verifier, 2, 64, 32, 64,),
355 );
356
357 let checking_policy = components::appid::checker_signature::AppCheckerSignatureComponent::new(
359 sha,
360 verifier_multiple_keys,
361 tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
362 )
363 .finalize(components::app_checker_signature_component_static!(
364 SignatureVerifyInMemoryKeys,
365 capsules_extra::sha256::Sha256Software<'static>,
366 32,
367 64,
368 ));
369
370 let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
372 .finalize(components::appid_assigner_names_component_static!());
373
374 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
376 .finalize(components::process_checker_machine_component_static!());
377
378 let storage_permissions_policy =
383 components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
384 components::storage_permissions_null_component_static!(
385 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
386 kernel::process::ProcessStandardDebugFull,
387 ),
388 );
389
390 extern "C" {
396 static _sapps: u8;
398 static _eapps: u8;
400 static mut _sappmem: u8;
402 static _eappmem: u8;
404 }
405
406 let app_flash = core::slice::from_raw_parts(
407 core::ptr::addr_of!(_sapps),
408 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
409 );
410 let app_memory = core::slice::from_raw_parts_mut(
411 core::ptr::addr_of_mut!(_sappmem),
412 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
413 );
414
415 let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
417 checker,
418 board_kernel,
419 chip,
420 &FAULT_RESPONSE,
421 assigner,
422 storage_permissions_policy,
423 app_flash,
424 app_memory,
425 )
426 .finalize(components::process_loader_sequential_component_static!(
427 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
428 kernel::process::ProcessStandardDebugFull,
429 NUM_PROCS
430 ));
431
432 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
437 .finalize(components::round_robin_component_static!(NUM_PROCS));
438
439 let platform = Platform {
440 console,
441 led,
442 alarm,
443 scheduler,
444 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
445 };
446
447 board_kernel.kernel_loop(
448 &platform,
449 chip,
450 None::<&kernel::ipc::IPC<0>>,
451 &main_loop_capability,
452 );
453}