Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions boards/nordic/nrf52840dk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ use kernel::hil::led::LedLow;
use kernel::hil::time::Counter;
#[allow(unused_imports)]
use kernel::hil::usb::Client;
use kernel::platform::chip::Chip;
use kernel::platform::{KernelResources, SyscallDriverLookup};
use kernel::process::ProcessArray;
use kernel::scheduler::round_robin::RoundRobinSched;
Expand Down Expand Up @@ -404,12 +405,7 @@ pub unsafe fn start_no_pconsole() -> (
//--------------------------------------------------------------------------

// Apply errata fixes and enable interrupts.
nrf52840::init();

// Initialize deferred calls very early.
kernel::deferred_call::initialize_deferred_call_state::<
<ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
>();
ChipHw::init();

// Set up peripheral drivers. Called in separate function to reduce stack
// usage.
Expand Down
21 changes: 21 additions & 0 deletions chips/nrf52/src/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,27 @@ impl<'a, I: InterruptService + 'a> kernel::platform::chip::Chip for NRF52<'a, I>
type UserspaceKernelBoundary = cortexm4f::syscall::SysCall;
type ThreadIdProvider = cortexm4f::thread_id::CortexMThreadIdProvider;

fn init() {
// # Safety
//
// We are setting up the nRF52 chip, so these memory locations are valid
// on the nRF52 and this is OK to call.
unsafe {
crate::crt1::fix_errata();
}
crate::crt1::initialize_vector_table();

// # Safety
//
// Need to enable interrupts.
unsafe {
nvic::enable_all();
}

// Initialize deferred calls very early.
kernel::deferred_call::initialize_deferred_call_state::<Self::ThreadIdProvider>();
}

fn mpu(&self) -> &Self::MPU {
&self.mpu
}
Expand Down
40 changes: 26 additions & 14 deletions chips/nrf52/src/crt1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

use cortexm4f::{
initialize_ram_jump_to_main, nvic, scb, unhandled_interrupt, CortexM4F, CortexMVariant,
};
use cortexm4f::{initialize_ram_jump_to_main, scb, unhandled_interrupt, CortexM4F, CortexMVariant};

/*
* Adapted from crt1.c which was relicensed by the original author from
Expand Down Expand Up @@ -71,8 +69,13 @@ pub static BASE_VECTORS: [unsafe extern "C" fn(); 16] = [
#[cfg_attr(all(target_arch = "arm", target_os = "none"), used)]
pub static IRQS: [unsafe extern "C" fn(); 80] = [CortexM4F::GENERIC_ISR; 80];

#[no_mangle]
pub unsafe extern "C" fn init() {
/// Apply fixes for various nRF52 errata
///
/// # Safety
///
/// Fixing these errata requires writing to various memory locations. These
/// operations are safe as long as this is only run on an nRF52 MCU.
pub(crate) unsafe fn fix_errata() {
// Apply early initialization workarounds for anomalies documented on
// 2015-12-11 nRF52832 Errata v1.2
// http://infocenter.nordicsemi.com/pdf/nRF52832_Errata_v1.2.pdf
Expand Down Expand Up @@ -139,14 +142,23 @@ pub unsafe extern "C" fn init() {
// "RAM: RAM content cannot be trusted upon waking up from System ON Idle
// or System OFF mode" found at the Errata doc
*(0x40000ee4i32 as *mut u32) = *(0x10000258i32 as *mut u32) & 0x4fu32;
}

// Explicitly tell the core where Tock's vector table is located. If Tock is the
// only thing on the chip then this is effectively a no-op. If, however, there is
// a bootloader present then we want to ensure that the vector table is set
// correctly for Tock. The bootloader _may_ set this for us, but it may not
// so that any errors early in the Tock boot process trap back to the bootloader.
// To be safe we unconditionally set the vector table.
scb::set_vector_table_offset(BASE_VECTORS.as_ptr().cast::<()>());

nvic::enable_all();
/// Explicitly tell the core where Tock's vector table is located.
///
/// If Tock is the
/// only thing on the chip then this is effectively a no-op. If, however, there is
/// a bootloader present then we want to ensure that the vector table is set
/// correctly for Tock. The bootloader _may_ set this for us, but it may not
/// so that any errors early in the Tock boot process trap back to the bootloader.
/// To be safe we unconditionally set the vector table.
pub(crate) fn initialize_vector_table() {
// # Safety
//
// The vector table must setup function pointers for the thumb core
// correctly. Because `BASE_VECTORS` is the correct data type this is
// safe.
unsafe {
scb::set_vector_table_offset(BASE_VECTORS.as_ptr().cast::<()>());
}
}
1 change: 0 additions & 1 deletion chips/nrf52/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ pub mod uart;
pub mod uicr;
pub mod usbd;

pub use crate::crt1::init;
pub use nrf5x::{
aes, constants, gpio, peripheral_interrupts, pinmux, rtc, temperature, timer, trng,
};
4 changes: 2 additions & 2 deletions chips/nrf52840/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

#![no_std]
pub use nrf52::{
acomp, adc, aes, ble_radio, chip, clock, constants, crt1, ficr, i2c, ieee802154_radio, init,
nvmc, peripheral_interrupts as base_interrupts, pinmux, power, ppi, pwm, rtc, spi, temperature,
acomp, adc, aes, ble_radio, chip, clock, constants, crt1, ficr, i2c, ieee802154_radio, nvmc,
peripheral_interrupts as base_interrupts, pinmux, power, ppi, pwm, rtc, spi, temperature,
timer, trng, uart, uicr, usbd,
};
pub mod gpio;
Expand Down
11 changes: 11 additions & 0 deletions kernel/src/platform/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ pub trait Chip {
/// chips may have various custom requirements.
type UserspaceKernelBoundary: syscall::UserspaceKernelBoundary;

/// Run any necessary initialization for this chip.
///
/// This should be called first by the board in its `main()` function.
///
/// This should contain any necessary initialization steps, including:
///
/// - Any architecture-specific setup
/// - Any errata fixes
/// - Any configuration needed for the chip to continue booting the kernel
fn init();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to write a check that would panic if this function was not called by the board?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure, be we could probably enforce a return type that is required to call the kernel loop if we wanted.


/// The kernel calls this function to tell the chip to check for all pending
/// interrupts and to correctly dispatch them to the peripheral drivers for
/// the chip.
Expand Down
Loading