mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-30 23:44:34 +01:00
hide the unsafe Peripheral::new constructor
`peripherals!` is the safe way to declare `Peripheral`s
This commit is contained in:
parent
f9ada3f7f4
commit
840c32060b
1 changed files with 85 additions and 18 deletions
103
src/lib.rs
103
src/lib.rs
|
@ -17,8 +17,8 @@
|
||||||
//! - **Data race free memory sharing** through fine grained *non global*
|
//! - **Data race free memory sharing** through fine grained *non global*
|
||||||
//! critical sections.
|
//! critical sections.
|
||||||
//! - **Deadlock free execution** guaranteed at compile time.
|
//! - **Deadlock free execution** guaranteed at compile time.
|
||||||
//! - **Minimal overhead** as the scheduler has no software component / runtime; the
|
//! - **Minimal overhead** as the scheduler has no software component / runtime;
|
||||||
//! hardware does all the scheduling.
|
//! the hardware does all the scheduling.
|
||||||
//! - Full support for all Cortex M3, M4 and M7 devices. M0(+) is also supported
|
//! - Full support for all Cortex M3, M4 and M7 devices. M0(+) is also supported
|
||||||
//! but the whole API is not available (due to missing hardware features).
|
//! but the whole API is not available (due to missing hardware features).
|
||||||
//! - The number of task priority levels is configurable at compile time through
|
//! - The number of task priority levels is configurable at compile time through
|
||||||
|
@ -35,11 +35,11 @@
|
||||||
//!
|
//!
|
||||||
//! # Dependencies
|
//! # Dependencies
|
||||||
//!
|
//!
|
||||||
//! - A device crate generated using [`svd2rust`] v0.6.x
|
//! - A device crate generated using [`svd2rust`] v0.7.x
|
||||||
//! - A `start` lang time: Vanilla `main` must be supported in binary crates.
|
//! - A `start` lang time: Vanilla `main` must be supported in binary crates.
|
||||||
//! You can use the [`cortex-m-rt`] crate to fulfill the requirement
|
//! You can use the [`cortex-m-rt`] crate to fulfill the requirement
|
||||||
//!
|
//!
|
||||||
//! [`svd2rust`]: https://docs.rs/svd2rust/0.6.1/svd2rust/
|
//! [`svd2rust`]: https://docs.rs/svd2rust/0.7.0/svd2rust/
|
||||||
//! [`cortex-m-rt`]: https://docs.rs/cortex-m-rt/0.1.1/cortex_m_rt/
|
//! [`cortex-m-rt`]: https://docs.rs/cortex-m-rt/0.1.1/cortex_m_rt/
|
||||||
//!
|
//!
|
||||||
//! # Examples
|
//! # Examples
|
||||||
|
@ -494,12 +494,15 @@ impl<T, RC> Resource<T, C<RC>> {
|
||||||
unsafe impl<T, C> Sync for Resource<T, C> {}
|
unsafe impl<T, C> Sync for Resource<T, C> {}
|
||||||
|
|
||||||
/// A hardware peripheral as a resource
|
/// A hardware peripheral as a resource
|
||||||
pub struct Peripheral<P, CEILING>
|
///
|
||||||
|
/// To assign a ceiling to a peripheral, use the
|
||||||
|
/// [`peripherals!`](./macro.peripherals.html) macro
|
||||||
|
pub struct Peripheral<P, PC>
|
||||||
where
|
where
|
||||||
P: 'static,
|
P: 'static,
|
||||||
{
|
{
|
||||||
peripheral: cortex_m::peripheral::Peripheral<P>,
|
peripheral: cortex_m::peripheral::Peripheral<P>,
|
||||||
_ceiling: PhantomData<CEILING>,
|
_ceiling: PhantomData<PC>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, CEILING> Peripheral<P, C<CEILING>>
|
impl<P, CEILING> Peripheral<P, C<CEILING>>
|
||||||
|
@ -507,12 +510,8 @@ where
|
||||||
CEILING: GreaterThanOrEqual<U0>,
|
CEILING: GreaterThanOrEqual<U0>,
|
||||||
CEILING: LessThanOrEqual<UMAX>,
|
CEILING: LessThanOrEqual<UMAX>,
|
||||||
{
|
{
|
||||||
/// Assigns a ceiling `C` to the `peripheral`
|
#[doc(hidden)]
|
||||||
///
|
pub const unsafe fn _new(peripheral: cortex_m::peripheral::Peripheral<P>,)
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// You MUST not create two resources that point to the same peripheral
|
|
||||||
pub const unsafe fn new(peripheral: cortex_m::peripheral::Peripheral<P>,)
|
|
||||||
-> Self {
|
-> Self {
|
||||||
Peripheral {
|
Peripheral {
|
||||||
_ceiling: PhantomData,
|
_ceiling: PhantomData,
|
||||||
|
@ -563,7 +562,7 @@ where
|
||||||
///
|
///
|
||||||
/// The task won't run even if the underlying interrupt is raised
|
/// The task won't run even if the underlying interrupt is raised
|
||||||
pub fn disable<T, TP>(_task: fn(T, P<TP>))
|
pub fn disable<T, TP>(_task: fn(T, P<TP>))
|
||||||
where
|
where
|
||||||
T: Context + Nr,
|
T: Context + Nr,
|
||||||
{
|
{
|
||||||
// NOTE(safe) zero sized type
|
// NOTE(safe) zero sized type
|
||||||
|
@ -705,7 +704,31 @@ pub unsafe trait GreaterThanOrEqual<RHS> {}
|
||||||
/// Do not implement this trait yourself. This is an implementation detail.
|
/// Do not implement this trait yourself. This is an implementation detail.
|
||||||
pub unsafe trait LessThanOrEqual<RHS> {}
|
pub unsafe trait LessThanOrEqual<RHS> {}
|
||||||
|
|
||||||
/// Assigns ceilings to peripherals
|
/// A macro to assign ceilings to peripherals
|
||||||
|
///
|
||||||
|
/// **NOTE** A peripheral instance, like RCC, can only be bound to a *single*
|
||||||
|
/// ceiling. Trying to use this macro to bind the same peripheral to several
|
||||||
|
/// ceiling will result in a compiler error.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ``` ignore
|
||||||
|
/// #[macro_use]
|
||||||
|
/// extern crate cortex_m_rtfm;
|
||||||
|
/// // device crate generated using `svd2rust`
|
||||||
|
/// extern crate stm32f30x;
|
||||||
|
///
|
||||||
|
/// peripherals!(stm32f30x, {
|
||||||
|
/// GPIOA: Peripheral {
|
||||||
|
/// register_block: Gpioa,
|
||||||
|
/// ceiling: C1,
|
||||||
|
/// },
|
||||||
|
/// RCC: Peripheral {
|
||||||
|
/// register_block: Rcc,
|
||||||
|
/// ceiling: C0,
|
||||||
|
/// },
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! peripherals {
|
macro_rules! peripherals {
|
||||||
($device:ident, {
|
($device:ident, {
|
||||||
|
@ -719,7 +742,7 @@ macro_rules! peripherals {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
static $PERIPHERAL:
|
static $PERIPHERAL:
|
||||||
$crate::Peripheral<::$device::$RegisterBlock, $crate::$C> =
|
$crate::Peripheral<::$device::$RegisterBlock, $crate::$C> =
|
||||||
unsafe { $crate::Peripheral::new(::$device::$PERIPHERAL) };
|
unsafe { $crate::Peripheral::_new(::$device::$PERIPHERAL) };
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -729,13 +752,57 @@ macro_rules! peripherals {
|
||||||
/// **NOTE** This macro will expand to a `main` function.
|
/// **NOTE** This macro will expand to a `main` function.
|
||||||
///
|
///
|
||||||
/// Each `$task` is bound to an `$Interrupt` handler and has a priority `$P`.
|
/// Each `$task` is bound to an `$Interrupt` handler and has a priority `$P`.
|
||||||
/// `$enabled` indicates whether the task will be enabled before `idle` runs.
|
/// The minimum priority of a task is `P1`. `$enabled` indicates whether the
|
||||||
|
/// task will be enabled before `idle` runs.
|
||||||
///
|
///
|
||||||
/// The `$Interrupt` handlers are defined in the `$device` crate.
|
/// The `$Interrupt` handlers are defined in the `$device` crate.
|
||||||
///
|
///
|
||||||
/// Apart from defining the listed `$tasks`, the `init` and `idle` functions
|
/// Apart from defining the listed `$tasks`, the `init` and `idle` functions
|
||||||
/// must be defined as well. `init` has type signature `fn(P0, &C16)`, and
|
/// must be defined as well. `init` has signature `fn(P0, &C16)`, and `idle` has
|
||||||
/// `idle` has signature `fn(P0) -> !`.
|
/// signature `fn(P0) -> !`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ``` ignore
|
||||||
|
/// #[macro_use]
|
||||||
|
/// extern crate cortex_m_rtfm as rtfm;
|
||||||
|
/// // device crate generated using `svd2rust`
|
||||||
|
/// extern crate stm32f30x;
|
||||||
|
///
|
||||||
|
/// use rtfm::{C16, P0, P1, P2};
|
||||||
|
/// use stm32f30x::interrupt::{Exti0, Tim7};
|
||||||
|
///
|
||||||
|
/// tasks!(stm32f30x, {
|
||||||
|
/// periodic: Task {
|
||||||
|
/// interrupt: Tim7,
|
||||||
|
/// priority: P1,
|
||||||
|
/// enabled: true,
|
||||||
|
/// },
|
||||||
|
/// button: Task {
|
||||||
|
/// interrupt: Exti0,
|
||||||
|
/// priority: P2,
|
||||||
|
/// enabled: true,
|
||||||
|
/// },
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// fn init(priority: P0, ceiling: C16) {
|
||||||
|
/// // ..
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn idle(priority: P0) -> ! {
|
||||||
|
/// // Sleep
|
||||||
|
/// loop { rtfm::wfi() }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // NOTE signature must match the tasks! declaration
|
||||||
|
/// fn periodic(task: Tim7, priority: P1) {
|
||||||
|
/// // ..
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn button(task: Exti0, priority: P2) {
|
||||||
|
/// // ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! tasks {
|
macro_rules! tasks {
|
||||||
($device:ident, {
|
($device:ident, {
|
||||||
|
|
Loading…
Reference in a new issue