From def4fc8079dcb646ef3cab446a4b160e09e169bf Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 15 Jan 2018 23:26:07 +0100 Subject: v0.3.0 --- CHANGELOG.md | 24 +++++++++- Cargo.toml | 12 ++--- examples/safe-static-mut-ref.rs | 2 +- gen-examples.sh | 1 + macros/Cargo.toml | 5 +- macros/src/lib.rs | 22 ++++++--- src/examples/_6_generics.rs | 78 ------------------------------ src/examples/_6_safe_static_mut_ref.rs | 36 ++++++++++++++ src/examples/_7_full_syntax.rs | 88 ---------------------------------- src/examples/_7_generics.rs | 78 ++++++++++++++++++++++++++++++ src/examples/_8_full_syntax.rs | 88 ++++++++++++++++++++++++++++++++++ src/examples/mod.rs | 5 +- src/lib.rs | 8 ++-- 13 files changed, 256 insertions(+), 191 deletions(-) delete mode 100644 src/examples/_6_generics.rs create mode 100644 src/examples/_6_safe_static_mut_ref.rs delete mode 100644 src/examples/_7_full_syntax.rs create mode 100644 src/examples/_7_generics.rs create mode 100644 src/examples/_8_full_syntax.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 405923b..c30ff4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.3.0] - 2018-01-15 + +### Added + +- [feat] `&'static mut` references can be safely created by assigning resources to `init`. See the + `init.resources` section of the `app!` macro documentation and the `safe-static-mut-ref` example + for details. + +### Changed + +- [breaking-change] svd2rust dependency has been bumped to v0.12.0 + +- [breaking-change] resources assigned to tasks, or to idle, that were not declared in the top + `resources` field generate compiler errors. Before these were assumed to be peripherals, that's no + longer the case. + +- [breaking-change] the layout of `init::Peripherals` has changed. This struct now has two fields: + `core` and `device`. The value of the `core` field is a struct that owns all the core peripherals + of the device and the value of the `device` field is a struct that owns all the device specific + peripherals of the device. + ## [v0.2.2] - 2017-11-22 ### Added @@ -56,7 +77,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Initial release -[Unreleased]: https://github.com/japaric/cortex-m-rtfm/compare/v0.2.2...HEAD +[Unreleased]: https://github.com/japaric/cortex-m-rtfm/compare/v0.3.0...HEAD +[v0.3.0]: https://github.com/japaric/cortex-m-rtfm/compare/v0.2.2...v0.3.0 [v0.2.2]: https://github.com/japaric/cortex-m-rtfm/compare/v0.2.1...v0.2.2 [v0.2.1]: https://github.com/japaric/cortex-m-rtfm/compare/v0.2.0...v0.2.1 [v0.2.0]: https://github.com/japaric/cortex-m-rtfm/compare/v0.1.1...v0.2.0 diff --git a/Cargo.toml b/Cargo.toml index bf123dd..129fd20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,23 +13,21 @@ repository = "https://github.com/japaric/cortex-m-rtfm" version = "0.3.0" [dependencies] -cortex-m = { git = "https://github.com/japaric/cortex-m" } +cortex-m = "0.4.0" +cortex-m-rtfm-macros = "0.3.0" +rtfm-core = "0.2.0" untagged-option = "0.1.1" -# rtfm-core = "0.2.0" -rtfm-core = { git = "https://github.com/japaric/rtfm-core" } -cortex-m-rtfm-macros = { path = "macros" } [target.'cfg(target_arch = "x86_64")'.dev-dependencies] compiletest_rs = "0.3.5" [dev-dependencies.cortex-m-rt] features = ["abort-on-panic"] -version = "0.3.3" +version = "0.3.9" [dev-dependencies.stm32f103xx] features = ["rt"] -git = "https://github.com/japaric/stm32f103xx" -# version = "0.8.0" +version = "0.8.0" [features] cm7-r0p1 = ["cortex-m/cm7-r0p1"] diff --git a/examples/safe-static-mut-ref.rs b/examples/safe-static-mut-ref.rs index bb87212..81dbde2 100644 --- a/examples/safe-static-mut-ref.rs +++ b/examples/safe-static-mut-ref.rs @@ -22,7 +22,7 @@ app! { } fn init(_p: init::Peripherals, r: init::Resources) { - let _buf: &'static mut [u8] = r.BUFFER; + let _buf: &'static mut [u8; 16] = r.BUFFER; } fn idle() -> ! { diff --git a/gen-examples.sh b/gen-examples.sh index e6870c4..20c9d7c 100644 --- a/gen-examples.sh +++ b/gen-examples.sh @@ -11,6 +11,7 @@ main() { preemption nested late-resources + safe-static-mut-ref generics full-syntax ) diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 27bd1f5..254b7bd 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -7,13 +7,12 @@ keywords = ["arm", "cortex-m"] license = "MIT OR Apache-2.0" name = "cortex-m-rtfm-macros" repository = "https://github.com/japaric/cortex-m-rtfm" -version = "0.2.1" +version = "0.3.0" [dependencies] error-chain = "0.10.0" quote = "0.3.15" -# rtfm-syntax = "0.2.0" -rtfm-syntax = { git = "https://github.com/japaric/rtfm-syntax" } +rtfm-syntax = "0.2.1" syn = "0.11.11" [lib] diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 039c19a..c45646c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -58,7 +58,7 @@ mod trans; /// ``` /// /// The initial value of a resource can be omitted. This means that the resource will be runtime -/// initialized. +/// initialized; these runtime initialized resources are also known as *late resources*. /// /// If this key is omitted its value defaults to an empty list. /// @@ -79,6 +79,18 @@ mod trans; /// /// If the key is omitted its value defaults to `init`. /// +/// ## `init.resources` +/// +/// This key is optional. Its value is a set of resources the `init` function *owns*. The resources +/// in this list must be a subset of the resources listed in the top `resources` key. Note that some +/// restrictions apply: +/// +/// - The resources in this list can't be late resources. +/// - The resources that appear in this list can't appear in other list like `idle.resources` or +/// `tasks.$TASK.resources` +/// +/// If this key is omitted its value is assumed to be an empty list. +/// /// # `idle` /// /// This key is optional. Its value is a set of key values. All the possible keys are shown below: @@ -100,9 +112,7 @@ mod trans; /// ## `idle.resources` /// /// This key is optional. Its value is a list of resources the `idle` loop has access to. The -/// resources in this list can refer to the resources listed in the top `resources` key. If the name -/// doesn't match one of the resources /// listed in the top `resources` key the resource is assumed -/// to be a peripheral. +/// resources in this list must be a subset of the resources listed in the top `resources` key. /// /// If omitted its value defaults to an empty list. /// @@ -154,9 +164,7 @@ mod trans; /// ## `tasks.$TASK.resources` /// /// This key is optional. Its value is a list of resources this task has access to. The resources in -/// this list can refer to the resources listed in the top `resources` key. If the name doesn't -/// match one of the resources listed in the top `resources` key the resource is assumed to be a -/// peripheral. +/// this list must be a subset of the resources listed in the top `resources` key. /// /// If omitted its value defaults to an empty list. #[proc_macro] diff --git a/src/examples/_6_generics.rs b/src/examples/_6_generics.rs deleted file mode 100644 index 22bb777..0000000 --- a/src/examples/_6_generics.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! Working with resources in a generic fashion -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![feature(proc_macro)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Resource, Threshold}; -//! use stm32f103xx::{SPI1, GPIOA}; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static GPIOA: GPIOA; -//! static SPI1: SPI1; -//! }, -//! -//! tasks: { -//! EXTI0: { -//! path: exti0, -//! priority: 1, -//! resources: [GPIOA, SPI1], -//! }, -//! -//! EXTI1: { -//! path: exti1, -//! priority: 2, -//! resources: [GPIOA, SPI1], -//! }, -//! }, -//! } -//! -//! fn init(p: init::Peripherals) -> init::LateResources { -//! init::LateResources { -//! GPIOA: p.device.GPIOA, -//! SPI1: p.device.SPI1, -//! } -//! } -//! -//! fn idle() -> ! { -//! loop { -//! rtfm::wfi(); -//! } -//! } -//! -//! // A generic function that uses some resources -//! fn work(t: &mut Threshold, gpioa: &G, spi1: &S) -//! where -//! G: Resource, -//! S: Resource, -//! { -//! gpioa.claim(t, |_gpioa, t| { -//! // drive NSS low -//! -//! spi1.claim(t, |_spi1, _| { -//! // transfer data -//! }); -//! -//! // drive NSS high -//! }); -//! } -//! -//! // This task needs critical sections to access the resources -//! fn exti0(t: &mut Threshold, r: EXTI0::Resources) { -//! work(t, &r.GPIOA, &r.SPI1); -//! } -//! -//! // This task has direct access to the resources -//! fn exti1(t: &mut Threshold, r: EXTI1::Resources) { -//! work(t, &r.GPIOA, &r.SPI1); -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_6_safe_static_mut_ref.rs b/src/examples/_6_safe_static_mut_ref.rs new file mode 100644 index 0000000..32eb3d9 --- /dev/null +++ b/src/examples/_6_safe_static_mut_ref.rs @@ -0,0 +1,36 @@ +//! Safe creation of `&'static mut` references +//! +//! ``` +//! #![deny(unsafe_code)] +//! #![deny(warnings)] +//! #![feature(proc_macro)] +//! #![no_std] +//! +//! extern crate cortex_m_rtfm as rtfm; +//! extern crate stm32f103xx; +//! +//! use rtfm::app; +//! +//! app! { +//! device: stm32f103xx, +//! +//! resources: { +//! static BUFFER: [u8; 16] = [0; 16]; +//! }, +//! +//! init: { +//! resources: [BUFFER], +//! }, +//! } +//! +//! fn init(_p: init::Peripherals, r: init::Resources) { +//! let _buf: &'static mut [u8; 16] = r.BUFFER; +//! } +//! +//! fn idle() -> ! { +//! loop { +//! rtfm::wfi(); +//! } +//! } +//! ``` +// Auto-generated. Do not modify. diff --git a/src/examples/_7_full_syntax.rs b/src/examples/_7_full_syntax.rs deleted file mode 100644 index f8db408..0000000 --- a/src/examples/_7_full_syntax.rs +++ /dev/null @@ -1,88 +0,0 @@ -//! A showcase of the `app!` macro syntax -//! -//! ``` -//! #![deny(unsafe_code)] -//! #![deny(warnings)] -//! #![feature(proc_macro)] -//! #![no_std] -//! -//! extern crate cortex_m_rtfm as rtfm; -//! extern crate stm32f103xx; -//! -//! use rtfm::{app, Threshold}; -//! -//! app! { -//! device: stm32f103xx, -//! -//! resources: { -//! static CO_OWNED: u32 = 0; -//! static ON: bool = false; -//! static OWNED: bool = false; -//! static SHARED: bool = false; -//! }, -//! -//! init: { -//! // This is the path to the `init` function -//! // -//! // `init` doesn't necessarily has to be in the root of the crate -//! path: main::init, -//! }, -//! -//! idle: { -//! // This is a path to the `idle` function -//! // -//! // `idle` doesn't necessarily has to be in the root of the crate -//! path: main::idle, -//! resources: [OWNED, SHARED], -//! }, -//! -//! tasks: { -//! SYS_TICK: { -//! path: sys_tick, -//! // If omitted priority is assumed to be 1 -//! // priority: 1, -//! resources: [CO_OWNED, ON, SHARED], -//! }, -//! -//! TIM2: { -//! // Tasks are enabled, between `init` and `idle`, by default but they -//! // can start disabled if `false` is specified here -//! enabled: false, -//! path: tim2, -//! priority: 1, -//! resources: [CO_OWNED], -//! }, -//! }, -//! } -//! -//! mod main { -//! use rtfm::{self, Resource, Threshold}; -//! -//! pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {} -//! -//! pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! { -//! loop { -//! *r.OWNED != *r.OWNED; -//! -//! if *r.OWNED { -//! if r.SHARED.claim(t, |shared, _| *shared) { -//! rtfm::wfi(); -//! } -//! } else { -//! r.SHARED.claim_mut(t, |shared, _| *shared = !*shared); -//! } -//! } -//! } -//! } -//! -//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) { -//! *r.ON = !*r.ON; -//! -//! *r.CO_OWNED += 1; -//! } -//! -//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) { -//! *r.CO_OWNED += 1; -//! } -//! ``` -// Auto-generated. Do not modify. diff --git a/src/examples/_7_generics.rs b/src/examples/_7_generics.rs new file mode 100644 index 0000000..22bb777 --- /dev/null +++ b/src/examples/_7_generics.rs @@ -0,0 +1,78 @@ +//! Working with resources in a generic fashion +//! +//! ``` +//! #![deny(unsafe_code)] +//! #![deny(warnings)] +//! #![feature(proc_macro)] +//! #![no_std] +//! +//! extern crate cortex_m_rtfm as rtfm; +//! extern crate stm32f103xx; +//! +//! use rtfm::{app, Resource, Threshold}; +//! use stm32f103xx::{SPI1, GPIOA}; +//! +//! app! { +//! device: stm32f103xx, +//! +//! resources: { +//! static GPIOA: GPIOA; +//! static SPI1: SPI1; +//! }, +//! +//! tasks: { +//! EXTI0: { +//! path: exti0, +//! priority: 1, +//! resources: [GPIOA, SPI1], +//! }, +//! +//! EXTI1: { +//! path: exti1, +//! priority: 2, +//! resources: [GPIOA, SPI1], +//! }, +//! }, +//! } +//! +//! fn init(p: init::Peripherals) -> init::LateResources { +//! init::LateResources { +//! GPIOA: p.device.GPIOA, +//! SPI1: p.device.SPI1, +//! } +//! } +//! +//! fn idle() -> ! { +//! loop { +//! rtfm::wfi(); +//! } +//! } +//! +//! // A generic function that uses some resources +//! fn work(t: &mut Threshold, gpioa: &G, spi1: &S) +//! where +//! G: Resource, +//! S: Resource, +//! { +//! gpioa.claim(t, |_gpioa, t| { +//! // drive NSS low +//! +//! spi1.claim(t, |_spi1, _| { +//! // transfer data +//! }); +//! +//! // drive NSS high +//! }); +//! } +//! +//! // This task needs critical sections to access the resources +//! fn exti0(t: &mut Threshold, r: EXTI0::Resources) { +//! work(t, &r.GPIOA, &r.SPI1); +//! } +//! +//! // This task has direct access to the resources +//! fn exti1(t: &mut Threshold, r: EXTI1::Resources) { +//! work(t, &r.GPIOA, &r.SPI1); +//! } +//! ``` +// Auto-generated. Do not modify. diff --git a/src/examples/_8_full_syntax.rs b/src/examples/_8_full_syntax.rs new file mode 100644 index 0000000..f8db408 --- /dev/null +++ b/src/examples/_8_full_syntax.rs @@ -0,0 +1,88 @@ +//! A showcase of the `app!` macro syntax +//! +//! ``` +//! #![deny(unsafe_code)] +//! #![deny(warnings)] +//! #![feature(proc_macro)] +//! #![no_std] +//! +//! extern crate cortex_m_rtfm as rtfm; +//! extern crate stm32f103xx; +//! +//! use rtfm::{app, Threshold}; +//! +//! app! { +//! device: stm32f103xx, +//! +//! resources: { +//! static CO_OWNED: u32 = 0; +//! static ON: bool = false; +//! static OWNED: bool = false; +//! static SHARED: bool = false; +//! }, +//! +//! init: { +//! // This is the path to the `init` function +//! // +//! // `init` doesn't necessarily has to be in the root of the crate +//! path: main::init, +//! }, +//! +//! idle: { +//! // This is a path to the `idle` function +//! // +//! // `idle` doesn't necessarily has to be in the root of the crate +//! path: main::idle, +//! resources: [OWNED, SHARED], +//! }, +//! +//! tasks: { +//! SYS_TICK: { +//! path: sys_tick, +//! // If omitted priority is assumed to be 1 +//! // priority: 1, +//! resources: [CO_OWNED, ON, SHARED], +//! }, +//! +//! TIM2: { +//! // Tasks are enabled, between `init` and `idle`, by default but they +//! // can start disabled if `false` is specified here +//! enabled: false, +//! path: tim2, +//! priority: 1, +//! resources: [CO_OWNED], +//! }, +//! }, +//! } +//! +//! mod main { +//! use rtfm::{self, Resource, Threshold}; +//! +//! pub fn init(_p: ::init::Peripherals, _r: ::init::Resources) {} +//! +//! pub fn idle(t: &mut Threshold, mut r: ::idle::Resources) -> ! { +//! loop { +//! *r.OWNED != *r.OWNED; +//! +//! if *r.OWNED { +//! if r.SHARED.claim(t, |shared, _| *shared) { +//! rtfm::wfi(); +//! } +//! } else { +//! r.SHARED.claim_mut(t, |shared, _| *shared = !*shared); +//! } +//! } +//! } +//! } +//! +//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) { +//! *r.ON = !*r.ON; +//! +//! *r.CO_OWNED += 1; +//! } +//! +//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) { +//! *r.CO_OWNED += 1; +//! } +//! ``` +// Auto-generated. Do not modify. diff --git a/src/examples/mod.rs b/src/examples/mod.rs index 53e74ed..64d1e2e 100644 --- a/src/examples/mod.rs +++ b/src/examples/mod.rs @@ -6,5 +6,6 @@ pub mod _2_two_tasks; pub mod _3_preemption; pub mod _4_nested; pub mod _5_late_resources; -pub mod _6_generics; -pub mod _7_full_syntax; +pub mod _6_safe_static_mut_ref; +pub mod _7_generics; +pub mod _8_full_syntax; diff --git a/src/lib.rs b/src/lib.rs index 697dca6..4f909ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,18 +37,18 @@ //! # Dependencies //! //! The application crate must depend on a device crate generated using -//! [`svd2rust`] v0.11.x and the "rt" feature of that crate must be enabled. The +//! [`svd2rust`] v0.12.x and the "rt" feature of that crate must be enabled. The //! SVD file used to generate the device crate *must* contain [``] //! information. //! -//! [`svd2rust`]: https://docs.rs/svd2rust/0..0/svd2rust/ +//! [`svd2rust`]: https://docs.rs/svd2rust/0.12.0/svd2rust/ //! [``]: https://www.keil.com/pack/doc/CMSIS/SVD/html/elem_cpu.html //! //! # `app!` //! //! The `app!` macro is documented [here]. //! -//! [here]: https://docs.rs/cortex-m-rtfm-macros/0.2.0/cortex_m_rtfm_macros/fn.app.html +//! [here]: https://docs.rs/cortex-m-rtfm-macros/0.2.1/cortex_m_rtfm_macros/fn.app.html //! //! # Important: Cortex-M7 devices //! @@ -90,13 +90,13 @@ extern crate untagged_option; use core::{mem, u8}; pub use cortex_m::asm::{bkpt, wfi}; -pub use cortex_m::peripheral::NVIC; pub use cortex_m_rtfm_macros::app; pub use rtfm_core::{Resource, Threshold}; #[doc(hidden)] pub use untagged_option::UntaggedOption; use cortex_m::interrupt::{self, Nr}; +use cortex_m::peripheral::NVIC; #[cfg(not(armv6m))] use cortex_m::register::basepri; -- cgit v1.2.3