1#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use core::ptr::addr_of;
14
15use kernel::capabilities;
16use kernel::component::Component;
17use kernel::debug::PanicResources;
18use kernel::hil::led::LedLow;
19use kernel::hil::time::Counter;
20use kernel::hil::usb::Client;
21use kernel::platform::{KernelResources, SyscallDriverLookup};
22use kernel::scheduler::round_robin::RoundRobinSched;
23use kernel::utilities::cells::MapCell;
24use kernel::utilities::single_thread_value::SingleThreadValue;
25#[allow(unused_imports)]
26use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init};
27
28use nrf52840::gpio::Pin;
29use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
30
31const LED_PIN: Pin = Pin::P1_11;
37
38const BUTTON_RST_PIN: Pin = Pin::P0_18;
39const BUTTON_PIN: Pin = Pin::P1_15;
40
41const GPIO_D0: Pin = Pin::P0_23;
42const GPIO_D1: Pin = Pin::P0_12;
43const GPIO_D2: Pin = Pin::P0_09;
44const GPIO_D3: Pin = Pin::P0_07;
45
46const _UART_TX_PIN: Pin = Pin::P0_06;
47const _UART_RX_PIN: Pin = Pin::P0_08;
48
49const I2C_SDA_PIN: Pin = Pin::P0_26;
51const I2C_SCL_PIN: Pin = Pin::P0_27;
52
53const PAN_ID: u16 = 0xABCD;
56const DST_MAC_ADDR: capsules_extra::net::ieee802154::MacAddress =
58 capsules_extra::net::ieee802154::MacAddress::Short(49138);
59const DEFAULT_CTX_PREFIX_LEN: u8 = 8; const DEFAULT_CTX_PREFIX: [u8; 16] = [0x0_u8; 16]; pub mod io;
64
65const FAULT_RESPONSE: capsules_system::process_policies::StopWithDebugFaultPolicy =
70 capsules_system::process_policies::StopWithDebugFaultPolicy {};
71
72const NUM_PROCS: usize = 8;
74
75type ChipHw = nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>;
76type ProcessPrinter = capsules_system::process_printer::ProcessPrinterText;
77
78static mut CDC_REF_FOR_PANIC: Option<
79 &'static capsules_extra::usb::cdc::CdcAcm<
80 'static,
81 nrf52::usbd::Usbd,
82 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc>,
83 >,
84> = None;
85static PANIC_RESOURCES: SingleThreadValue<PanicResources<ChipHw, ProcessPrinter>> =
87 SingleThreadValue::new(PanicResources::new());
88static NRF52_POWER: SingleThreadValue<MapCell<&'static nrf52840::power::Power>> =
89 SingleThreadValue::new(MapCell::empty());
90
91kernel::stack_size! {0x1000}
92
93fn baud_rate_reset_bootloader_enter() {
95 unsafe {
96 NRF52_POWER.get().map(|power_cell| {
98 power_cell.map(|power| {
99 power.set_gpregret(0x90);
100 });
101 });
102 cortexm4::scb::reset();
103 }
104}
105
106fn crc(s: &'static str) -> u32 {
107 kernel::utilities::helpers::crc32_posix(s.as_bytes())
108}
109
110type AlarmDriver = components::alarm::AlarmDriverComponentType<nrf52840::rtc::Rtc<'static>>;
115
116type Screen = components::ssd1306::Ssd1306ComponentType<nrf52840::i2c::TWI<'static>>;
117type ScreenDriver = components::screen::ScreenSharedComponentType<Screen>;
118
119type Ieee802154MacDevice = components::ieee802154::Ieee802154ComponentMacDeviceType<
120 nrf52840::ieee802154_radio::Radio<'static>,
121 nrf52840::aes::AesECB<'static>,
122>;
123type Ieee802154Driver = components::ieee802154::Ieee802154ComponentType<
124 nrf52840::ieee802154_radio::Radio<'static>,
125 nrf52840::aes::AesECB<'static>,
126>;
127type RngDriver = components::rng::RngComponentType<nrf52840::trng::Trng<'static>>;
128
129pub struct Platform {
131 ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
132 'static,
133 nrf52::ble_radio::Radio<'static>,
134 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
135 'static,
136 nrf52::rtc::Rtc<'static>,
137 >,
138 >,
139 ieee802154_radio: &'static Ieee802154Driver,
140 console: &'static capsules_core::console::Console<'static>,
141 pconsole: &'static capsules_core::process_console::ProcessConsole<
142 'static,
143 { capsules_core::process_console::DEFAULT_COMMAND_HISTORY_LEN },
144 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
145 'static,
146 nrf52::rtc::Rtc<'static>,
147 >,
148 components::process_console::Capability,
149 >,
150 gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
151 led: &'static capsules_core::led::LedDriver<
152 'static,
153 LedLow<'static, nrf52::gpio::GPIOPin<'static>>,
154 1,
155 >,
156 adc: &'static capsules_core::adc::AdcVirtualized<'static>,
157 rng: &'static RngDriver,
158 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
159 alarm: &'static AlarmDriver,
160 button: &'static capsules_core::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
161 screen: &'static ScreenDriver,
162 udp_driver: &'static capsules_extra::net::udp::UDPDriver<'static>,
163 scheduler: &'static RoundRobinSched<'static>,
164 systick: cortexm4::systick::SysTick,
165}
166
167impl SyscallDriverLookup for Platform {
168 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
169 where
170 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
171 {
172 match driver_num {
173 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
174 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
175 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
176 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
177 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
178 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
179 capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
180 capsules_extra::screen::screen::DRIVER_NUM => f(Some(self.screen)),
181 capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
182 capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_radio)),
183 capsules_extra::net::udp::DRIVER_NUM => f(Some(self.udp_driver)),
184 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
185 _ => f(None),
186 }
187 }
188}
189
190impl KernelResources<nrf52::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
191 for Platform
192{
193 type SyscallDriverLookup = Self;
194 type SyscallFilter = ();
195 type ProcessFault = ();
196 type Scheduler = RoundRobinSched<'static>;
197 type SchedulerTimer = cortexm4::systick::SysTick;
198 type WatchDog = ();
199 type ContextSwitchCallback = ();
200
201 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
202 self
203 }
204 fn syscall_filter(&self) -> &Self::SyscallFilter {
205 &()
206 }
207 fn process_fault(&self) -> &Self::ProcessFault {
208 &()
209 }
210 fn scheduler(&self) -> &Self::Scheduler {
211 self.scheduler
212 }
213 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
214 &self.systick
215 }
216 fn watchdog(&self) -> &Self::WatchDog {
217 &()
218 }
219 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
220 &()
221 }
222}
223
224#[inline(never)]
228pub unsafe fn start() -> (
229 &'static kernel::Kernel,
230 Platform,
231 &'static nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>,
232) {
233 nrf52840::init();
234
235 kernel::deferred_call::initialize_deferred_call_state::<
237 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
238 >();
239
240 PANIC_RESOURCES.bind_to_thread::<<ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider>();
242 NRF52_POWER.bind_to_thread::<<ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider>();
243
244 let ieee802154_ack_buf = static_init!(
245 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
246 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
247 );
248
249 let nrf52840_peripherals = static_init!(
251 Nrf52840DefaultPeripherals,
252 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
253 );
254
255 nrf52840_peripherals.init();
257 let base_peripherals = &nrf52840_peripherals.nrf52;
258
259 NRF52_POWER.get().map(|power_cell| {
262 power_cell.put(&base_peripherals.pwr_clk);
263 });
264
265 let processes = components::process_array::ProcessArrayComponent::new()
267 .finalize(components::process_array_component_static!(NUM_PROCS));
268 PANIC_RESOURCES.get().map(|resources| {
269 resources.processes.put(processes.as_slice());
270 });
271
272 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
274
275 nrf52_components::startup::NrfStartupComponent::new(
278 false,
279 BUTTON_RST_PIN,
280 nrf52840::uicr::Regulator0Output::DEFAULT,
281 &base_peripherals.nvmc,
282 )
283 .finalize(());
284
285 let chip = static_init!(
286 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
287 nrf52840::chip::NRF52::new(nrf52840_peripherals)
288 );
289 PANIC_RESOURCES.get().map(|resources| {
290 resources.chip.put(chip);
291 });
292
293 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
300
301 let debug_gpios = static_init!(
309 [&'static dyn kernel::hil::gpio::Pin; 1],
310 [&nrf52840_peripherals.gpio_port[LED_PIN]]
311 );
312 kernel::debug::initialize_debug_gpio::<
313 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
314 >();
315 kernel::debug::assign_gpios(debug_gpios);
316
317 let gpio = components::gpio::GpioComponent::new(
322 board_kernel,
323 capsules_core::gpio::DRIVER_NUM,
324 components::gpio_component_helper!(
325 nrf52840::gpio::GPIOPin,
326 0 => &nrf52840_peripherals.gpio_port[GPIO_D0],
327 1 => &nrf52840_peripherals.gpio_port[GPIO_D1],
328 2 => &nrf52840_peripherals.gpio_port[GPIO_D2],
329 3 => &nrf52840_peripherals.gpio_port[GPIO_D3],
330 ),
331 )
332 .finalize(components::gpio_component_static!(nrf52840::gpio::GPIOPin));
333
334 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
339 LedLow<'static, nrf52840::gpio::GPIOPin>,
340 LedLow::new(&nrf52840_peripherals.gpio_port[LED_PIN]),
341 ));
342
343 let button = components::button::ButtonComponent::new(
348 board_kernel,
349 capsules_core::button::DRIVER_NUM,
350 components::button_component_helper!(
351 nrf52840::gpio::GPIOPin,
352 (
353 &nrf52840_peripherals.gpio_port[BUTTON_PIN],
354 kernel::hil::gpio::ActivationMode::ActiveLow,
355 kernel::hil::gpio::FloatingState::PullUp
356 )
357 ),
358 )
359 .finalize(components::button_component_static!(
360 nrf52840::gpio::GPIOPin
361 ));
362
363 let rtc = &base_peripherals.rtc;
368 let _ = rtc.start();
369
370 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
371 .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
372 let alarm = components::alarm::AlarmDriverComponent::new(
373 board_kernel,
374 capsules_core::alarm::DRIVER_NUM,
375 mux_alarm,
376 )
377 .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
378
379 let serial_number_buf = static_init!([u8; 17], [0; 17]);
389 let serial_number_string: &'static str =
390 (*addr_of!(nrf52::ficr::FICR_INSTANCE)).address_str(serial_number_buf);
391 let strings = static_init!(
392 [&str; 3],
393 [
394 "MakePython", "NRF52840 - TockOS", serial_number_string, ]
398 );
399
400 let cdc = components::cdc::CdcAcmComponent::new(
401 &nrf52840_peripherals.usbd,
402 capsules_extra::usb::cdc::MAX_CTRL_PACKET_SIZE_NRF52840,
403 0x2341,
404 0x005a,
405 strings,
406 mux_alarm,
407 Some(&baud_rate_reset_bootloader_enter),
408 )
409 .finalize(components::cdc_acm_component_static!(
410 nrf52::usbd::Usbd,
411 nrf52::rtc::Rtc
412 ));
413 CDC_REF_FOR_PANIC = Some(cdc); let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
417 .finalize(components::process_printer_text_component_static!());
418 PANIC_RESOURCES.get().map(|resources| {
419 resources.printer.put(process_printer);
420 });
421
422 let uart_mux = components::console::UartMuxComponent::new(cdc, 115200)
424 .finalize(components::uart_mux_component_static!());
425
426 let pconsole = components::process_console::ProcessConsoleComponent::new(
427 board_kernel,
428 uart_mux,
429 mux_alarm,
430 process_printer,
431 Some(cortexm4::support::reset),
432 )
433 .finalize(components::process_console_component_static!(
434 nrf52::rtc::Rtc<'static>
435 ));
436
437 let console = components::console::ConsoleComponent::new(
439 board_kernel,
440 capsules_core::console::DRIVER_NUM,
441 uart_mux,
442 )
443 .finalize(components::console_component_static!());
444 components::debug_writer::DebugWriterComponent::new::<
446 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
447 >(
448 uart_mux,
449 create_capability!(capabilities::SetDebugWriterCapability),
450 )
451 .finalize(components::debug_writer_component_static!());
452
453 let rng = components::rng::RngComponent::new(
458 board_kernel,
459 capsules_core::rng::DRIVER_NUM,
460 &base_peripherals.trng,
461 )
462 .finalize(components::rng_component_static!(nrf52840::trng::Trng));
463
464 base_peripherals.adc.calibrate();
468
469 let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
470 .finalize(components::adc_mux_component_static!(nrf52840::adc::Adc));
471
472 let adc_syscall =
473 components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
474 .finalize(components::adc_syscall_component_helper!(
475 components::adc::AdcComponent::new(
477 adc_mux,
478 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput2)
479 )
480 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
481 components::adc::AdcComponent::new(
483 adc_mux,
484 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput3)
485 )
486 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
487 components::adc::AdcComponent::new(
489 adc_mux,
490 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput6)
491 )
492 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
493 components::adc::AdcComponent::new(
495 adc_mux,
496 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput5)
497 )
498 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
499 components::adc::AdcComponent::new(
501 adc_mux,
502 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput7)
503 )
504 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
505 components::adc::AdcComponent::new(
507 adc_mux,
508 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput0)
509 )
510 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
511 components::adc::AdcComponent::new(
513 adc_mux,
514 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput4)
515 )
516 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
517 components::adc::AdcComponent::new(
519 adc_mux,
520 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput1)
521 )
522 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
523 ));
524
525 let i2c_bus = components::i2c::I2CMuxComponent::new(&base_peripherals.twi1, None)
530 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
531 base_peripherals.twi1.configure(
532 nrf52840::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
533 nrf52840::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
534 );
535
536 let ssd1306_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
538 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
539
540 let ssd1306 = components::ssd1306::Ssd1306Component::new(ssd1306_i2c, true)
542 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
543
544 let apps_regions = static_init!(
554 [capsules_extra::screen::screen_shared::AppScreenRegion; 3],
555 [
556 capsules_extra::screen::screen_shared::AppScreenRegion::new(
557 kernel::process::ShortId::Fixed(core::num::NonZeroU32::new(crc("circle")).unwrap()),
558 0, 0, 8 * 8, 8 * 8 ),
563 capsules_extra::screen::screen_shared::AppScreenRegion::new(
564 kernel::process::ShortId::Fixed(core::num::NonZeroU32::new(crc("count")).unwrap()),
565 8 * 8, 0, 8 * 8, 4 * 8 ),
570 capsules_extra::screen::screen_shared::AppScreenRegion::new(
571 kernel::process::ShortId::Fixed(
572 core::num::NonZeroU32::new(crc("tock-scroll")).unwrap()
573 ),
574 8 * 8, 4 * 8, 8 * 8, 4 * 8 )
579 ]
580 );
581
582 let screen = components::screen::ScreenSharedComponent::new(
583 board_kernel,
584 capsules_extra::screen::screen::DRIVER_NUM,
585 ssd1306,
586 apps_regions,
587 )
588 .finalize(components::screen_shared_component_static!(1032, Screen));
589
590 let ble_radio = components::ble::BLEComponent::new(
595 board_kernel,
596 capsules_extra::ble_advertising_driver::DRIVER_NUM,
597 &base_peripherals.ble_radio,
598 mux_alarm,
599 )
600 .finalize(components::ble_component_static!(
601 nrf52840::rtc::Rtc,
602 nrf52840::ble_radio::Radio
603 ));
604
605 use capsules_extra::net::ieee802154::MacAddress;
606
607 let aes_mux = components::ieee802154::MuxAes128ccmComponent::new(&base_peripherals.ecb)
608 .finalize(components::mux_aes128ccm_component_static!(
609 nrf52840::aes::AesECB
610 ));
611
612 let device_id = (*addr_of!(nrf52840::ficr::FICR_INSTANCE)).id();
613 let device_id_bottom_16 = u16::from_le_bytes([device_id[0], device_id[1]]);
614 let (ieee802154_radio, mux_mac) = components::ieee802154::Ieee802154Component::new(
615 board_kernel,
616 capsules_extra::ieee802154::DRIVER_NUM,
617 &nrf52840_peripherals.ieee802154_radio,
618 aes_mux,
619 PAN_ID,
620 device_id_bottom_16,
621 device_id,
622 )
623 .finalize(components::ieee802154_component_static!(
624 nrf52840::ieee802154_radio::Radio,
625 nrf52840::aes::AesECB<'static>
626 ));
627 use capsules_extra::net::ipv6::ip_utils::IPAddr;
628
629 let local_ip_ifaces = static_init!(
630 [IPAddr; 3],
631 [
632 IPAddr([
633 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
634 0x0e, 0x0f,
635 ]),
636 IPAddr([
637 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
638 0x1e, 0x1f,
639 ]),
640 IPAddr::generate_from_mac(capsules_extra::net::ieee802154::MacAddress::Short(
641 device_id_bottom_16
642 )),
643 ]
644 );
645
646 let (udp_send_mux, udp_recv_mux, udp_port_table) = components::udp_mux::UDPMuxComponent::new(
647 mux_mac,
648 DEFAULT_CTX_PREFIX_LEN,
649 DEFAULT_CTX_PREFIX,
650 DST_MAC_ADDR,
651 MacAddress::Short(device_id_bottom_16),
652 local_ip_ifaces,
653 mux_alarm,
654 )
655 .finalize(components::udp_mux_component_static!(
656 nrf52840::rtc::Rtc,
657 Ieee802154MacDevice
658 ));
659
660 let udp_driver = components::udp_driver::UDPDriverComponent::new(
662 board_kernel,
663 capsules_extra::net::udp::DRIVER_NUM,
664 udp_send_mux,
665 udp_recv_mux,
666 udp_port_table,
667 local_ip_ifaces,
668 )
669 .finalize(components::udp_driver_component_static!(nrf52840::rtc::Rtc));
670
671 let sha = components::sha::ShaSoftware256Component::new()
677 .finalize(components::sha_software_256_component_static!());
678
679 let checking_policy = components::appid::checker_sha::AppCheckerSha256Component::new(sha)
681 .finalize(components::app_checker_sha256_component_static!());
682
683 let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
685 .finalize(components::appid_assigner_names_component_static!());
686
687 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
689 .finalize(components::process_checker_machine_component_static!());
690
691 let storage_permissions_policy =
696 components::storage_permissions::individual::StoragePermissionsIndividualComponent::new()
697 .finalize(
698 components::storage_permissions_individual_component_static!(
699 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
700 kernel::process::ProcessStandardDebugFull,
701 ),
702 );
703
704 extern "C" {
710 static _sapps: u8;
712 static _eapps: u8;
714 static mut _sappmem: u8;
716 static _eappmem: u8;
718 }
719
720 let app_flash = core::slice::from_raw_parts(
721 core::ptr::addr_of!(_sapps),
722 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
723 );
724 let app_memory = core::slice::from_raw_parts_mut(
725 core::ptr::addr_of_mut!(_sappmem),
726 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
727 );
728
729 let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
731 checker,
732 board_kernel,
733 chip,
734 &FAULT_RESPONSE,
735 assigner,
736 storage_permissions_policy,
737 app_flash,
738 app_memory,
739 )
740 .finalize(components::process_loader_sequential_component_static!(
741 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
742 kernel::process::ProcessStandardDebugFull,
743 NUM_PROCS
744 ));
745
746 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
753
754 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
755 .finalize(components::round_robin_component_static!(NUM_PROCS));
756
757 let platform = Platform {
758 ble_radio,
759 ieee802154_radio,
760 console,
761 pconsole,
762 adc: adc_syscall,
763 led,
764 button,
765 gpio,
766 rng,
767 screen,
768 alarm,
769 udp_driver,
770 ipc: kernel::ipc::IPC::new(
771 board_kernel,
772 kernel::ipc::DRIVER_NUM,
773 &memory_allocation_capability,
774 ),
775 scheduler,
776 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
777 };
778
779 cdc.enable();
781 cdc.attach();
782
783 debug!("Initialization complete. Entering main loop.");
796 let _ = platform.pconsole.start();
797
798 ssd1306.init_screen();
799
800 (board_kernel, platform, chip)
805}
806
807#[no_mangle]
809pub unsafe fn main() {
810 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
811
812 let (board_kernel, platform, chip) = start();
813 board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability);
814}