From fcd3a45f95286f8bc743249a13ea0832d779624f Mon Sep 17 00:00:00 2001 From: viswajith-g Date: Wed, 30 Apr 2025 16:51:23 -0400 Subject: [PATCH 01/14] boards: tutorials: add nrf52840dk-process-control and other required docs --- Cargo.toml | 1 + .../.cargo/config.toml | 14 + .../nrf52840dk-process-control/Cargo.toml | 34 + .../nrf52840dk-process-control/Makefile | 6 + .../nrf52840dk-process-control/README.md | 9 + .../jtag/gdbinit_pca10040.jlink | 28 + .../jtag/jdbserver_pca10040.sh | 5 + .../nrf52840dk-process-control/layout.ld | 6 + .../nrf52840dk-process-control/src/io.rs | 91 +++ .../nrf52840dk-process-control/src/main.rs | 641 ++++++++++++++++++ 10 files changed, 835 insertions(+) create mode 100644 boards/tutorials/nrf52840dk-process-control/.cargo/config.toml create mode 100644 boards/tutorials/nrf52840dk-process-control/Cargo.toml create mode 100644 boards/tutorials/nrf52840dk-process-control/Makefile create mode 100644 boards/tutorials/nrf52840dk-process-control/README.md create mode 100644 boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink create mode 100644 boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh create mode 100644 boards/tutorials/nrf52840dk-process-control/layout.ld create mode 100644 boards/tutorials/nrf52840dk-process-control/src/io.rs create mode 100644 boards/tutorials/nrf52840dk-process-control/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index f7077eb30b..aaa089dc88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,7 @@ members = [ "boards/configurations/nrf52840dk/nrf52840dk-test-dynamic-app-load", "boards/configurations/microbit_v2/microbit_v2-test-dynamic-app-load", "boards/tutorials/nrf52840dk-hotp-tutorial", + "boards/tutorials/nrf52840dk-process-control", "boards/tutorials/nrf52840dk-thread-tutorial", "capsules/aes_gcm", "capsules/ecdsa_sw", diff --git a/boards/tutorials/nrf52840dk-process-control/.cargo/config.toml b/boards/tutorials/nrf52840dk-process-control/.cargo/config.toml new file mode 100644 index 0000000000..1d8a988dc4 --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/.cargo/config.toml @@ -0,0 +1,14 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2024. + +include = [ + "../../../cargo/tock_flags.toml", + "../../../cargo/unstable_flags.toml", +] + +[build] +target = "thumbv7em-none-eabi" + +[unstable] +config-include = true diff --git a/boards/tutorials/nrf52840dk-process-control/Cargo.toml b/boards/tutorials/nrf52840dk-process-control/Cargo.toml new file mode 100644 index 0000000000..45f908084f --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/Cargo.toml @@ -0,0 +1,34 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2022. + +[package] +name = "nrf52840dk-process-control" +version.workspace = true +authors.workspace = true +build = "../../build.rs" +edition.workspace = true + +[features] +default = ["screen_ssd1306"] +screen_ssd1306 = [] +screen_sh1106 = [] + +[dependencies] +kernel = { path = "../../../kernel" } + +components = { path = "../../components" } +segger = { path = "../../../chips/segger" } +cortexm4 = { path = "../../../arch/cortex-m4" } +nrf52840 = { path = "../../../chips/nrf52840" } +nrf52840dk = { path = "../../nordic/nrf52840dk" } +capsules-core = { path = "../../../capsules/core" } +capsules-extra = { path = "../../../capsules/extra" } +capsules-system = { path = "../../../capsules/system" } +nrf52_components = { path = "../../nordic/nrf52_components" } + +[build-dependencies] +tock_build_scripts = { path = "../../build_scripts" } + +[lints] +workspace = true diff --git a/boards/tutorials/nrf52840dk-process-control/Makefile b/boards/tutorials/nrf52840dk-process-control/Makefile new file mode 100644 index 0000000000..ac9238d30a --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/Makefile @@ -0,0 +1,6 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2022. + +include ../../Makefile.common +include ../../configurations/nrf52840dk/nrf52840dk.mk diff --git a/boards/tutorials/nrf52840dk-process-control/README.md b/boards/tutorials/nrf52840dk-process-control/README.md new file mode 100644 index 0000000000..b556efe494 --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/README.md @@ -0,0 +1,9 @@ +nRF52840DK Board Definition for the Tock Thread Tutorial +======================================================== + +This is the board definition for the nRF52840DK target used in the +[Thread Network tutorial](https://book.tockos.org/course/thread-net/overview). + +Please follow the instructions in that tutorial. You may also want to look at +the documentation of the base nRF52840DK board definition +[here](../../nordic/nrf52840dk/README.md). diff --git a/boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink b/boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink new file mode 100644 index 0000000000..8094e76819 --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink @@ -0,0 +1,28 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2018. +# +# +# +# J-LINK GDB SERVER initialization +# +# This connects to a GDB Server listening +# for commands on localhost at tcp port 2331 +target remote localhost:2331 +monitor speed 30 +file ../../../../target/thumbv7em-none-eabi/release/nrf52dk +monitor reset +# +# CPU core initialization (to be done by user) +# +# Set the processor mode +# monitor reg cpsr = 0xd3 +# Set auto JTAG speed +monitor speed auto +# Setup GDB FOR FASTER DOWNLOADS +set remote memory-write-packet-size 1024 +set remote memory-write-packet-size fixed +# tui enable +# layout split +# layout service_pending_interrupts +b initialize_ram_jump_to_main diff --git a/boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh b/boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh new file mode 100644 index 0000000000..5edf8b5cb8 --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh @@ -0,0 +1,5 @@ +# Licensed under the Apache License, Version 2.0 or the MIT License. +# SPDX-License-Identifier: Apache-2.0 OR MIT +# Copyright Tock Contributors 2023. + +JLinkGDBServer -device nrf52 -speed 1200 -if swd -AutoConnect 1 -port 2331 diff --git a/boards/tutorials/nrf52840dk-process-control/layout.ld b/boards/tutorials/nrf52840dk-process-control/layout.ld new file mode 100644 index 0000000000..8924ae11fe --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/layout.ld @@ -0,0 +1,6 @@ +/* Licensed under the Apache License, Version 2.0 or the MIT License. */ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* Copyright Tock Contributors 2023. */ + +INCLUDE ../../nordic/nrf52840_chip_layout.ld +INCLUDE tock_kernel_layout.ld diff --git a/boards/tutorials/nrf52840dk-process-control/src/io.rs b/boards/tutorials/nrf52840dk-process-control/src/io.rs new file mode 100644 index 0000000000..8a5fa9035d --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/src/io.rs @@ -0,0 +1,91 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2024. + +use core::fmt::Write; +use kernel::debug::IoWrite; +use kernel::hil::uart; +use kernel::hil::uart::Configure; + +use nrf52840::uart::{Uarte, UARTE0_BASE}; + +enum Writer { + WriterUart(/* initialized */ bool), + WriterRtt(&'static segger::rtt::SeggerRttMemory<'static>), +} + +static mut WRITER: Writer = Writer::WriterUart(false); + +/// Set the RTT memory buffer used to output panic messages. +pub unsafe fn set_rtt_memory(rtt_memory: &'static segger::rtt::SeggerRttMemory<'static>) { + WRITER = Writer::WriterRtt(rtt_memory); +} + +impl Write for Writer { + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { + self.write(s.as_bytes()); + Ok(()) + } +} + +impl IoWrite for Writer { + fn write(&mut self, buf: &[u8]) -> usize { + match self { + Writer::WriterUart(ref mut initialized) => { + // Here, we create a second instance of the Uarte struct. + // This is okay because we only call this during a panic, and + // we will never actually process the interrupts + let uart = Uarte::new(UARTE0_BASE); + if !*initialized { + *initialized = true; + let _ = uart.configure(uart::Parameters { + baud_rate: 115200, + stop_bits: uart::StopBits::One, + parity: uart::Parity::None, + hw_flow_control: false, + width: uart::Width::Eight, + }); + } + for &c in buf { + unsafe { + uart.send_byte(c); + } + while !uart.tx_ready() {} + } + } + Writer::WriterRtt(rtt_memory) => { + rtt_memory.write_sync(buf); + } + } + buf.len() + } +} + +#[cfg(not(test))] +#[no_mangle] +#[panic_handler] +/// Panic handler +pub unsafe fn panic_fmt(pi: &core::panic::PanicInfo) -> ! { + use core::ptr::{addr_of, addr_of_mut}; + use kernel::debug; + use kernel::hil::led; + use nrf52840::gpio::Pin; + + use crate::CHIP; + use crate::PROCESSES; + use crate::PROCESS_PRINTER; + + // The nRF52840DK LEDs (see back of board) + let led_kernel_pin = &nrf52840::gpio::GPIOPin::new(Pin::P0_13); + let led = &mut led::LedLow::new(led_kernel_pin); + let writer = &mut *addr_of_mut!(WRITER); + debug::panic( + &mut [led], + writer, + pi, + &cortexm4::support::nop, + &*addr_of!(PROCESSES), + &*addr_of!(CHIP), + &*addr_of!(PROCESS_PRINTER), + ) +} diff --git a/boards/tutorials/nrf52840dk-process-control/src/main.rs b/boards/tutorials/nrf52840dk-process-control/src/main.rs new file mode 100644 index 0000000000..bf480632d6 --- /dev/null +++ b/boards/tutorials/nrf52840dk-process-control/src/main.rs @@ -0,0 +1,641 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK). + +#![no_std] +// Disable this attribute when documenting, as a workaround for +// https://github.com/rust-lang/rust/issues/62184. +#![cfg_attr(not(doc), no_main)] +#![deny(missing_docs)] + +use core::ptr::{addr_of, addr_of_mut}; + +use kernel::component::Component; +use kernel::hil::led::LedLow; +use kernel::hil::time::Counter; +use kernel::platform::{KernelResources, SyscallDriverLookup}; +use kernel::process::ProcessLoadingAsync; +use kernel::scheduler::round_robin::RoundRobinSched; +use kernel::{capabilities, create_capability, static_init}; +use nrf52840::gpio::Pin; +use nrf52840::interrupt_service::Nrf52840DefaultPeripherals; +use nrf52_components::{UartChannel, UartPins}; + +// The nRF52840DK LEDs (see back of board) +const LED1_PIN: Pin = Pin::P0_13; +const LED2_PIN: Pin = Pin::P0_14; +const LED3_PIN: Pin = Pin::P0_15; +const LED4_PIN: Pin = Pin::P0_16; + +// The nRF52840DK buttons (see back of board) +const BUTTON1_PIN: Pin = Pin::P0_11; +const BUTTON2_PIN: Pin = Pin::P0_12; +const BUTTON3_PIN: Pin = Pin::P0_24; +const BUTTON4_PIN: Pin = Pin::P0_25; +const BUTTON_RST_PIN: Pin = Pin::P0_18; + +const UART_RTS: Option = Some(Pin::P0_05); +const UART_TXD: Pin = Pin::P0_06; +const UART_CTS: Option = Some(Pin::P0_07); +const UART_RXD: Pin = Pin::P0_08; + +/// Debug Writer +pub mod io; + +// State for loading and holding applications. +// How should the kernel respond when a process faults. +const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy = + capsules_system::process_policies::PanicFaultPolicy {}; + +// Number of concurrent processes this platform supports. +const NUM_PROCS: usize = 8; + +static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] = + [None; NUM_PROCS]; + +static mut CHIP: Option<&'static nrf52840::chip::NRF52> = None; +// Static reference to process printer for panic dumps. +static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> = + None; + +/// Dummy buffer that causes the linker to reserve enough space for the stack. +#[no_mangle] +#[link_section = ".stack_buffer"] +pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; + +//------------------------------------------------------------------------------ +// SYSCALL DRIVER TYPE DEFINITIONS +//------------------------------------------------------------------------------ + +type AlarmDriver = components::alarm::AlarmDriverComponentType>; + +type Screen = components::ssd1306::Ssd1306ComponentType>; +type ScreenDriver = components::screen::ScreenSharedComponentType; + +type NonVolatilePages = components::dynamic_binary_storage::NVPages< + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, +>; +type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage< + 'static, + 'static, + nrf52840::chip::NRF52<'a, Nrf52840DefaultPeripherals<'a>>, + kernel::process::ProcessStandardDebugFull, + NonVolatilePages, +>; + +/// Needed for process info capsule. +pub struct PMCapability; +unsafe impl capabilities::ProcessManagementCapability for PMCapability {} +unsafe impl capabilities::ProcessStartCapability for PMCapability {} + +/// Supported drivers by the platform +pub struct Platform { + console: &'static capsules_core::console::Console<'static>, + button: &'static capsules_core::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>, + adc: &'static capsules_core::adc::AdcDedicated<'static, nrf52840::adc::Adc<'static>>, + led: &'static capsules_core::led::LedDriver< + 'static, + kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>, + 4, + >, + alarm: &'static AlarmDriver, + scheduler: &'static RoundRobinSched<'static>, + screen: &'static ScreenDriver, + systick: cortexm4::systick::SysTick, + processes: &'static [Option<&'static dyn kernel::process::Process>], + process_info: &'static capsules_extra::process_info_driver::ProcessInfo, + nonvolatile_storage: + &'static capsules_extra::nonvolatile_storage_driver::NonvolatileStorage<'static>, + dynamic_app_loader: &'static capsules_extra::app_loader::AppLoader< + DynamicBinaryStorage<'static>, + DynamicBinaryStorage<'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_core::console::DRIVER_NUM => f(Some(self.console)), + capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)), + capsules_core::led::DRIVER_NUM => f(Some(self.led)), + capsules_core::button::DRIVER_NUM => f(Some(self.button)), + capsules_core::adc::DRIVER_NUM => f(Some(self.adc)), + capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)), + capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)), + capsules_extra::nonvolatile_storage_driver::DRIVER_NUM => { + f(Some(self.nonvolatile_storage)) + } + capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)), + _ => f(None), + } + } +} + +/// 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. +#[inline(never)] +unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> { + let ieee802154_ack_buf = static_init!( + [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE], + [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE] + ); + // Initialize chip peripheral drivers + let nrf52840_peripherals = static_init!( + Nrf52840DefaultPeripherals, + Nrf52840DefaultPeripherals::new(ieee802154_ack_buf) + ); + + nrf52840_peripherals +} + +impl KernelResources>> + for Platform +{ + type SyscallDriverLookup = Self; + type SyscallFilter = (); + type ProcessFault = (); + type Scheduler = RoundRobinSched<'static>; + type SchedulerTimer = cortexm4::systick::SysTick; + type WatchDog = (); + type ContextSwitchCallback = (); + + fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup { + self + } + fn syscall_filter(&self) -> &Self::SyscallFilter { + &() + } + fn process_fault(&self) -> &Self::ProcessFault { + &() + } + fn scheduler(&self) -> &Self::Scheduler { + self.scheduler + } + fn scheduler_timer(&self) -> &Self::SchedulerTimer { + &self.systick + } + fn watchdog(&self) -> &Self::WatchDog { + &() + } + fn context_switch_callback(&self) -> &Self::ContextSwitchCallback { + &() + } +} + +impl kernel::process::ProcessLoadingAsyncClient for Platform { + fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {} + + fn process_loading_finished(&self) { + kernel::debug!("Processes Loaded at Main:"); + + for (i, proc) in self.processes.iter().enumerate() { + proc.map(|p| { + kernel::debug!("[{}] {}", i, p.get_process_name()); + kernel::debug!(" ShortId: {}", p.short_app_id()); + }); + } + } +} + +/// Main function called after RAM initialized. +#[no_mangle] +pub unsafe fn main() { + //-------------------------------------------------------------------------- + // INITIAL SETUP + //-------------------------------------------------------------------------- + + // Apply errata fixes and enable interrupts. + nrf52840::init(); + + // Set up peripheral drivers. Called in separate function to reduce stack + // usage. + let nrf52840_peripherals = create_peripherals(); + + // Set up circular peripheral dependencies. + nrf52840_peripherals.init(); + let base_peripherals = &nrf52840_peripherals.nrf52; + + let processes = &*addr_of!(PROCESSES); + + // Choose the channel for serial output. This board can be configured to use + // either the Segger RTT channel or via UART with traditional TX/RX GPIO + // pins. + let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)); + + // Setup space to store the core kernel data structure. + let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes)); + + // Create (and save for panic debugging) a chip object to setup low-level + // resources (e.g. MPU, systick). + let chip = static_init!( + nrf52840::chip::NRF52, + nrf52840::chip::NRF52::new(nrf52840_peripherals) + ); + CHIP = Some(chip); + + // Do nRF configuration and setup. This is shared code with other nRF-based + // platforms. + nrf52_components::startup::NrfStartupComponent::new( + false, + BUTTON_RST_PIN, + nrf52840::uicr::Regulator0Output::DEFAULT, + &base_peripherals.nvmc, + ) + .finalize(()); + + //-------------------------------------------------------------------------- + // CAPABILITIES + //-------------------------------------------------------------------------- + + // Create capabilities that the board needs to call certain protected kernel + // functions. + let main_loop_capability = create_capability!(capabilities::MainLoopCapability); + + //-------------------------------------------------------------------------- + // LEDs + //-------------------------------------------------------------------------- + + let led = components::led::LedsComponent::new().finalize(components::led_component_static!( + LedLow<'static, nrf52840::gpio::GPIOPin>, + LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]), + LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]), + LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]), + LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]), + )); + + //-------------------------------------------------------------------------- + // TIMER + //-------------------------------------------------------------------------- + + let rtc = &base_peripherals.rtc; + let _ = rtc.start(); + let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc) + .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc)); + let alarm = components::alarm::AlarmDriverComponent::new( + board_kernel, + capsules_core::alarm::DRIVER_NUM, + mux_alarm, + ) + .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc)); + + //-------------------------------------------------------------------------- + // UART & CONSOLE & DEBUG + //-------------------------------------------------------------------------- + + let uart_channel = nrf52_components::UartChannelComponent::new( + uart_channel, + mux_alarm, + &base_peripherals.uarte0, + ) + .finalize(nrf52_components::uart_channel_component_static!( + nrf52840::rtc::Rtc + )); + + // Virtualize the UART channel for the console and for kernel debug. + let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200) + .finalize(components::uart_mux_component_static!()); + + // Setup the serial console for userspace. + let console = components::console::ConsoleComponent::new( + board_kernel, + capsules_core::console::DRIVER_NUM, + uart_mux, + ) + .finalize(components::console_component_static!()); + + // Tool for displaying information about processes. + let process_printer = components::process_printer::ProcessPrinterTextComponent::new() + .finalize(components::process_printer_text_component_static!()); + PROCESS_PRINTER = Some(process_printer); + + // Create the process console, an interactive terminal for managing + // processes. + let pconsole = components::process_console::ProcessConsoleComponent::new( + board_kernel, + uart_mux, + mux_alarm, + process_printer, + Some(cortexm4::support::reset), + ) + .finalize(components::process_console_component_static!( + nrf52840::rtc::Rtc<'static> + )); + + // Create the debugger object that handles calls to `debug!()`. + components::debug_writer::DebugWriterComponent::new(uart_mux) + .finalize(components::debug_writer_component_static!()); + + //-------------------------------------------------------------------------- + // BUTTONS + //-------------------------------------------------------------------------- + + let button = components::button::ButtonComponent::new( + board_kernel, + capsules_core::button::DRIVER_NUM, + components::button_component_helper!( + nrf52840::gpio::GPIOPin, + ( + &nrf52840_peripherals.gpio_port[BUTTON1_PIN], + kernel::hil::gpio::ActivationMode::ActiveLow, + kernel::hil::gpio::FloatingState::PullUp + ), + ( + &nrf52840_peripherals.gpio_port[BUTTON2_PIN], + kernel::hil::gpio::ActivationMode::ActiveLow, + kernel::hil::gpio::FloatingState::PullUp + ), + ( + &nrf52840_peripherals.gpio_port[BUTTON3_PIN], + kernel::hil::gpio::ActivationMode::ActiveLow, + kernel::hil::gpio::FloatingState::PullUp + ), + ( + &nrf52840_peripherals.gpio_port[BUTTON4_PIN], + kernel::hil::gpio::ActivationMode::ActiveLow, + kernel::hil::gpio::FloatingState::PullUp + ) + ), + ) + .finalize(components::button_component_static!( + nrf52840::gpio::GPIOPin + )); + + //-------------------------------------------------------------------------- + // ADC + //-------------------------------------------------------------------------- + + let adc_channels = static_init!( + [nrf52840::adc::AdcChannelSetup; 6], + [ + nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput1), + nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput2), + nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput4), + nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput5), + nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput6), + nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput7), + ] + ); + let adc = components::adc::AdcDedicatedComponent::new( + &base_peripherals.adc, + adc_channels, + board_kernel, + capsules_core::adc::DRIVER_NUM, + ) + .finalize(components::adc_dedicated_component_static!( + nrf52840::adc::Adc + )); + + //-------------------------------------------------------------------------- + // NRF CLOCK SETUP + //-------------------------------------------------------------------------- + + nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(()); + + //-------------------------------------------------------------------------- + // SCREEN + //-------------------------------------------------------------------------- + + 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(&nrf52840_peripherals.nrf52.twi1, None) + .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI)); + nrf52840_peripherals.nrf52.twi1.configure( + nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32), + nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32), + ); + nrf52840_peripherals + .nrf52 + .twi1 + .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) + .finalize(components::i2c_component_static!(nrf52840::i2c::TWI)); + + // Create the ssd1306 object for the actual screen driver. + #[cfg(feature = "screen_ssd1306")] + let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true) + .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI)); + + #[cfg(feature = "screen_sh1106")] + let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true) + .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI)); + + let apps_regions = kernel::static_init!( + [capsules_extra::screen_shared::AppScreenRegion; 3], + [ + capsules_extra::screen_shared::AppScreenRegion::new( + kernel::process::ShortId::Fixed( + core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( + "process_control".as_bytes() + )) + .unwrap() + ), + 0, // x + 0, // y + 16 * 8, // width + 7 * 8 // height + ), + capsules_extra::screen_shared::AppScreenRegion::new( + kernel::process::ShortId::Fixed( + core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( + "counter".as_bytes() + )) + .unwrap() + ), + 0, // x + 7 * 8, // y + 8 * 8, // width + 1 * 8 // height + ), + capsules_extra::screen_shared::AppScreenRegion::new( + kernel::process::ShortId::Fixed( + core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( + "temperature".as_bytes() + )) + .unwrap() + ), + 8 * 8, // x + 7 * 8, // y + 8 * 8, // width + 1 * 8 // height + ) + ] + ); + + let screen = components::screen::ScreenSharedComponent::new( + board_kernel, + capsules_extra::screen::DRIVER_NUM, + ssd1306_sh1106, + apps_regions, + ) + .finalize(components::screen_shared_component_static!(1032, Screen)); + + ssd1306_sh1106.init_screen(); + + //-------------------------------------------------------------------------- + // PROCESS INFO FOR USERSPACE + //-------------------------------------------------------------------------- + + let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); + let process_info = kernel::static_init!( + capsules_extra::process_info_driver::ProcessInfo, + capsules_extra::process_info_driver::ProcessInfo::new( + board_kernel, + board_kernel.create_grant(capsules_extra::process_info_driver::DRIVER_NUM, &grant_cap), + PMCapability + ) + ); + + CHIP = Some(chip); + + let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc) + .finalize(components::flash_mux_component_static!( + nrf52840::nvmc::Nvmc + )); + + // Create a virtual flash user for dynamic binary storage + let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize( + components::flash_user_component_static!(nrf52840::nvmc::Nvmc), + ); + + // Create a virtual flash user for nonvolatile + let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize( + components::flash_user_component_static!(nrf52840::nvmc::Nvmc), + ); + + //-------------------------------------------------------------------------- + // Credential Checking + //-------------------------------------------------------------------------- + + // Create the credential checker. + let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new() + .finalize(components::app_checker_null_component_static!()); + + // Create the AppID assigner. + let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new() + .finalize(components::appid_assigner_tbf_header_component_static!()); + + // Create the process checking machine. + let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy) + .finalize(components::process_checker_machine_component_static!()); + + //-------------------------------------------------------------------------- + // STORAGE PERMISSIONS + //-------------------------------------------------------------------------- + + let storage_permissions_policy = + components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize( + components::storage_permissions_null_component_static!( + nrf52840::chip::NRF52, + kernel::process::ProcessStandardDebugFull, + ), + ); + + // Create and start the asynchronous process loader. + let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new( + checker, + &mut *addr_of_mut!(PROCESSES), + board_kernel, + chip, + &FAULT_RESPONSE, + assigner, + storage_permissions_policy, + ) + .finalize(components::process_loader_sequential_component_static!( + nrf52840::chip::NRF52, + kernel::process::ProcessStandardDebugFull, + NUM_PROCS + )); + + //-------------------------------------------------------------------------- + // Dynamic App Loading + //-------------------------------------------------------------------------- + + // Create the dynamic binary flasher. + let dynamic_binary_storage = + components::dynamic_binary_storage::SequentialBinaryStorageComponent::new( + virtual_flash_dbs, + loader, + ) + .finalize(components::sequential_binary_storage_component_static!( + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, + nrf52840::chip::NRF52, + kernel::process::ProcessStandardDebugFull, + )); + + // Create the dynamic app loader capsule. + let dynamic_app_loader = components::app_loader::AppLoaderComponent::new( + board_kernel, + capsules_extra::app_loader::DRIVER_NUM, + dynamic_binary_storage, + dynamic_binary_storage, + ) + .finalize(components::app_loader_component_static!( + DynamicBinaryStorage<'static>, + DynamicBinaryStorage<'static>, + )); + + //-------------------------------------------------------------------------- + // NONVOLATILE STORAGE + //-------------------------------------------------------------------------- + + // 32kB of userspace-accessible storage, page aligned: + kernel::storage_volume!(APP_STORAGE, 32); + + let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new( + board_kernel, + capsules_extra::nonvolatile_storage_driver::DRIVER_NUM, + virtual_flash_nvm, + core::ptr::addr_of!(APP_STORAGE) as usize, + APP_STORAGE.len(), + // No kernel-writeable flash: + core::ptr::null::<()>() as usize, + 0, + ) + .finalize(components::nonvolatile_storage_component_static!( + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc> + )); + + //-------------------------------------------------------------------------- + // PLATFORM SETUP, SCHEDULER, AND START KERNEL LOOP + //-------------------------------------------------------------------------- + + let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes) + .finalize(components::round_robin_component_static!(NUM_PROCS)); + + let platform = static_init!( + Platform, + Platform { + console, + button, + adc, + led, + alarm, + scheduler, + screen, + systick: cortexm4::systick::SysTick::new_with_calibration(64000000), + processes, + process_info, + nonvolatile_storage, + dynamic_app_loader, + } + ); + loader.set_client(platform); + + let _ = pconsole.start(); + + board_kernel.kernel_loop( + platform, + chip, + None::<&kernel::ipc::IPC<0>>, + &main_loop_capability, + ); +} From 24bb7126722742f1d5355ec6751a588b5cc78de7 Mon Sep 17 00:00:00 2001 From: viswajith-g Date: Wed, 30 Apr 2025 17:54:59 -0400 Subject: [PATCH 02/14] boards: tutorials: dynamic-apps-and-policies: addressed pr comments --- Cargo.toml | 2 +- .../.cargo/config.toml | 0 .../Cargo.toml | 2 +- .../Makefile | 0 .../README.md | 10 ++ .../layout.ld | 0 .../src/io.rs | 0 .../src/main.rs | 106 +++++++++--------- .../nrf52840dk-process-control/README.md | 9 -- .../jtag/gdbinit_pca10040.jlink | 28 ----- .../jtag/jdbserver_pca10040.sh | 5 - 11 files changed, 65 insertions(+), 97 deletions(-) rename boards/tutorials/{nrf52840dk-process-control => nrf52840dk-dynamic-apps-and-policies}/.cargo/config.toml (100%) rename boards/tutorials/{nrf52840dk-process-control => nrf52840dk-dynamic-apps-and-policies}/Cargo.toml (95%) rename boards/tutorials/{nrf52840dk-process-control => nrf52840dk-dynamic-apps-and-policies}/Makefile (100%) create mode 100644 boards/tutorials/nrf52840dk-dynamic-apps-and-policies/README.md rename boards/tutorials/{nrf52840dk-process-control => nrf52840dk-dynamic-apps-and-policies}/layout.ld (100%) rename boards/tutorials/{nrf52840dk-process-control => nrf52840dk-dynamic-apps-and-policies}/src/io.rs (100%) rename boards/tutorials/{nrf52840dk-process-control => nrf52840dk-dynamic-apps-and-policies}/src/main.rs (96%) delete mode 100644 boards/tutorials/nrf52840dk-process-control/README.md delete mode 100644 boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink delete mode 100644 boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh diff --git a/Cargo.toml b/Cargo.toml index aaa089dc88..7e663f52d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,8 +61,8 @@ members = [ "boards/configurations/nrf52840dk/nrf52840dk-test-kernel", "boards/configurations/nrf52840dk/nrf52840dk-test-dynamic-app-load", "boards/configurations/microbit_v2/microbit_v2-test-dynamic-app-load", + "boards/tutorials/nrf52840dk-dynamic-apps-and-policies", "boards/tutorials/nrf52840dk-hotp-tutorial", - "boards/tutorials/nrf52840dk-process-control", "boards/tutorials/nrf52840dk-thread-tutorial", "capsules/aes_gcm", "capsules/ecdsa_sw", diff --git a/boards/tutorials/nrf52840dk-process-control/.cargo/config.toml b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/.cargo/config.toml similarity index 100% rename from boards/tutorials/nrf52840dk-process-control/.cargo/config.toml rename to boards/tutorials/nrf52840dk-dynamic-apps-and-policies/.cargo/config.toml diff --git a/boards/tutorials/nrf52840dk-process-control/Cargo.toml b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/Cargo.toml similarity index 95% rename from boards/tutorials/nrf52840dk-process-control/Cargo.toml rename to boards/tutorials/nrf52840dk-dynamic-apps-and-policies/Cargo.toml index 45f908084f..ba1a136e13 100644 --- a/boards/tutorials/nrf52840dk-process-control/Cargo.toml +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/Cargo.toml @@ -3,7 +3,7 @@ # Copyright Tock Contributors 2022. [package] -name = "nrf52840dk-process-control" +name = "nrf52840dk-dynamic-apps-and-policies" version.workspace = true authors.workspace = true build = "../../build.rs" diff --git a/boards/tutorials/nrf52840dk-process-control/Makefile b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/Makefile similarity index 100% rename from boards/tutorials/nrf52840dk-process-control/Makefile rename to boards/tutorials/nrf52840dk-dynamic-apps-and-policies/Makefile diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/README.md b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/README.md new file mode 100644 index 0000000000..0644158715 --- /dev/null +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/README.md @@ -0,0 +1,10 @@ +nRF52840DK Board Definition for the Tock Dynamic Apps and Secure Policies Tutorial +================================================================================== + +This is the board definition for the nRF52840DK target used in the +[Dynamic App Loading and Secure Policies] +(https://github.com/tock/book/pull/60/files). + +Please follow the instructions in that tutorial. You may also want to look at +the documentation of the base nRF52840DK board definition +[here](../../nordic/nrf52840dk/README.md). diff --git a/boards/tutorials/nrf52840dk-process-control/layout.ld b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/layout.ld similarity index 100% rename from boards/tutorials/nrf52840dk-process-control/layout.ld rename to boards/tutorials/nrf52840dk-dynamic-apps-and-policies/layout.ld diff --git a/boards/tutorials/nrf52840dk-process-control/src/io.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs similarity index 100% rename from boards/tutorials/nrf52840dk-process-control/src/io.rs rename to boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs diff --git a/boards/tutorials/nrf52840dk-process-control/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs similarity index 96% rename from boards/tutorials/nrf52840dk-process-control/src/main.rs rename to boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index bf480632d6..9cf51913c5 100644 --- a/boards/tutorials/nrf52840dk-process-control/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -74,9 +74,9 @@ type AlarmDriver = components::alarm::AlarmDriverComponentType>; type ScreenDriver = components::screen::ScreenSharedComponentType; -type NonVolatilePages = components::dynamic_binary_storage::NVPages< - capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, ->; +type FlashUserType = + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>; +type NonVolatilePages = components::dynamic_binary_storage::NVPages; type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage< 'static, 'static, @@ -391,6 +391,46 @@ pub unsafe fn main() { nrf52840::adc::Adc )); + //-------------------------------------------------------------------------- + // VIRTUAL FLASH + //-------------------------------------------------------------------------- + + let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc) + .finalize(components::flash_mux_component_static!( + nrf52840::nvmc::Nvmc + )); + + // Create a virtual flash user for dynamic binary storage + let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize( + components::flash_user_component_static!(nrf52840::nvmc::Nvmc), + ); + + // Create a virtual flash user for nonvolatile + let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize( + components::flash_user_component_static!(nrf52840::nvmc::Nvmc), + ); + + //-------------------------------------------------------------------------- + // NONVOLATILE STORAGE + //-------------------------------------------------------------------------- + + // 32kB of userspace-accessible storage, page aligned: + kernel::storage_volume!(APP_STORAGE, 32); + + let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new( + board_kernel, + capsules_extra::nonvolatile_storage_driver::DRIVER_NUM, + virtual_flash_nvm, + core::ptr::addr_of!(APP_STORAGE) as usize, + APP_STORAGE.len(), + // No kernel-writeable flash: + core::ptr::null::<()>() as usize, + 0, + ) + .finalize(components::nonvolatile_storage_component_static!( + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc> + )); + //-------------------------------------------------------------------------- // NRF CLOCK SETUP //-------------------------------------------------------------------------- @@ -484,35 +524,12 @@ pub unsafe fn main() { // PROCESS INFO FOR USERSPACE //-------------------------------------------------------------------------- - let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); - let process_info = kernel::static_init!( - capsules_extra::process_info_driver::ProcessInfo, - capsules_extra::process_info_driver::ProcessInfo::new( - board_kernel, - board_kernel.create_grant(capsules_extra::process_info_driver::DRIVER_NUM, &grant_cap), - PMCapability - ) - ); - - CHIP = Some(chip); - - let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc) - .finalize(components::flash_mux_component_static!( - nrf52840::nvmc::Nvmc - )); - - // Create a virtual flash user for dynamic binary storage - let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize( - components::flash_user_component_static!(nrf52840::nvmc::Nvmc), - ); - - // Create a virtual flash user for nonvolatile - let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize( - components::flash_user_component_static!(nrf52840::nvmc::Nvmc), - ); + // let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); + let process_info = components::process_info_driver::new() + .finalize(components::process_info_component_static!()); //-------------------------------------------------------------------------- - // Credential Checking + // CREDENTIAL CHECKING //-------------------------------------------------------------------------- // Create the credential checker. @@ -539,6 +556,10 @@ pub unsafe fn main() { ), ); + //-------------------------------------------------------------------------- + // ASYNCHRONOUS PROCESS LOADER MACHINE + //-------------------------------------------------------------------------- + // Create and start the asynchronous process loader. let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new( checker, @@ -556,7 +577,7 @@ pub unsafe fn main() { )); //-------------------------------------------------------------------------- - // Dynamic App Loading + // DYNAMIC PROCESS LOADING //-------------------------------------------------------------------------- // Create the dynamic binary flasher. @@ -566,7 +587,7 @@ pub unsafe fn main() { loader, ) .finalize(components::sequential_binary_storage_component_static!( - capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, + FlashUserType, nrf52840::chip::NRF52, kernel::process::ProcessStandardDebugFull, )); @@ -583,27 +604,6 @@ pub unsafe fn main() { DynamicBinaryStorage<'static>, )); - //-------------------------------------------------------------------------- - // NONVOLATILE STORAGE - //-------------------------------------------------------------------------- - - // 32kB of userspace-accessible storage, page aligned: - kernel::storage_volume!(APP_STORAGE, 32); - - let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new( - board_kernel, - capsules_extra::nonvolatile_storage_driver::DRIVER_NUM, - virtual_flash_nvm, - core::ptr::addr_of!(APP_STORAGE) as usize, - APP_STORAGE.len(), - // No kernel-writeable flash: - core::ptr::null::<()>() as usize, - 0, - ) - .finalize(components::nonvolatile_storage_component_static!( - capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc> - )); - //-------------------------------------------------------------------------- // PLATFORM SETUP, SCHEDULER, AND START KERNEL LOOP //-------------------------------------------------------------------------- diff --git a/boards/tutorials/nrf52840dk-process-control/README.md b/boards/tutorials/nrf52840dk-process-control/README.md deleted file mode 100644 index b556efe494..0000000000 --- a/boards/tutorials/nrf52840dk-process-control/README.md +++ /dev/null @@ -1,9 +0,0 @@ -nRF52840DK Board Definition for the Tock Thread Tutorial -======================================================== - -This is the board definition for the nRF52840DK target used in the -[Thread Network tutorial](https://book.tockos.org/course/thread-net/overview). - -Please follow the instructions in that tutorial. You may also want to look at -the documentation of the base nRF52840DK board definition -[here](../../nordic/nrf52840dk/README.md). diff --git a/boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink b/boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink deleted file mode 100644 index 8094e76819..0000000000 --- a/boards/tutorials/nrf52840dk-process-control/jtag/gdbinit_pca10040.jlink +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed under the Apache License, Version 2.0 or the MIT License. -# SPDX-License-Identifier: Apache-2.0 OR MIT -# Copyright Tock Contributors 2018. -# -# -# -# J-LINK GDB SERVER initialization -# -# This connects to a GDB Server listening -# for commands on localhost at tcp port 2331 -target remote localhost:2331 -monitor speed 30 -file ../../../../target/thumbv7em-none-eabi/release/nrf52dk -monitor reset -# -# CPU core initialization (to be done by user) -# -# Set the processor mode -# monitor reg cpsr = 0xd3 -# Set auto JTAG speed -monitor speed auto -# Setup GDB FOR FASTER DOWNLOADS -set remote memory-write-packet-size 1024 -set remote memory-write-packet-size fixed -# tui enable -# layout split -# layout service_pending_interrupts -b initialize_ram_jump_to_main diff --git a/boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh b/boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh deleted file mode 100644 index 5edf8b5cb8..0000000000 --- a/boards/tutorials/nrf52840dk-process-control/jtag/jdbserver_pca10040.sh +++ /dev/null @@ -1,5 +0,0 @@ -# Licensed under the Apache License, Version 2.0 or the MIT License. -# SPDX-License-Identifier: Apache-2.0 OR MIT -# Copyright Tock Contributors 2023. - -JLinkGDBServer -device nrf52 -speed 1200 -if swd -AutoConnect 1 -port 2331 From 8df34372be0b7c14f00efd69e07d98582088aa0b Mon Sep 17 00:00:00 2001 From: viswajith-g Date: Thu, 1 May 2025 11:09:50 -0400 Subject: [PATCH 03/14] boards: tutorial: dynamic-apps-and-policies: change nvm to isolated nvm and make types for some capsules --- .../src/main.rs | 59 +++++++++++-------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 9cf51913c5..e7699399aa 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -1,6 +1,6 @@ // Licensed under the Apache License, Version 2.0 or the MIT License. // SPDX-License-Identifier: Apache-2.0 OR MIT -// Copyright Tock Contributors 2022. +// Copyright Tock Contributors 2025. //! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK). @@ -61,7 +61,6 @@ static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::Pr None; /// Dummy buffer that causes the linker to reserve enough space for the stack. -#[no_mangle] #[link_section = ".stack_buffer"] pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; @@ -69,14 +68,29 @@ pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; // SYSCALL DRIVER TYPE DEFINITIONS //------------------------------------------------------------------------------ +/// Needed for process info capsule. +pub struct PMCapability; +unsafe impl capabilities::ProcessManagementCapability for PMCapability {} +unsafe impl capabilities::ProcessStartCapability for PMCapability {} + type AlarmDriver = components::alarm::AlarmDriverComponentType>; type Screen = components::ssd1306::Ssd1306ComponentType>; type ScreenDriver = components::screen::ScreenSharedComponentType; -type FlashUserType = +type ProcessInfoDriver = capsules_extra::process_info_driver::ProcessInfo; + +type IsolatedNonvolatileStorageDriver = + capsules_extra::isolated_nonvolatile_storage_driver::IsolatedNonvolatileStorage< + 'static, + { + components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT + }, + >; + +type FlashUser = capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>; -type NonVolatilePages = components::dynamic_binary_storage::NVPages; +type NonVolatilePages = components::dynamic_binary_storage::NVPages; type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage< 'static, 'static, @@ -84,11 +98,10 @@ type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynami kernel::process::ProcessStandardDebugFull, NonVolatilePages, >; - -/// Needed for process info capsule. -pub struct PMCapability; -unsafe impl capabilities::ProcessManagementCapability for PMCapability {} -unsafe impl capabilities::ProcessStartCapability for PMCapability {} +type AppLoaderDriver = capsules_extra::app_loader::AppLoader< + DynamicBinaryStorage<'static>, + DynamicBinaryStorage<'static>, +>; /// Supported drivers by the platform pub struct Platform { @@ -105,13 +118,9 @@ pub struct Platform { screen: &'static ScreenDriver, systick: cortexm4::systick::SysTick, processes: &'static [Option<&'static dyn kernel::process::Process>], - process_info: &'static capsules_extra::process_info_driver::ProcessInfo, - nonvolatile_storage: - &'static capsules_extra::nonvolatile_storage_driver::NonvolatileStorage<'static>, - dynamic_app_loader: &'static capsules_extra::app_loader::AppLoader< - DynamicBinaryStorage<'static>, - DynamicBinaryStorage<'static>, - >, + process_info: &'static ProcessInfoDriver, + nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver, + dynamic_app_loader: &'static AppLoaderDriver, } impl SyscallDriverLookup for Platform { @@ -127,7 +136,7 @@ impl SyscallDriverLookup for Platform { capsules_core::adc::DRIVER_NUM => f(Some(self.adc)), capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)), capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)), - capsules_extra::nonvolatile_storage_driver::DRIVER_NUM => { + capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => { f(Some(self.nonvolatile_storage)) } capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)), @@ -417,18 +426,16 @@ pub unsafe fn main() { // 32kB of userspace-accessible storage, page aligned: kernel::storage_volume!(APP_STORAGE, 32); - let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new( + let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new( board_kernel, - capsules_extra::nonvolatile_storage_driver::DRIVER_NUM, + capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM, virtual_flash_nvm, core::ptr::addr_of!(APP_STORAGE) as usize, - APP_STORAGE.len(), - // No kernel-writeable flash: - core::ptr::null::<()>() as usize, - 0, + APP_STORAGE.len() ) - .finalize(components::nonvolatile_storage_component_static!( - capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc> + .finalize(components::isolated_nonvolatile_storage_component_static!( + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, + { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT } )); //-------------------------------------------------------------------------- @@ -587,7 +594,7 @@ pub unsafe fn main() { loader, ) .finalize(components::sequential_binary_storage_component_static!( - FlashUserType, + FlashUser, nrf52840::chip::NRF52, kernel::process::ProcessStandardDebugFull, )); From 9d93ee26046908b627abf120503ca234635a3a30 Mon Sep 17 00:00:00 2001 From: viswajith-g Date: Thu, 1 May 2025 11:26:10 -0400 Subject: [PATCH 04/14] revert no_mangle removal from main.rs and remove in io.rs --- boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs | 1 - .../tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs index 8a5fa9035d..73520b05c7 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/io.rs @@ -62,7 +62,6 @@ impl IoWrite for Writer { } #[cfg(not(test))] -#[no_mangle] #[panic_handler] /// Panic handler pub unsafe fn panic_fmt(pi: &core::panic::PanicInfo) -> ! { diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index e7699399aa..4188fa8ebb 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -61,6 +61,7 @@ static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::Pr None; /// Dummy buffer that causes the linker to reserve enough space for the stack. +#[no_mangle] #[link_section = ".stack_buffer"] pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; From 7f869b26705cae0e5682df3fda1bf67090596b95 Mon Sep 17 00:00:00 2001 From: viswajith-g Date: Fri, 16 May 2025 18:12:22 -0400 Subject: [PATCH 05/14] boards: tutorial: dynamic-apps: working board --- .../src/main.rs | 395 +++++------------- 1 file changed, 94 insertions(+), 301 deletions(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 4188fa8ebb..2ef3b6fc25 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -1,27 +1,23 @@ // Licensed under the Apache License, Version 2.0 or the MIT License. // SPDX-License-Identifier: Apache-2.0 OR MIT -// Copyright Tock Contributors 2025. +// Copyright Tock Contributors 2022. //! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK). #![no_std] -// Disable this attribute when documenting, as a workaround for -// https://github.com/rust-lang/rust/issues/62184. -#![cfg_attr(not(doc), no_main)] +#![no_main] #![deny(missing_docs)] use core::ptr::{addr_of, addr_of_mut}; use kernel::component::Component; use kernel::hil::led::LedLow; -use kernel::hil::time::Counter; use kernel::platform::{KernelResources, SyscallDriverLookup}; use kernel::process::ProcessLoadingAsync; -use kernel::scheduler::round_robin::RoundRobinSched; use kernel::{capabilities, create_capability, static_init}; use nrf52840::gpio::Pin; use nrf52840::interrupt_service::Nrf52840DefaultPeripherals; -use nrf52_components::{UartChannel, UartPins}; +use nrf52840dk_lib::{self, PROCESSES}; // The nRF52840DK LEDs (see back of board) const LED1_PIN: Pin = Pin::P0_13; @@ -29,42 +25,20 @@ const LED2_PIN: Pin = Pin::P0_14; const LED3_PIN: Pin = Pin::P0_15; const LED4_PIN: Pin = Pin::P0_16; -// The nRF52840DK buttons (see back of board) -const BUTTON1_PIN: Pin = Pin::P0_11; -const BUTTON2_PIN: Pin = Pin::P0_12; -const BUTTON3_PIN: Pin = Pin::P0_24; -const BUTTON4_PIN: Pin = Pin::P0_25; -const BUTTON_RST_PIN: Pin = Pin::P0_18; +// GPIO used for the screen shield +const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10; +const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11; -const UART_RTS: Option = Some(Pin::P0_05); -const UART_TXD: Pin = Pin::P0_06; -const UART_CTS: Option = Some(Pin::P0_07); -const UART_RXD: Pin = Pin::P0_08; +// Number of concurrent processes this platform supports. +const NUM_PROCS: usize = 8; -/// Debug Writer -pub mod io; +static mut CHIP: Option<&'static nrf52840::chip::NRF52> = None; // State for loading and holding applications. // How should the kernel respond when a process faults. const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy = capsules_system::process_policies::PanicFaultPolicy {}; -// Number of concurrent processes this platform supports. -const NUM_PROCS: usize = 8; - -static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] = - [None; NUM_PROCS]; - -static mut CHIP: Option<&'static nrf52840::chip::NRF52> = None; -// Static reference to process printer for panic dumps. -static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> = - None; - -/// Dummy buffer that causes the linker to reserve enough space for the stack. -#[no_mangle] -#[link_section = ".stack_buffer"] -pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; - //------------------------------------------------------------------------------ // SYSCALL DRIVER TYPE DEFINITIONS //------------------------------------------------------------------------------ @@ -74,8 +48,6 @@ pub struct PMCapability; unsafe impl capabilities::ProcessManagementCapability for PMCapability {} unsafe impl capabilities::ProcessStartCapability for PMCapability {} -type AlarmDriver = components::alarm::AlarmDriverComponentType>; - type Screen = components::ssd1306::Ssd1306ComponentType>; type ScreenDriver = components::screen::ScreenSharedComponentType; @@ -92,6 +64,7 @@ type IsolatedNonvolatileStorageDriver = type FlashUser = capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>; type NonVolatilePages = components::dynamic_binary_storage::NVPages; + type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage< 'static, 'static, @@ -104,20 +77,19 @@ type AppLoaderDriver = capsules_extra::app_loader::AppLoader< DynamicBinaryStorage<'static>, >; -/// Supported drivers by the platform -pub struct Platform { - console: &'static capsules_core::console::Console<'static>, - button: &'static capsules_core::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>, +//------------------------------------------------------------------------------ +// PLATFORM +//------------------------------------------------------------------------------ + +struct Platform { + base: nrf52840dk_lib::Platform, + screen: &'static ScreenDriver, adc: &'static capsules_core::adc::AdcDedicated<'static, nrf52840::adc::Adc<'static>>, led: &'static capsules_core::led::LedDriver< 'static, kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>, 4, >, - alarm: &'static AlarmDriver, - scheduler: &'static RoundRobinSched<'static>, - screen: &'static ScreenDriver, - systick: cortexm4::systick::SysTick, processes: &'static [Option<&'static dyn kernel::process::Process>], process_info: &'static ProcessInfoDriver, nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver, @@ -130,71 +102,51 @@ impl SyscallDriverLookup for Platform { F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R, { match driver_num { - capsules_core::console::DRIVER_NUM => f(Some(self.console)), - capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)), + capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)), capsules_core::led::DRIVER_NUM => f(Some(self.led)), - capsules_core::button::DRIVER_NUM => f(Some(self.button)), capsules_core::adc::DRIVER_NUM => f(Some(self.adc)), - capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)), capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)), capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => { f(Some(self.nonvolatile_storage)) } capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)), - _ => f(None), + _ => self.base.with_driver(driver_num, f), } } } -/// 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. -#[inline(never)] -unsafe fn create_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> { - let ieee802154_ack_buf = static_init!( - [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE], - [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE] - ); - // Initialize chip peripheral drivers - let nrf52840_peripherals = static_init!( - Nrf52840DefaultPeripherals, - Nrf52840DefaultPeripherals::new(ieee802154_ack_buf) - ); - - nrf52840_peripherals -} +type Chip = nrf52840dk_lib::Chip; -impl KernelResources>> - for Platform -{ +impl KernelResources for Platform { type SyscallDriverLookup = Self; - type SyscallFilter = (); - type ProcessFault = (); - type Scheduler = RoundRobinSched<'static>; - type SchedulerTimer = cortexm4::systick::SysTick; - type WatchDog = (); - type ContextSwitchCallback = (); + 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.scheduler + self.base.scheduler() } fn scheduler_timer(&self) -> &Self::SchedulerTimer { - &self.systick + self.base.scheduler_timer() } fn watchdog(&self) -> &Self::WatchDog { - &() + self.base.watchdog() } fn context_switch_callback(&self) -> &Self::ContextSwitchCallback { - &() + self.base.context_switch_callback() } } @@ -216,57 +168,16 @@ impl kernel::process::ProcessLoadingAsyncClient for Platform { /// Main function called after RAM initialized. #[no_mangle] pub unsafe fn main() { - //-------------------------------------------------------------------------- - // INITIAL SETUP - //-------------------------------------------------------------------------- - - // Apply errata fixes and enable interrupts. - nrf52840::init(); - - // Set up peripheral drivers. Called in separate function to reduce stack - // usage. - let nrf52840_peripherals = create_peripherals(); - - // Set up circular peripheral dependencies. - nrf52840_peripherals.init(); - let base_peripherals = &nrf52840_peripherals.nrf52; + let main_loop_capability = create_capability!(capabilities::MainLoopCapability); let processes = &*addr_of!(PROCESSES); - // Choose the channel for serial output. This board can be configured to use - // either the Segger RTT channel or via UART with traditional TX/RX GPIO - // pins. - let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)); - - // Setup space to store the core kernel data structure. - let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes)); + // Create the base board: + let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) = + nrf52840dk_lib::start(); - // Create (and save for panic debugging) a chip object to setup low-level - // resources (e.g. MPU, systick). - let chip = static_init!( - nrf52840::chip::NRF52, - nrf52840::chip::NRF52::new(nrf52840_peripherals) - ); CHIP = Some(chip); - // Do nRF configuration and setup. This is shared code with other nRF-based - // platforms. - nrf52_components::startup::NrfStartupComponent::new( - false, - BUTTON_RST_PIN, - nrf52840::uicr::Regulator0Output::DEFAULT, - &base_peripherals.nvmc, - ) - .finalize(()); - - //-------------------------------------------------------------------------- - // CAPABILITIES - //-------------------------------------------------------------------------- - - // Create capabilities that the board needs to call certain protected kernel - // functions. - let main_loop_capability = create_capability!(capabilities::MainLoopCapability); - //-------------------------------------------------------------------------- // LEDs //-------------------------------------------------------------------------- @@ -279,103 +190,6 @@ pub unsafe fn main() { LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]), )); - //-------------------------------------------------------------------------- - // TIMER - //-------------------------------------------------------------------------- - - let rtc = &base_peripherals.rtc; - let _ = rtc.start(); - let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc) - .finalize(components::alarm_mux_component_static!(nrf52840::rtc::Rtc)); - let alarm = components::alarm::AlarmDriverComponent::new( - board_kernel, - capsules_core::alarm::DRIVER_NUM, - mux_alarm, - ) - .finalize(components::alarm_component_static!(nrf52840::rtc::Rtc)); - - //-------------------------------------------------------------------------- - // UART & CONSOLE & DEBUG - //-------------------------------------------------------------------------- - - let uart_channel = nrf52_components::UartChannelComponent::new( - uart_channel, - mux_alarm, - &base_peripherals.uarte0, - ) - .finalize(nrf52_components::uart_channel_component_static!( - nrf52840::rtc::Rtc - )); - - // Virtualize the UART channel for the console and for kernel debug. - let uart_mux = components::console::UartMuxComponent::new(uart_channel, 115200) - .finalize(components::uart_mux_component_static!()); - - // Setup the serial console for userspace. - let console = components::console::ConsoleComponent::new( - board_kernel, - capsules_core::console::DRIVER_NUM, - uart_mux, - ) - .finalize(components::console_component_static!()); - - // Tool for displaying information about processes. - let process_printer = components::process_printer::ProcessPrinterTextComponent::new() - .finalize(components::process_printer_text_component_static!()); - PROCESS_PRINTER = Some(process_printer); - - // Create the process console, an interactive terminal for managing - // processes. - let pconsole = components::process_console::ProcessConsoleComponent::new( - board_kernel, - uart_mux, - mux_alarm, - process_printer, - Some(cortexm4::support::reset), - ) - .finalize(components::process_console_component_static!( - nrf52840::rtc::Rtc<'static> - )); - - // Create the debugger object that handles calls to `debug!()`. - components::debug_writer::DebugWriterComponent::new(uart_mux) - .finalize(components::debug_writer_component_static!()); - - //-------------------------------------------------------------------------- - // BUTTONS - //-------------------------------------------------------------------------- - - let button = components::button::ButtonComponent::new( - board_kernel, - capsules_core::button::DRIVER_NUM, - components::button_component_helper!( - nrf52840::gpio::GPIOPin, - ( - &nrf52840_peripherals.gpio_port[BUTTON1_PIN], - kernel::hil::gpio::ActivationMode::ActiveLow, - kernel::hil::gpio::FloatingState::PullUp - ), - ( - &nrf52840_peripherals.gpio_port[BUTTON2_PIN], - kernel::hil::gpio::ActivationMode::ActiveLow, - kernel::hil::gpio::FloatingState::PullUp - ), - ( - &nrf52840_peripherals.gpio_port[BUTTON3_PIN], - kernel::hil::gpio::ActivationMode::ActiveLow, - kernel::hil::gpio::FloatingState::PullUp - ), - ( - &nrf52840_peripherals.gpio_port[BUTTON4_PIN], - kernel::hil::gpio::ActivationMode::ActiveLow, - kernel::hil::gpio::FloatingState::PullUp - ) - ), - ) - .finalize(components::button_component_static!( - nrf52840::gpio::GPIOPin - )); - //-------------------------------------------------------------------------- // ADC //-------------------------------------------------------------------------- @@ -392,7 +206,7 @@ pub unsafe fn main() { ] ); let adc = components::adc::AdcDedicatedComponent::new( - &base_peripherals.adc, + &nrf52840_peripherals.nrf52.adc, adc_channels, board_kernel, capsules_core::adc::DRIVER_NUM, @@ -401,57 +215,10 @@ pub unsafe fn main() { nrf52840::adc::Adc )); - //-------------------------------------------------------------------------- - // VIRTUAL FLASH - //-------------------------------------------------------------------------- - - let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc) - .finalize(components::flash_mux_component_static!( - nrf52840::nvmc::Nvmc - )); - - // Create a virtual flash user for dynamic binary storage - let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize( - components::flash_user_component_static!(nrf52840::nvmc::Nvmc), - ); - - // Create a virtual flash user for nonvolatile - let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize( - components::flash_user_component_static!(nrf52840::nvmc::Nvmc), - ); - - //-------------------------------------------------------------------------- - // NONVOLATILE STORAGE - //-------------------------------------------------------------------------- - - // 32kB of userspace-accessible storage, page aligned: - kernel::storage_volume!(APP_STORAGE, 32); - - let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new( - board_kernel, - capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM, - virtual_flash_nvm, - core::ptr::addr_of!(APP_STORAGE) as usize, - APP_STORAGE.len() - ) - .finalize(components::isolated_nonvolatile_storage_component_static!( - capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, - { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT } - )); - - //-------------------------------------------------------------------------- - // NRF CLOCK SETUP - //-------------------------------------------------------------------------- - - nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(()); - //-------------------------------------------------------------------------- // SCREEN //-------------------------------------------------------------------------- - 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(&nrf52840_peripherals.nrf52.twi1, None) .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI)); nrf52840_peripherals.nrf52.twi1.configure( @@ -482,7 +249,7 @@ pub unsafe fn main() { capsules_extra::screen_shared::AppScreenRegion::new( kernel::process::ShortId::Fixed( core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( - "process_control".as_bytes() + b"process_control" )) .unwrap() ), @@ -493,10 +260,8 @@ pub unsafe fn main() { ), capsules_extra::screen_shared::AppScreenRegion::new( kernel::process::ShortId::Fixed( - core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( - "counter".as_bytes() - )) - .unwrap() + core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix(b"counter")) + .unwrap() ), 0, // x 7 * 8, // y @@ -506,7 +271,7 @@ pub unsafe fn main() { capsules_extra::screen_shared::AppScreenRegion::new( kernel::process::ShortId::Fixed( core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( - "temperature".as_bytes() + b"temperature" )) .unwrap() ), @@ -528,16 +293,57 @@ pub unsafe fn main() { ssd1306_sh1106.init_screen(); + //-------------------------------------------------------------------------- + // VIRTUAL FLASH + //-------------------------------------------------------------------------- + + let mux_flash = components::flash::FlashMuxComponent::new(&nrf52840_peripherals.nrf52.nvmc) + .finalize(components::flash_mux_component_static!( + nrf52840::nvmc::Nvmc + )); + + // Create a virtual flash user for dynamic binary storage + let virtual_flash_dbs = components::flash::FlashUserComponent::new(mux_flash).finalize( + components::flash_user_component_static!(nrf52840::nvmc::Nvmc), + ); + + // Create a virtual flash user for nonvolatile + let virtual_flash_nvm = components::flash::FlashUserComponent::new(mux_flash).finalize( + components::flash_user_component_static!(nrf52840::nvmc::Nvmc), + ); + + //-------------------------------------------------------------------------- + // NONVOLATILE STORAGE + //-------------------------------------------------------------------------- + + // 32kB of userspace-accessible storage, page aligned: + kernel::storage_volume!(APP_STORAGE, 32); + + let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new( + board_kernel, + capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM, + virtual_flash_nvm, + core::ptr::addr_of!(APP_STORAGE) as usize, + APP_STORAGE.len() + ) + .finalize(components::isolated_nonvolatile_storage_component_static!( + capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, + { components::isolated_nonvolatile_storage::ISOLATED_NONVOLATILE_STORAGE_APP_REGION_SIZE_DEFAULT } + )); + //-------------------------------------------------------------------------- // PROCESS INFO FOR USERSPACE //-------------------------------------------------------------------------- - // let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); - let process_info = components::process_info_driver::new() - .finalize(components::process_info_component_static!()); + let process_info = components::process_info_driver::ProcessInfoComponent::new( + board_kernel, + capsules_extra::process_info_driver::DRIVER_NUM, + PMCapability, + ) + .finalize(components::process_info_component_static!(PMCapability)); //-------------------------------------------------------------------------- - // CREDENTIAL CHECKING + // Credential Checking //-------------------------------------------------------------------------- // Create the credential checker. @@ -545,8 +351,8 @@ pub unsafe fn main() { .finalize(components::app_checker_null_component_static!()); // Create the AppID assigner. - let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new() - .finalize(components::appid_assigner_tbf_header_component_static!()); + let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new() + .finalize(components::appid_assigner_names_component_static!()); // Create the process checking machine. let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy) @@ -564,10 +370,6 @@ pub unsafe fn main() { ), ); - //-------------------------------------------------------------------------- - // ASYNCHRONOUS PROCESS LOADER MACHINE - //-------------------------------------------------------------------------- - // Create and start the asynchronous process loader. let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new( checker, @@ -585,7 +387,7 @@ pub unsafe fn main() { )); //-------------------------------------------------------------------------- - // DYNAMIC PROCESS LOADING + // Dynamic App Loading //-------------------------------------------------------------------------- // Create the dynamic binary flasher. @@ -616,20 +418,13 @@ pub unsafe fn main() { // PLATFORM SETUP, SCHEDULER, AND START KERNEL LOOP //-------------------------------------------------------------------------- - let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes) - .finalize(components::round_robin_component_static!(NUM_PROCS)); - let platform = static_init!( Platform, Platform { - console, - button, + base: base_platform, + screen, adc, led, - alarm, - scheduler, - screen, - systick: cortexm4::systick::SysTick::new_with_calibration(64000000), processes, process_info, nonvolatile_storage, @@ -638,12 +433,10 @@ pub unsafe fn main() { ); loader.set_client(platform); - let _ = pconsole.start(); - board_kernel.kernel_loop( platform, chip, - None::<&kernel::ipc::IPC<0>>, + Some(&platform.base.ipc), &main_loop_capability, ); } From 9506151b14dca361be33dac638bd4891e38c3580 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 12:45:09 -0400 Subject: [PATCH 06/14] boards: tut: dyn process: fix SeqProcLoad --- .../src/main.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 2ef3b6fc25..6c3f72e028 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -370,6 +370,27 @@ pub unsafe fn main() { ), ); + // These symbols are defined in the standard Tock linker script. + extern "C" { + /// Beginning of the ROM region containing app images. + static _sapps: u8; + /// End of the ROM region containing app images. + static _eapps: u8; + /// Beginning of the RAM region for app memory. + static mut _sappmem: u8; + /// End of the RAM region for app memory. + static _eappmem: u8; + } + + let app_flash = core::slice::from_raw_parts( + core::ptr::addr_of!(_sapps), + core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize, + ); + let app_memory = core::slice::from_raw_parts_mut( + core::ptr::addr_of_mut!(_sappmem), + core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize, + ); + // Create and start the asynchronous process loader. let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new( checker, @@ -379,6 +400,8 @@ pub unsafe fn main() { &FAULT_RESPONSE, assigner, storage_permissions_policy, + app_flash, + app_memory, ) .finalize(components::process_loader_sequential_component_static!( nrf52840::chip::NRF52, From d590be70f71705002b977ed87c56bff6585f58b4 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 12:45:23 -0400 Subject: [PATCH 07/14] components: process info: fix capability --- boards/components/src/process_info_driver.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/components/src/process_info_driver.rs b/boards/components/src/process_info_driver.rs index b510b4c7cd..505f73d396 100644 --- a/boards/components/src/process_info_driver.rs +++ b/boards/components/src/process_info_driver.rs @@ -13,10 +13,10 @@ use kernel::create_capability; #[macro_export] macro_rules! process_info_component_static { - () => {{ + ($C:ty $(,)?) => {{ let process_info = kernel::static_buf!( capsules_extra::process_info_driver::ProcessInfo< - components::process_info_driver::Capability, + $C, > ); @@ -43,13 +43,13 @@ impl ProcessInfoCompone impl Component for ProcessInfoComponent { - type StaticInput = (&'static mut MaybeUninit>,); + type StaticInput = &'static mut MaybeUninit>; type Output = &'static process_info_driver::ProcessInfo; fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output { let grant_cap = create_capability!(capabilities::MemoryAllocationCapability); - let process_info = static_buffer.0.write(ProcessInfo::new( + let process_info = static_buffer.write(ProcessInfo::new( self.board_kernel, self.board_kernel.create_grant(self.driver_num, &grant_cap), self.capability, From 895f076e9a2bb3c4e7738178eab2703971d32a8b Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 21 Apr 2025 23:13:53 -0400 Subject: [PATCH 08/14] tutorial: dpl: add appid assigner Uses the name and the verifying key index. --- .../src/app_id_assigner_name_metadata.rs | 73 +++++++++++++++++++ .../src/main.rs | 41 ++++++----- 2 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/app_id_assigner_name_metadata.rs diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/app_id_assigner_name_metadata.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/app_id_assigner_name_metadata.rs new file mode 100644 index 0000000000..ac965d1001 --- /dev/null +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/app_id_assigner_name_metadata.rs @@ -0,0 +1,73 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2025. + +//! AppID assigner based on name and credential check metadata. +//! +//! This assigns a short ID where the most significant four bits are from the +//! credential checking metadata and the remaining bits are a CRC of the name. +//! +//! ```text +//! 32 28 0 bits +//! +----------+------------------------+ +//! | metadata | CRC(name) | +//! +----------+------------------------+ +//! ``` +//! +//! The intention is that the CRC makes the short ID generally unique, and the +//! 4-bit metadata indicates the key that was used to verify the app's signing +//! credential. + +use kernel::process::{Process, ProcessBinary, ShortId}; +use kernel::process_checker::Compress; + +pub struct AppIdAssignerNameMetadata {} + +impl AppIdAssignerNameMetadata { + pub fn new() -> Self { + Self {} + } +} + +impl kernel::process_checker::Compress for AppIdAssignerNameMetadata { + fn to_short_id(&self, process: &ProcessBinary) -> ShortId { + // Get the stored metadata returned when this process had its credential + // checked. + let metadata = process.credential.get().map_or(0xF, |accepted_credential| { + accepted_credential + .metadata + .map_or(0xF, |metadata| metadata.metadata) as u32 + }); + + let name = process.header.get_package_name().unwrap_or(""); + let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes()); + + // Combine the metadata and CRC into the short id. + let sid = ((metadata & 0xF) << 28) | (sum & 0xFFFFFFF); + + core::num::NonZeroU32::new(sid).into() + } +} + +// We just use the generic version which compares Short IDs. +impl kernel::process_checker::AppUniqueness for AppIdAssignerNameMetadata { + fn different_identifier(&self, process_a: &ProcessBinary, process_b: &ProcessBinary) -> bool { + self.to_short_id(process_a) != self.to_short_id(process_b) + } + + fn different_identifier_process( + &self, + process_a: &ProcessBinary, + process_b: &dyn Process, + ) -> bool { + self.to_short_id(process_a) != process_b.short_app_id() + } + + fn different_identifier_processes( + &self, + process_a: &dyn Process, + process_b: &dyn Process, + ) -> bool { + process_a.short_app_id() != process_b.short_app_id() + } +} diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 6c3f72e028..5e67d6a8fa 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -14,11 +14,14 @@ use kernel::component::Component; use kernel::hil::led::LedLow; use kernel::platform::{KernelResources, SyscallDriverLookup}; use kernel::process::ProcessLoadingAsync; +use kernel::process::ShortId; use kernel::{capabilities, create_capability, static_init}; use nrf52840::gpio::Pin; use nrf52840::interrupt_service::Nrf52840DefaultPeripherals; use nrf52840dk_lib::{self, PROCESSES}; +mod app_id_assigner_name_metadata; + // The nRF52840DK LEDs (see back of board) const LED1_PIN: Pin = Pin::P0_13; const LED2_PIN: Pin = Pin::P0_14; @@ -77,6 +80,19 @@ type AppLoaderDriver = capsules_extra::app_loader::AppLoader< DynamicBinaryStorage<'static>, >; +//------------------------------------------------------------------------------ +// SHORTID HELPER FUNCTION +//------------------------------------------------------------------------------ + +fn create_short_id_from_name(name: &str, metadata: u8) -> ShortId { + let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes()); + + // Combine the metadata and CRC into the short id. + let sid = ((metadata as u32) << 28) | (sum & 0xFFFFFFF); + + core::num::NonZeroU32::new(sid).into() +} + //------------------------------------------------------------------------------ // PLATFORM //------------------------------------------------------------------------------ @@ -247,34 +263,21 @@ pub unsafe fn main() { [capsules_extra::screen_shared::AppScreenRegion; 3], [ capsules_extra::screen_shared::AppScreenRegion::new( - kernel::process::ShortId::Fixed( - core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( - b"process_control" - )) - .unwrap() - ), + create_short_id_from_name("process_manager", 0x0), 0, // x 0, // y 16 * 8, // width 7 * 8 // height ), capsules_extra::screen_shared::AppScreenRegion::new( - kernel::process::ShortId::Fixed( - core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix(b"counter")) - .unwrap() - ), + create_short_id_from_name("counter", 0x0), 0, // x 7 * 8, // y 8 * 8, // width 1 * 8 // height ), capsules_extra::screen_shared::AppScreenRegion::new( - kernel::process::ShortId::Fixed( - core::num::NonZeroU32::new(kernel::utilities::helpers::crc32_posix( - b"temperature" - )) - .unwrap() - ), + create_short_id_from_name("temperature", 0x0), 8 * 8, // x 7 * 8, // y 8 * 8, // width @@ -351,8 +354,10 @@ pub unsafe fn main() { .finalize(components::app_checker_null_component_static!()); // Create the AppID assigner. - let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new() - .finalize(components::appid_assigner_names_component_static!()); + let assigner = static_init!( + app_id_assigner_name_metadata::AppIdAssignerNameMetadata, + app_id_assigner_name_metadata::AppIdAssignerNameMetadata::new() + ); // Create the process checking machine. let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy) From 00f3fafa12196ed585a783af84a65eae06ffed02 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 13:11:56 -0400 Subject: [PATCH 09/14] boards: tut: dyn proc: fix screen feature --- .../tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 5e67d6a8fa..d82321d982 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -51,7 +51,10 @@ pub struct PMCapability; unsafe impl capabilities::ProcessManagementCapability for PMCapability {} unsafe impl capabilities::ProcessStartCapability for PMCapability {} +#[cfg(feature = "screen_ssd1306")] type Screen = components::ssd1306::Ssd1306ComponentType>; +#[cfg(feature = "screen_sh1106")] +type Screen = components::sh1106::Sh1106ComponentType>; type ScreenDriver = components::screen::ScreenSharedComponentType; type ProcessInfoDriver = capsules_extra::process_info_driver::ProcessInfo; From a2213413da415b0aa5e63eb0d08d3a309606ac8e Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 13:12:12 -0400 Subject: [PATCH 10/14] boards: tut: dyn proc: expect unsigned apps --- .../nrf52840dk-dynamic-apps-and-policies/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index d82321d982..80aa1ce0fe 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -266,21 +266,21 @@ pub unsafe fn main() { [capsules_extra::screen_shared::AppScreenRegion; 3], [ capsules_extra::screen_shared::AppScreenRegion::new( - create_short_id_from_name("process_manager", 0x0), + create_short_id_from_name("process_manager", 0xf), 0, // x 0, // y 16 * 8, // width 7 * 8 // height ), capsules_extra::screen_shared::AppScreenRegion::new( - create_short_id_from_name("counter", 0x0), + create_short_id_from_name("counter", 0xf), 0, // x 7 * 8, // y 8 * 8, // width 1 * 8 // height ), capsules_extra::screen_shared::AppScreenRegion::new( - create_short_id_from_name("temperature", 0x0), + create_short_id_from_name("temperature", 0xf), 8 * 8, // x 7 * 8, // y 8 * 8, // width From 9f17748ab062ee482943bd7ac3d5a463b26eae26 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 13:23:43 -0400 Subject: [PATCH 11/14] boards: tut: dyn proc: improve main Try to make it clear --- .../src/main.rs | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 80aa1ce0fe..acaa4cb774 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -35,7 +35,8 @@ const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11; // Number of concurrent processes this platform supports. const NUM_PROCS: usize = 8; -static mut CHIP: Option<&'static nrf52840::chip::NRF52> = None; +type Chip = nrf52840dk_lib::Chip; +static mut CHIP: Option<&'static Chip> = None; // State for loading and holding applications. // How should the kernel respond when a process faults. @@ -51,6 +52,14 @@ pub struct PMCapability; unsafe impl capabilities::ProcessManagementCapability for PMCapability {} unsafe impl capabilities::ProcessStartCapability for PMCapability {} +type LedDriver = capsules_core::led::LedDriver< + 'static, + kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>, + 4, +>; + +type AdcDriver = capsules_core::adc::AdcDedicated<'static, nrf52840::adc::Adc<'static>>; + #[cfg(feature = "screen_ssd1306")] type Screen = components::ssd1306::Ssd1306ComponentType>; #[cfg(feature = "screen_sh1106")] @@ -101,20 +110,17 @@ fn create_short_id_from_name(name: &str, metadata: u8) -> ShortId { //------------------------------------------------------------------------------ struct Platform { + processes: &'static [Option<&'static dyn kernel::process::Process>], base: nrf52840dk_lib::Platform, screen: &'static ScreenDriver, - adc: &'static capsules_core::adc::AdcDedicated<'static, nrf52840::adc::Adc<'static>>, - led: &'static capsules_core::led::LedDriver< - 'static, - kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>, - 4, - >, - processes: &'static [Option<&'static dyn kernel::process::Process>], + adc: &'static AdcDriver, + led: &'static LedDriver, process_info: &'static ProcessInfoDriver, nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver, dynamic_app_loader: &'static AppLoaderDriver, } +// Expose system call interfaces to userspace. impl SyscallDriverLookup for Platform { fn with_driver(&self, driver_num: usize, f: F) -> R where @@ -134,8 +140,7 @@ impl SyscallDriverLookup for Platform { } } -type Chip = nrf52840dk_lib::Chip; - +// Configure the kernel. impl KernelResources for Platform { type SyscallDriverLookup = Self; type SyscallFilter = >::SyscallFilter; @@ -169,6 +174,7 @@ impl KernelResources for Platform { } } +// Called by the process loader when the board boots. impl kernel::process::ProcessLoadingAsyncClient for Platform { fn process_loaded(&self, _result: Result<(), kernel::process::ProcessLoadError>) {} @@ -184,6 +190,10 @@ impl kernel::process::ProcessLoadingAsyncClient for Platform { } } +//------------------------------------------------------------------------------ +// MAIN +//------------------------------------------------------------------------------ + /// Main function called after RAM initialized. #[no_mangle] pub unsafe fn main() { @@ -326,11 +336,11 @@ pub unsafe fn main() { kernel::storage_volume!(APP_STORAGE, 32); let nonvolatile_storage = components::isolated_nonvolatile_storage::IsolatedNonvolatileStorageComponent::new( - board_kernel, - capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM, - virtual_flash_nvm, - core::ptr::addr_of!(APP_STORAGE) as usize, - APP_STORAGE.len() + board_kernel, + capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM, + virtual_flash_nvm, + core::ptr::addr_of!(APP_STORAGE) as usize, + APP_STORAGE.len() ) .finalize(components::isolated_nonvolatile_storage_component_static!( capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52840::nvmc::Nvmc>, @@ -349,7 +359,7 @@ pub unsafe fn main() { .finalize(components::process_info_component_static!(PMCapability)); //-------------------------------------------------------------------------- - // Credential Checking + // CREDENTIAL CHECKING //-------------------------------------------------------------------------- // Create the credential checker. @@ -378,6 +388,10 @@ pub unsafe fn main() { ), ); + //-------------------------------------------------------------------------- + // PROCESS LOADING + //-------------------------------------------------------------------------- + // These symbols are defined in the standard Tock linker script. extern "C" { /// Beginning of the ROM region containing app images. @@ -418,7 +432,7 @@ pub unsafe fn main() { )); //-------------------------------------------------------------------------- - // Dynamic App Loading + // DYNAMIC PROCESS LOADING //-------------------------------------------------------------------------- // Create the dynamic binary flasher. @@ -446,17 +460,17 @@ pub unsafe fn main() { )); //-------------------------------------------------------------------------- - // PLATFORM SETUP, SCHEDULER, AND START KERNEL LOOP + // PLATFORM SETUP AND START KERNEL LOOP //-------------------------------------------------------------------------- let platform = static_init!( Platform, Platform { + processes, base: base_platform, screen, adc, led, - processes, process_info, nonvolatile_storage, dynamic_app_loader, From 7bcbff6a6ce206ba47c32496adc01de708e44d34 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 13:25:22 -0400 Subject: [PATCH 12/14] boards: tut: dyn proc: led/adc already provided --- .../src/main.rs | 59 +------------------ 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index acaa4cb774..14a00dc6b6 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -11,7 +11,6 @@ use core::ptr::{addr_of, addr_of_mut}; use kernel::component::Component; -use kernel::hil::led::LedLow; use kernel::platform::{KernelResources, SyscallDriverLookup}; use kernel::process::ProcessLoadingAsync; use kernel::process::ShortId; @@ -22,12 +21,6 @@ use nrf52840dk_lib::{self, PROCESSES}; mod app_id_assigner_name_metadata; -// The nRF52840DK LEDs (see back of board) -const LED1_PIN: Pin = Pin::P0_13; -const LED2_PIN: Pin = Pin::P0_14; -const LED3_PIN: Pin = Pin::P0_15; -const LED4_PIN: Pin = Pin::P0_16; - // GPIO used for the screen shield const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10; const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11; @@ -52,14 +45,6 @@ pub struct PMCapability; unsafe impl capabilities::ProcessManagementCapability for PMCapability {} unsafe impl capabilities::ProcessStartCapability for PMCapability {} -type LedDriver = capsules_core::led::LedDriver< - 'static, - kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>, - 4, ->; - -type AdcDriver = capsules_core::adc::AdcDedicated<'static, nrf52840::adc::Adc<'static>>; - #[cfg(feature = "screen_ssd1306")] type Screen = components::ssd1306::Ssd1306ComponentType>; #[cfg(feature = "screen_sh1106")] @@ -113,8 +98,6 @@ struct Platform { processes: &'static [Option<&'static dyn kernel::process::Process>], base: nrf52840dk_lib::Platform, screen: &'static ScreenDriver, - adc: &'static AdcDriver, - led: &'static LedDriver, process_info: &'static ProcessInfoDriver, nonvolatile_storage: &'static IsolatedNonvolatileStorageDriver, dynamic_app_loader: &'static AppLoaderDriver, @@ -128,8 +111,6 @@ impl SyscallDriverLookup for Platform { { match driver_num { capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)), - capsules_core::led::DRIVER_NUM => f(Some(self.led)), - capsules_core::adc::DRIVER_NUM => f(Some(self.adc)), capsules_extra::process_info_driver::DRIVER_NUM => f(Some(self.process_info)), capsules_extra::isolated_nonvolatile_storage_driver::DRIVER_NUM => { f(Some(self.nonvolatile_storage)) @@ -207,43 +188,6 @@ pub unsafe fn main() { CHIP = Some(chip); - //-------------------------------------------------------------------------- - // LEDs - //-------------------------------------------------------------------------- - - let led = components::led::LedsComponent::new().finalize(components::led_component_static!( - LedLow<'static, nrf52840::gpio::GPIOPin>, - LedLow::new(&nrf52840_peripherals.gpio_port[LED1_PIN]), - LedLow::new(&nrf52840_peripherals.gpio_port[LED2_PIN]), - LedLow::new(&nrf52840_peripherals.gpio_port[LED3_PIN]), - LedLow::new(&nrf52840_peripherals.gpio_port[LED4_PIN]), - )); - - //-------------------------------------------------------------------------- - // ADC - //-------------------------------------------------------------------------- - - let adc_channels = static_init!( - [nrf52840::adc::AdcChannelSetup; 6], - [ - nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput1), - nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput2), - nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput4), - nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput5), - nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput6), - nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput7), - ] - ); - let adc = components::adc::AdcDedicatedComponent::new( - &nrf52840_peripherals.nrf52.adc, - adc_channels, - board_kernel, - capsules_core::adc::DRIVER_NUM, - ) - .finalize(components::adc_dedicated_component_static!( - nrf52840::adc::Adc - )); - //-------------------------------------------------------------------------- // SCREEN //-------------------------------------------------------------------------- @@ -469,8 +413,7 @@ pub unsafe fn main() { processes, base: base_platform, screen, - adc, - led, + process_info, nonvolatile_storage, dynamic_app_loader, From 6e4ed438f10d6e05ca0e4917ca8dedf391b52f6b Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Mon, 19 May 2025 13:29:29 -0400 Subject: [PATCH 13/14] boards: tut: dyn proc: use stop&debug panic policy --- .../nrf52840dk-dynamic-apps-and-policies/src/main.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index 14a00dc6b6..dbb07afdac 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT // Copyright Tock Contributors 2022. -//! Tock kernel for the Nordic Semiconductor nRF52840 development kit (DK). +//! Tock kernel for the nRF52840-based dynamic processes and policies tutorial. #![no_std] #![no_main] @@ -31,10 +31,9 @@ const NUM_PROCS: usize = 8; type Chip = nrf52840dk_lib::Chip; static mut CHIP: Option<&'static Chip> = None; -// State for loading and holding applications. // How should the kernel respond when a process faults. -const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy = - capsules_system::process_policies::PanicFaultPolicy {}; +const FAULT_RESPONSE: capsules_system::process_policies::StopWithDebugFaultPolicy = + capsules_system::process_policies::StopWithDebugFaultPolicy {}; //------------------------------------------------------------------------------ // SYSCALL DRIVER TYPE DEFINITIONS From 47f966917f68ff1cb0d321e3c150790cdba8654a Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 20 May 2025 17:24:51 -0400 Subject: [PATCH 14/14] boards: tut: dyn proc: add system call filter template --- .../src/main.rs | 17 +++++++-- .../src/system_call_filter.rs | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/system_call_filter.rs diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs index dbb07afdac..121bb0575c 100644 --- a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/main.rs @@ -20,6 +20,7 @@ use nrf52840::interrupt_service::Nrf52840DefaultPeripherals; use nrf52840dk_lib::{self, PROCESSES}; mod app_id_assigner_name_metadata; +mod system_call_filter; // GPIO used for the screen shield const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10; @@ -95,6 +96,7 @@ fn create_short_id_from_name(name: &str, metadata: u8) -> ShortId { struct Platform { processes: &'static [Option<&'static dyn kernel::process::Process>], + syscall_filter: &'static system_call_filter::DynamicPoliciesCustomFilter, base: nrf52840dk_lib::Platform, screen: &'static ScreenDriver, process_info: &'static ProcessInfoDriver, @@ -123,7 +125,7 @@ impl SyscallDriverLookup for Platform { // Configure the kernel. impl KernelResources for Platform { type SyscallDriverLookup = Self; - type SyscallFilter = >::SyscallFilter; + type SyscallFilter = system_call_filter::DynamicPoliciesCustomFilter; type ProcessFault = >::ProcessFault; type Scheduler = >::Scheduler; type SchedulerTimer = >::SchedulerTimer; @@ -135,7 +137,7 @@ impl KernelResources for Platform { self } fn syscall_filter(&self) -> &Self::SyscallFilter { - self.base.syscall_filter() + self.syscall_filter } fn process_fault(&self) -> &Self::ProcessFault { self.base.process_fault() @@ -301,6 +303,15 @@ pub unsafe fn main() { ) .finalize(components::process_info_component_static!(PMCapability)); + //-------------------------------------------------------------------------- + // SYSTEM CALL FILTERING + //-------------------------------------------------------------------------- + + let syscall_filter = static_init!( + system_call_filter::DynamicPoliciesCustomFilter, + system_call_filter::DynamicPoliciesCustomFilter {} + ); + //-------------------------------------------------------------------------- // CREDENTIAL CHECKING //-------------------------------------------------------------------------- @@ -410,9 +421,9 @@ pub unsafe fn main() { Platform, Platform { processes, + syscall_filter, base: base_platform, screen, - process_info, nonvolatile_storage, dynamic_app_loader, diff --git a/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/system_call_filter.rs b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/system_call_filter.rs new file mode 100644 index 0000000000..548f88051a --- /dev/null +++ b/boards/tutorials/nrf52840dk-dynamic-apps-and-policies/src/system_call_filter.rs @@ -0,0 +1,37 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2025. + +use kernel::errorcode; +use kernel::platform::SyscallFilter; +use kernel::process; +use kernel::process::ShortId; +use kernel::syscall; + +pub struct DynamicPoliciesCustomFilter {} + +impl SyscallFilter for DynamicPoliciesCustomFilter { + fn filter_syscall( + &self, + process: &dyn process::Process, + _syscall: &syscall::Syscall, + ) -> Result<(), errorcode::ErrorCode> { + // Get the upper four bits of the ShortId. + let signing_key_id = if let ShortId::Fixed(fixed_id) = process.short_app_id() { + ((u32::from(fixed_id) >> 28) & 0xF) as u8 + } else { + 0xff_u8 + }; + + // Enforce the correct policy based on the signing key and the system + // call. + // + // Documentation for system call: + // https://docs.tockos.org/kernel/syscall/enum.syscall#implementations + match signing_key_id { + 0 => Ok(()), + 1 => Ok(()), + _ => Ok(()), + } + } +}