Tock V2 port - rebased and updated (#620)

* Changes from #580

* fixes USB cancel panic

* style fixes

* Update src/env/tock/storage.rs

Co-authored-by: Zach Halvorsen <zhalvorsen@google.com>

---------

Co-authored-by: Zach Halvorsen <zhalvorsen@google.com>
This commit is contained in:
kaczmarczyck
2023-05-05 09:55:16 +02:00
committed by GitHub
parent 645c1ba3a7
commit f25cdd6acc
78 changed files with 4079 additions and 4699 deletions

View File

@@ -10,6 +10,7 @@ use nrf52840::gpio::Pin;
use crate::CHIP;
use crate::PROCESSES;
use crate::PROCESS_PRINTER;
enum Writer {
WriterUart(/* initialized */ bool),
@@ -48,7 +49,7 @@ impl IoWrite for Writer {
let uart = nrf52840::uart::Uarte::new();
if !*initialized {
*initialized = true;
uart.configure(uart::Parameters {
let _ = uart.configure(uart::Parameters {
baud_rate: 115200,
stop_bits: uart::StopBits::One,
parity: uart::Parity::None,
@@ -102,5 +103,6 @@ pub unsafe extern "C" fn panic_fmt(pi: &PanicInfo) -> ! {
&cortexm4::support::nop,
&PROCESSES,
&CHIP,
&PROCESS_PRINTER,
)
}

View File

@@ -64,14 +64,16 @@
// Disable this attribute when documenting, as a workaround for
// https://github.com/rust-lang/rust/issues/62184.
#![cfg_attr(not(doc), no_main)]
#![feature(const_in_array_repeat_expressions)]
#![deny(missing_docs)]
use capsules::virtual_alarm::VirtualMuxAlarm;
use core::env;
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
use kernel::component::Component;
use kernel::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
use kernel::hil::led::LedLow;
use kernel::hil::time::Counter;
use kernel::platform::{KernelResources, SyscallDriverLookup, SyscallFilter};
use kernel::scheduler::round_robin::RoundRobinSched;
#[allow(unused_imports)]
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
use nrf52840::gpio::Pin;
@@ -121,28 +123,33 @@ static STRINGS: &'static [&'static str] = &[
// State for loading and holding applications.
// How should the kernel respond when a process faults.
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
const FAULT_RESPONSE: kernel::process::PanicFaultPolicy = kernel::process::PanicFaultPolicy {};
// Number of concurrent processes this platform supports.
const NUM_PROCS: usize = 8;
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
[None; NUM_PROCS];
include!(concat!(env!("OUT_DIR"), "/locations.rs"));
static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
static mut PROCESS_PRINTER: Option<&'static kernel::process::ProcessPrinterText> = None;
/// Flash buffer for the custom nvmc driver
static mut APP_FLASH_BUFFER: [u8; 0x1000] = [0; 0x1000];
/// 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; 0x1000] = [0; 0x1000];
pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
/// Supported drivers by the platform
pub struct Platform {
button: &'static capsules::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
pconsole: &'static capsules::process_console::ProcessConsole<
'static,
VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
components::process_console::Capability,
>,
console: &'static capsules::console::Console<'static>,
@@ -150,9 +157,10 @@ pub struct Platform {
led: &'static capsules::led::LedDriver<
'static,
kernel::hil::led::LedLow<'static, nrf52840::gpio::GPIOPin<'static>>,
4,
>,
rng: &'static capsules::rng::RngDriver<'static>,
ipc: kernel::ipc::IPC<NUM_PROCS>,
ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
analog_comparator: &'static capsules::analog_comparator::AnalogComparator<
'static,
nrf52840::acomp::Comparator<'static>,
@@ -167,13 +175,14 @@ pub struct Platform {
'static,
nrf52840::usbd::Usbd<'static>,
>,
crp: &'static capsules::firmware_protection::FirmwareProtection<nrf52840::uicr::Uicr>,
scheduler: &'static RoundRobinSched<'static>,
systick: cortexm4::systick::SysTick,
}
impl kernel::Platform for Platform {
impl SyscallDriverLookup for Platform {
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
where
F: FnOnce(Option<&dyn kernel::Driver>) -> R,
F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
{
match driver_num {
capsules::console::DRIVER_NUM => f(Some(self.console)),
@@ -185,44 +194,89 @@ impl kernel::Platform for Platform {
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
capsules::usb::usb_ctap::DRIVER_NUM => f(Some(self.usb)),
capsules::firmware_protection::DRIVER_NUM => f(Some(self.crp)),
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
_ => f(None),
}
}
}
impl SyscallFilter for Platform {
fn filter_syscall(
&self,
process: &dyn kernel::procs::ProcessType,
process: &dyn kernel::process::Process,
syscall: &kernel::syscall::Syscall,
) -> Result<(), kernel::ReturnCode> {
) -> Result<(), kernel::errorcode::ErrorCode> {
use kernel::syscall::Syscall;
match *syscall {
Syscall::COMMAND {
Syscall::Command {
driver_number: nrf52840::nvmc::DRIVER_NUM,
subdriver_number: cmd,
arg0: ptr,
arg1: len,
} if (cmd == 2 || cmd == 3) && !process.fits_in_storage_location(ptr, len) => {
Err(kernel::ReturnCode::EINVAL)
Err(kernel::ErrorCode::INVAL)
}
_ => Ok(()),
}
}
}
/// Entry point in the vector table called on hard reset.
#[no_mangle]
pub unsafe fn reset_handler() {
// Loads relocations and clears BSS
nrf52840::init();
let ppi = static_init!(nrf52840::ppi::Ppi, nrf52840::ppi::Ppi::new());
/// 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 get_peripherals() -> &'static mut Nrf52840DefaultPeripherals<'static> {
// Initialize chip peripheral drivers
let nrf52840_peripherals = static_init!(
Nrf52840DefaultPeripherals,
Nrf52840DefaultPeripherals::new(ppi)
Nrf52840DefaultPeripherals::new()
);
nrf52840_peripherals
}
impl KernelResources<nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
for Platform
{
type SyscallDriverLookup = Self;
type SyscallFilter = Self;
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 {
&self
}
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 {
&()
}
}
/// Main function called after RAM initialized.
#[no_mangle]
pub unsafe fn main() {
// Loads relocations and clears BSS
nrf52840::init();
// Initialize chip peripheral drivers
let nrf52840_peripherals = get_peripherals();
// set up circular peripheral dependencies
nrf52840_peripherals.init();
let base_peripherals = &nrf52840_peripherals.nrf52;
@@ -249,6 +303,7 @@ pub unsafe fn reset_handler() {
let gpio = components::gpio::GpioComponent::new(
board_kernel,
capsules::gpio::DRIVER_NUM,
components::gpio_component_helper!(
nrf52840::gpio::GPIOPin,
0 => &nrf52840_peripherals.gpio_port[Pin::P1_01],
@@ -273,6 +328,7 @@ pub unsafe fn reset_handler() {
let button = components::button::ButtonComponent::new(
board_kernel,
capsules::button::DRIVER_NUM,
components::button_component_helper!(
nrf52840::gpio::GPIOPin,
(
@@ -299,15 +355,12 @@ pub unsafe fn reset_handler() {
)
.finalize(components::button_component_buf!(nrf52840::gpio::GPIOPin));
let led = components::led::LedsComponent::new(components::led_component_helper!(
let led = components::led::LedsComponent::new().finalize(components::led_component_helper!(
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]),
))
.finalize(components::led_component_buf!(
LedLow<'static, nrf52840::gpio::GPIOPin>
));
let chip = static_init!(
@@ -339,11 +392,15 @@ pub unsafe fn reset_handler() {
);
let rtc = &base_peripherals.rtc;
rtc.start();
let _ = rtc.start();
let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
.finalize(components::alarm_mux_component_helper!(nrf52840::rtc::Rtc));
let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
let alarm = components::alarm::AlarmDriverComponent::new(
board_kernel,
capsules::alarm::DRIVER_NUM,
mux_alarm,
)
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
let channel = nrf52_components::UartChannelComponent::new(
uart_channel,
@@ -359,22 +416,41 @@ pub unsafe fn reset_handler() {
DynamicDeferredCall::new(dynamic_deferred_call_clients)
);
DynamicDeferredCall::set_global_instance(dynamic_deferred_caller);
let process_printer =
components::process_printer::ProcessPrinterTextComponent::new().finalize(());
PROCESS_PRINTER = Some(process_printer);
// Create a shared UART channel for the console and for kernel debug.
let uart_mux =
components::console::UartMuxComponent::new(channel, 115200, dynamic_deferred_caller)
.finalize(());
let pconsole =
components::process_console::ProcessConsoleComponent::new(board_kernel, uart_mux)
.finalize(());
let pconsole = components::process_console::ProcessConsoleComponent::new(
board_kernel,
uart_mux,
mux_alarm,
process_printer,
)
.finalize(components::process_console_component_helper!(
nrf52840::rtc::Rtc<'static>
));
// Setup the console.
let console = components::console::ConsoleComponent::new(board_kernel, uart_mux).finalize(());
let console = components::console::ConsoleComponent::new(
board_kernel,
capsules::console::DRIVER_NUM,
uart_mux,
)
.finalize(components::console_component_helper!());
// Create the debugger object that handles calls to `debug!()`.
components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());
let rng = components::rng::RngComponent::new(board_kernel, &base_peripherals.trng).finalize(());
let rng = components::rng::RngComponent::new(
board_kernel,
capsules::rng::DRIVER_NUM,
&base_peripherals.trng,
)
.finalize(());
base_peripherals.spim0.configure(
nrf52840::pinmux::Pinmux::new(SPI_MOSI as u32),
@@ -390,6 +466,8 @@ pub unsafe fn reset_handler() {
nrf52840::acomp::Channel,
&nrf52840::acomp::CHANNEL_AC0
),
board_kernel,
capsules::analog_comparator::DRIVER_NUM,
)
.finalize(components::acomp_component_buf!(
nrf52840::acomp::Comparator
@@ -399,8 +477,9 @@ pub unsafe fn reset_handler() {
nrf52840::nvmc::SyscallDriver,
nrf52840::nvmc::SyscallDriver::new(
&base_peripherals.nvmc,
board_kernel.create_grant(&memory_allocation_capability),
board_kernel.create_grant(nrf52840::nvmc::DRIVER_NUM, &memory_allocation_capability),
dynamic_deferred_caller,
&mut APP_FLASH_BUFFER,
)
);
nvmc.set_deferred_handle(
@@ -412,21 +491,17 @@ pub unsafe fn reset_handler() {
// Configure USB controller
let usb = components::usb_ctap::UsbCtapComponent::new(
board_kernel,
capsules::usb::usb_ctap::DRIVER_NUM,
&nrf52840_peripherals.usbd,
capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
VENDOR_ID,
PRODUCT_ID,
STRINGS,
)
.finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
.finalize(components::usb_ctap_component_helper!(nrf52840::usbd::Usbd));
let crp = components::firmware_protection::FirmwareProtectionComponent::new(
board_kernel,
nrf52840::uicr::Uicr::new(),
)
.finalize(components::firmware_protection_component_helper!(
nrf52840::uicr::Uicr
));
let scheduler = components::sched::round_robin::RoundRobinComponent::new(&PROCESSES)
.finalize(components::rr_component_helper!(NUM_PROCS));
nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
@@ -441,15 +516,20 @@ pub unsafe fn reset_handler() {
analog_comparator,
nvmc,
usb,
crp,
ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability),
ipc: kernel::ipc::IPC::new(
board_kernel,
kernel::ipc::DRIVER_NUM,
&memory_allocation_capability,
),
scheduler,
systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
};
platform.pconsole.start();
let _ = platform.pconsole.start();
debug!("Initialization complete. Entering main loop\r");
debug!("{}", &nrf52840::ficr::FICR_INSTANCE);
/// These symbols are defined in the linker script.
// These symbols are defined in the linker script.
extern "C" {
/// Beginning of the ROM region containing app images.
static _sapps: u8;
@@ -461,7 +541,7 @@ pub unsafe fn reset_handler() {
static _eappmem: u8;
}
kernel::procs::load_processes(
kernel::process::load_processes(
board_kernel,
chip,
core::slice::from_raw_parts(
@@ -473,7 +553,7 @@ pub unsafe fn reset_handler() {
&_eappmem as *const u8 as usize - &_sappmem as *const u8 as usize,
),
&mut PROCESSES,
FAULT_RESPONSE,
&FAULT_RESPONSE,
&process_management_capability,
)
.unwrap_or_else(|err| {
@@ -481,13 +561,5 @@ pub unsafe fn reset_handler() {
debug!("{:?}", err);
});
let scheduler = components::sched::round_robin::RoundRobinComponent::new(&PROCESSES)
.finalize(components::rr_component_helper!(NUM_PROCS));
board_kernel.kernel_loop(
&platform,
chip,
Some(&platform.ipc),
scheduler,
&main_loop_capability,
);
board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability);
}