From b97af528f02dc619fc137121e00193eea2eef322 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 5 Jun 2024 13:43:17 -0400 Subject: [PATCH 1/2] boards: nrf52840dk: make 15.4 stack optional This moves the 15.4/udp stack into their own function in lib.rs which main.rs files can then use if they want. Unfortunately this gets more and more complicated as now the sub-boards need access to the alarm mux. --- boards/nordic/nrf52840dk/src/lib.rs | 191 ++++++++++-------- boards/nordic/nrf52840dk/src/main.rs | 81 +++++++- .../nrf52840dk-thread-tutorial/src/main.rs | 14 +- 3 files changed, 192 insertions(+), 94 deletions(-) diff --git a/boards/nordic/nrf52840dk/src/lib.rs b/boards/nordic/nrf52840dk/src/lib.rs index 7513730265..1166341986 100644 --- a/boards/nordic/nrf52840dk/src/lib.rs +++ b/boards/nordic/nrf52840dk/src/lib.rs @@ -72,7 +72,7 @@ use core::ptr::addr_of; -use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm; +use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm}; use capsules_extra::net::ieee802154::MacAddress; use capsules_extra::net::ipv6::ip_utils::IPAddr; use kernel::component::Component; @@ -84,7 +84,6 @@ use kernel::platform::{KernelResources, SyscallDriverLookup}; use kernel::scheduler::round_robin::RoundRobinSched; #[allow(unused_imports)] use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init}; -use nrf52840::chip::Nrf52DefaultPeripherals; use nrf52840::gpio::Pin; use nrf52840::interrupt_service::Nrf52840DefaultPeripherals; use nrf52_components::{UartChannel, UartPins}; @@ -189,13 +188,15 @@ type Ieee802154MacDevice = components::ieee802154::Ieee802154ComponentMacDeviceT nrf52840::ieee802154_radio::Radio<'static>, nrf52840::aes::AesECB<'static>, >; -type Ieee802154Driver = components::ieee802154::Ieee802154ComponentType< +/// Userspace 802.15.4 driver with in-kernel packet framing and MAC layer. +pub type Ieee802154Driver = components::ieee802154::Ieee802154ComponentType< nrf52840::ieee802154_radio::Radio<'static>, nrf52840::aes::AesECB<'static>, >; // EUI64 -type Eui64Driver = components::eui64::Eui64ComponentType; +/// Userspace EUI64 driver. +pub type Eui64Driver = components::eui64::Eui64ComponentType; /// Supported drivers by the platform pub struct Platform { @@ -204,8 +205,6 @@ pub struct Platform { nrf52840::ble_radio::Radio<'static>, VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>, >, - ieee802154_radio: &'static Ieee802154Driver, - eui64: &'static Eui64Driver, button: &'static capsules_core::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>, pconsole: &'static capsules_core::process_console::ProcessConsole< 'static, @@ -230,7 +229,6 @@ pub struct Platform { nrf52840::acomp::Comparator<'static>, >, alarm: &'static AlarmDriver, - udp_driver: &'static capsules_extra::net::udp::UDPDriver<'static>, i2c_master_slave: &'static capsules_core::i2c_master_slave_driver::I2CMasterSlaveDriver< 'static, nrf52840::i2c::TWI<'static>, @@ -261,11 +259,8 @@ impl SyscallDriverLookup for Platform { capsules_core::rng::DRIVER_NUM => f(Some(self.rng)), capsules_core::adc::DRIVER_NUM => f(Some(self.adc)), capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)), - capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_radio)), - capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)), capsules_extra::temperature::DRIVER_NUM => f(Some(self.temp)), capsules_extra::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)), - capsules_extra::net::udp::DRIVER_NUM => f(Some(self.udp_driver)), kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)), capsules_core::i2c_master_slave_driver::DRIVER_NUM => f(Some(self.i2c_master_slave)), capsules_core::spi_controller::DRIVER_NUM => f(Some(self.spi_controller)), @@ -307,6 +302,96 @@ impl KernelResources for Platform { } } +/// Create the capsules needed for the in-kernel UDP and 15.4 stack. +pub unsafe fn ieee802154_udp( + board_kernel: &'static kernel::Kernel, + nrf52840_peripherals: &'static Nrf52840DefaultPeripherals<'static>, + mux_alarm: &'static MuxAlarm, +) -> ( + &'static Eui64Driver, + &'static Ieee802154Driver, + &'static capsules_extra::net::udp::UDPDriver<'static>, +) { + //-------------------------------------------------------------------------- + // AES + //-------------------------------------------------------------------------- + + let aes_mux = + components::ieee802154::MuxAes128ccmComponent::new(&nrf52840_peripherals.nrf52.ecb) + .finalize(components::mux_aes128ccm_component_static!( + nrf52840::aes::AesECB + )); + + //-------------------------------------------------------------------------- + // 802.15.4 + //-------------------------------------------------------------------------- + + let device_id = nrf52840::ficr::FICR_INSTANCE.id(); + let device_id_bottom_16: u16 = u16::from_le_bytes([device_id[0], device_id[1]]); + + let eui64_driver = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id)) + .finalize(components::eui64_component_static!()); + + let (ieee802154_driver, mux_mac) = components::ieee802154::Ieee802154Component::new( + board_kernel, + capsules_extra::ieee802154::DRIVER_NUM, + &nrf52840_peripherals.ieee802154_radio, + aes_mux, + PAN_ID, + device_id_bottom_16, + device_id, + ) + .finalize(components::ieee802154_component_static!( + nrf52840::ieee802154_radio::Radio, + nrf52840::aes::AesECB<'static> + )); + + //-------------------------------------------------------------------------- + // UDP + //-------------------------------------------------------------------------- + + let local_ip_ifaces = static_init!( + [IPAddr; 3], + [ + IPAddr::generate_from_mac(capsules_extra::net::ieee802154::MacAddress::Long(device_id)), + IPAddr([ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, + ]), + IPAddr::generate_from_mac(capsules_extra::net::ieee802154::MacAddress::Short( + device_id_bottom_16 + )), + ] + ); + + let (udp_send_mux, udp_recv_mux, udp_port_table) = components::udp_mux::UDPMuxComponent::new( + mux_mac, + DEFAULT_CTX_PREFIX_LEN, + DEFAULT_CTX_PREFIX, + DST_MAC_ADDR, + MacAddress::Long(device_id), + local_ip_ifaces, + mux_alarm, + ) + .finalize(components::udp_mux_component_static!( + nrf52840::rtc::Rtc, + Ieee802154MacDevice + )); + + // UDP driver initialization happens here + let udp_driver = components::udp_driver::UDPDriverComponent::new( + board_kernel, + capsules_extra::net::udp::driver::DRIVER_NUM, + udp_send_mux, + udp_recv_mux, + udp_port_table, + local_ip_ifaces, + ) + .finalize(components::udp_driver_component_static!(nrf52840::rtc::Rtc)); + + (eui64_driver, ieee802154_driver, udp_driver) +} + /// This is in a separate, inline(never) function so that its stack frame is /// removed when this function returns. Otherwise, the stack space used for /// these static_inits is wasted. @@ -315,7 +400,8 @@ pub unsafe fn start() -> ( &'static kernel::Kernel, Platform, &'static Chip, - &'static Nrf52DefaultPeripherals<'static>, + &'static Nrf52840DefaultPeripherals<'static>, + &'static MuxAlarm<'static, nrf52840::rtc::Rtc<'static>>, ) { //-------------------------------------------------------------------------- // INITIAL SETUP @@ -536,15 +622,6 @@ pub unsafe fn start() -> ( components::debug_writer::DebugWriterComponent::new(uart_mux) .finalize(components::debug_writer_component_static!()); - //-------------------------------------------------------------------------- - // AES - //-------------------------------------------------------------------------- - - let aes_mux = components::ieee802154::MuxAes128ccmComponent::new(&base_peripherals.ecb) - .finalize(components::mux_aes128ccm_component_static!( - nrf52840::aes::AesECB - )); - //-------------------------------------------------------------------------- // BLE //-------------------------------------------------------------------------- @@ -560,69 +637,6 @@ pub unsafe fn start() -> ( nrf52840::ble_radio::Radio )); - //-------------------------------------------------------------------------- - // IEEE 802.15.4 and UDP - //-------------------------------------------------------------------------- - - let device_id = nrf52840::ficr::FICR_INSTANCE.id(); - let device_id_bottom_16: u16 = u16::from_le_bytes([device_id[0], device_id[1]]); - - let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id)) - .finalize(components::eui64_component_static!()); - - let (ieee802154_radio, mux_mac) = components::ieee802154::Ieee802154Component::new( - board_kernel, - capsules_extra::ieee802154::DRIVER_NUM, - &nrf52840_peripherals.ieee802154_radio, - aes_mux, - PAN_ID, - device_id_bottom_16, - device_id, - ) - .finalize(components::ieee802154_component_static!( - nrf52840::ieee802154_radio::Radio, - nrf52840::aes::AesECB<'static> - )); - - let local_ip_ifaces = static_init!( - [IPAddr; 3], - [ - IPAddr::generate_from_mac(capsules_extra::net::ieee802154::MacAddress::Long(device_id)), - IPAddr([ - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f, - ]), - IPAddr::generate_from_mac(capsules_extra::net::ieee802154::MacAddress::Short( - device_id_bottom_16 - )), - ] - ); - - let (udp_send_mux, udp_recv_mux, udp_port_table) = components::udp_mux::UDPMuxComponent::new( - mux_mac, - DEFAULT_CTX_PREFIX_LEN, - DEFAULT_CTX_PREFIX, - DST_MAC_ADDR, - MacAddress::Long(device_id), - local_ip_ifaces, - mux_alarm, - ) - .finalize(components::udp_mux_component_static!( - nrf52840::rtc::Rtc, - Ieee802154MacDevice - )); - - // UDP driver initialization happens here - let udp_driver = components::udp_driver::UDPDriverComponent::new( - board_kernel, - capsules_extra::net::udp::driver::DRIVER_NUM, - udp_send_mux, - udp_recv_mux, - udp_port_table, - local_ip_ifaces, - ) - .finalize(components::udp_driver_component_static!(nrf52840::rtc::Rtc)); - //-------------------------------------------------------------------------- // TEMPERATURE (internal) //-------------------------------------------------------------------------- @@ -875,8 +889,6 @@ pub unsafe fn start() -> ( let platform = Platform { button, ble_radio, - ieee802154_radio, - eui64, pconsole, console, led, @@ -886,7 +898,6 @@ pub unsafe fn start() -> ( temp, alarm, analog_comparator, - udp_driver, ipc: kernel::ipc::IPC::new( board_kernel, kernel::ipc::DRIVER_NUM, @@ -905,5 +916,11 @@ pub unsafe fn start() -> ( debug!("Initialization complete. Entering main loop\r"); debug!("{}", &*addr_of!(nrf52840::ficr::FICR_INSTANCE)); - (board_kernel, platform, chip, base_peripherals) + ( + board_kernel, + platform, + chip, + nrf52840_peripherals, + mux_alarm, + ) } diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs index 3f2bc55afd..1462e653ba 100644 --- a/boards/nordic/nrf52840dk/src/main.rs +++ b/boards/nordic/nrf52840dk/src/main.rs @@ -13,6 +13,7 @@ use core::ptr::addr_of_mut; use kernel::debug; +use kernel::platform::{KernelResources, SyscallDriverLookup}; use kernel::{capabilities, create_capability}; use nrf52840dk_lib::{self, PROCESSES}; @@ -21,10 +22,81 @@ use nrf52840dk_lib::{self, PROCESSES}; const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy = capsules_system::process_policies::PanicFaultPolicy {}; +struct Platform { + base: nrf52840dk_lib::Platform, + eui64_driver: &'static nrf52840dk_lib::Eui64Driver, + ieee802154_driver: &'static nrf52840dk_lib::Ieee802154Driver, + udp_driver: &'static capsules_extra::net::udp::UDPDriver<'static>, +} + +impl SyscallDriverLookup for Platform { + fn with_driver(&self, driver_num: usize, f: F) -> R + where + F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R, + { + match driver_num { + capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64_driver)), + capsules_extra::net::udp::DRIVER_NUM => f(Some(self.udp_driver)), + capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_driver)), + _ => self.base.with_driver(driver_num, f), + } + } +} + +type Chip = nrf52840dk_lib::Chip; + +impl KernelResources for Platform { + type SyscallDriverLookup = Self; + type SyscallFilter = >::SyscallFilter; + type ProcessFault = >::ProcessFault; + type Scheduler = >::Scheduler; + type SchedulerTimer = >::SchedulerTimer; + type WatchDog = >::WatchDog; + type ContextSwitchCallback = + >::ContextSwitchCallback; + + fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup { + self + } + fn syscall_filter(&self) -> &Self::SyscallFilter { + self.base.syscall_filter() + } + fn process_fault(&self) -> &Self::ProcessFault { + self.base.process_fault() + } + fn scheduler(&self) -> &Self::Scheduler { + self.base.scheduler() + } + fn scheduler_timer(&self) -> &Self::SchedulerTimer { + self.base.scheduler_timer() + } + fn watchdog(&self) -> &Self::WatchDog { + self.base.watchdog() + } + fn context_switch_callback(&self) -> &Self::ContextSwitchCallback { + self.base.context_switch_callback() + } +} + /// Main function called after RAM initialized. #[no_mangle] pub unsafe fn main() { - let (board_kernel, platform, chip, _default_peripherals) = nrf52840dk_lib::start(); + let (board_kernel, base_platform, chip, default_peripherals, mux_alarm) = + nrf52840dk_lib::start(); + + //-------------------------------------------------------------------------- + // IEEE 802.15.4 and UDP + //-------------------------------------------------------------------------- + + let (eui64_driver, ieee802154_driver, udp_driver) = + nrf52840dk_lib::ieee802154_udp(board_kernel, default_peripherals, mux_alarm); + + let platform = Platform { + base: base_platform, + eui64_driver, + ieee802154_driver, + udp_driver, + }; // These symbols are defined in the linker script. extern "C" { @@ -61,5 +133,10 @@ pub unsafe fn main() { }); let main_loop_capability = create_capability!(capabilities::MainLoopCapability); - board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability); + board_kernel.kernel_loop( + &platform, + chip, + Some(&platform.base.ipc), + &main_loop_capability, + ); } diff --git a/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs b/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs index f8f4aa6737..e835a5bbc5 100644 --- a/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs +++ b/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs @@ -89,7 +89,8 @@ pub unsafe fn main() { let main_loop_capability = create_capability!(capabilities::MainLoopCapability); // Create the base board: - let (board_kernel, base_platform, chip, base_peripherals) = nrf52840dk_lib::start(); + let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) = + nrf52840dk_lib::start(); //-------------------------------------------------------------------------- // SCREEN @@ -98,13 +99,16 @@ pub unsafe fn main() { const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10; const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11; - let i2c_bus = components::i2c::I2CMuxComponent::new(&base_peripherals.twi0, None) + let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi0, None) .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI)); - base_peripherals.twi0.configure( + nrf52840_peripherals.nrf52.twi0.configure( nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32), nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32), ); - base_peripherals.twi0.set_speed(nrf52840::i2c::Speed::K400); + nrf52840_peripherals + .nrf52 + .twi0 + .set_speed(nrf52840::i2c::Speed::K400); // I2C address is b011110X, and on this board D/C̅ is GND. let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c) @@ -139,7 +143,7 @@ pub unsafe fn main() { let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new( board_kernel, capsules_extra::nonvolatile_storage_driver::DRIVER_NUM, - &base_peripherals.nvmc, + &nrf52840_peripherals.nrf52.nvmc, core::ptr::addr_of!(APP_STORAGE) as usize, APP_STORAGE.len(), // No kernel-writeable flash: From 84e5c25617eb7e18e3b3d6608dacb1f3e4ef5252 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Wed, 5 Jun 2024 13:48:36 -0400 Subject: [PATCH 2/2] boards: nrf52840dk tutorial: add 15.4 raw stack --- .../nrf52840dk-thread-tutorial/src/main.rs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs b/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs index e835a5bbc5..6599535153 100644 --- a/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs +++ b/boards/tutorials/nrf52840dk-thread-tutorial/src/main.rs @@ -26,8 +26,13 @@ type ScreenDriver = components::screen::ScreenComponentType; const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy = capsules_system::process_policies::PanicFaultPolicy {}; +type Ieee802154RawDriver = + components::ieee802154::Ieee802154RawComponentType>; + struct Platform { base: nrf52840dk_lib::Platform, + ieee802154: &'static Ieee802154RawDriver, + eui64: &'static nrf52840dk_lib::Eui64Driver, screen: &'static ScreenDriver, nonvolatile_storage: &'static capsules_extra::nonvolatile_storage_driver::NonvolatileStorage<'static>, @@ -39,6 +44,8 @@ impl SyscallDriverLookup for Platform { F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R, { match driver_num { + capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)), + capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)), capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)), capsules_extra::nonvolatile_storage_driver::DRIVER_NUM => { f(Some(self.nonvolatile_storage)) @@ -92,6 +99,24 @@ pub unsafe fn main() { let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) = nrf52840dk_lib::start(); + //-------------------------------------------------------------------------- + // RAW 802.15.4 + //-------------------------------------------------------------------------- + + let device_id = nrf52840::ficr::FICR_INSTANCE.id(); + + let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id)) + .finalize(components::eui64_component_static!()); + + let ieee802154 = components::ieee802154::Ieee802154RawComponent::new( + board_kernel, + capsules_extra::ieee802154::DRIVER_NUM, + &nrf52840_peripherals.ieee802154_radio, + ) + .finalize(components::ieee802154_raw_component_static!( + nrf52840::ieee802154_radio::Radio, + )); + //-------------------------------------------------------------------------- // SCREEN //-------------------------------------------------------------------------- @@ -160,6 +185,8 @@ pub unsafe fn main() { let platform = Platform { base: base_platform, + eui64, + ieee802154, screen, nonvolatile_storage, };