Skip to content
Snippets Groups Projects
Commit 948e1fd0 authored by Jorge Aparicio's avatar Jorge Aparicio
Browse files

v0.2.2

parent c184f91e
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ...@@ -5,6 +5,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] ## [Unreleased]
## [v0.2.2] - 2017-11-22
### Added
- Support for runtime initialized resources ("late" resources).
## [v0.2.1] - 2017-07-29 ## [v0.2.1] - 2017-07-29
### Fixed ### Fixed
...@@ -50,7 +56,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ...@@ -50,7 +56,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Initial release - Initial release
[Unreleased]: https://github.com/japaric/cortex-m-rtfm/compare/v0.2.1...HEAD [Unreleased]: https://github.com/japaric/cortex-m-rtfm/compare/v0.2.2...HEAD
[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.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 [v0.2.0]: https://github.com/japaric/cortex-m-rtfm/compare/v0.1.1...v0.2.0
[v0.1.1]: https://github.com/japaric/cortex-m-rtfm/compare/v0.1.0...v0.1.1 [v0.1.1]: https://github.com/japaric/cortex-m-rtfm/compare/v0.1.0...v0.1.1
...@@ -10,13 +10,13 @@ keywords = ["arm", "cortex-m"] ...@@ -10,13 +10,13 @@ keywords = ["arm", "cortex-m"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
name = "cortex-m-rtfm" name = "cortex-m-rtfm"
repository = "https://github.com/japaric/cortex-m-rtfm" repository = "https://github.com/japaric/cortex-m-rtfm"
version = "0.2.1" version = "0.2.2"
[dependencies] [dependencies]
cortex-m = "0.3.1" cortex-m = "0.3.1"
untagged-option = "0.1.1" untagged-option = "0.1.1"
rtfm-core = "0.1.0" rtfm-core = "0.1.0"
cortex-m-rtfm-macros = { path = "macros" } cortex-m-rtfm-macros = "0.2.1"
[target.'cfg(target_arch = "x86_64")'.dev-dependencies] [target.'cfg(target_arch = "x86_64")'.dev-dependencies]
compiletest_rs = "0.2.8" compiletest_rs = "0.2.8"
......
...@@ -16,19 +16,21 @@ app! { ...@@ -16,19 +16,21 @@ app! {
// Usually, resources are initialized with a constant initializer: // Usually, resources are initialized with a constant initializer:
static ON: bool = false; static ON: bool = false;
// However, there are cases where this is not possible or not desired. For example, there // However, there are cases where this is not possible or not desired.
// may not be a sensible value to use, or the type may not be constructible in a constant // For example, there may not be a sensible value to use, or the type may
// (like `Vec`). // not be constructible in a constant (like `Vec`).
// While it is possible to use an `Option` in some cases, that requires you to properly
// initialize it and `.unwrap()` it at every use. It also consumes more memory.
// //
// To solve this, it is possible to defer initialization of resources to `init` by omitting // While it is possible to use an `Option` in some cases, that requires
// the initializer. Doing that will require `init` to return the values of all "late" // you to properly initialize it and `.unwrap()` it at every use. It
// resources. // also consumes more memory.
//
// To solve this, it is possible to defer initialization of resources to
// `init` by omitting the initializer. Doing that will require `init` to
// return the values of all "late" resources.
static IP_ADDRESS: u32; static IP_ADDRESS: u32;
// PORT is used by 2 tasks, making it a shared resource. This just tests another internal // PORT is used by 2 tasks, making it a shared resource. This just tests
// code path and is not important for the example. // another internal code path and is not important for the example.
static PORT: u16; static PORT: u16;
}, },
...@@ -54,22 +56,24 @@ app! { ...@@ -54,22 +56,24 @@ app! {
// The signature of `init` is now required to have a specific return type. // The signature of `init` is now required to have a specific return type.
fn init(_p: init::Peripherals, _r: init::Resources) -> init::LateResourceValues { fn init(_p: init::Peripherals, _r: init::Resources) -> init::LateResourceValues {
// `init::Resources` does not contain `IP_ADDRESS`, since it is not yet initialized. // `init::Resources` does not contain `IP_ADDRESS`, since it is not yet
// initialized.
//_r.IP_ADDRESS; // doesn't compile //_r.IP_ADDRESS; // doesn't compile
// ...obtain value for IP_ADDRESS from EEPROM/DHCP... // ...obtain value for IP_ADDRESS from EEPROM/DHCP...
let ip_address = 0x7f000001; let ip_address = 0x7f000001;
init::LateResourceValues { init::LateResourceValues {
// This struct will contain fields for all resources with omitted initializers. // This struct will contain fields for all resources with omitted
// initializers.
IP_ADDRESS: ip_address, IP_ADDRESS: ip_address,
PORT: 0, PORT: 0,
} }
} }
fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) { fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
// Other tasks can access late resources like any other, since they are guaranteed to be // Other tasks can access late resources like any other, since they are
// initialized when tasks are run. // guaranteed to be initialized when tasks are run.
r.IP_ADDRESS; r.IP_ADDRESS;
} }
......
...@@ -10,6 +10,7 @@ main() { ...@@ -10,6 +10,7 @@ main() {
two-tasks two-tasks
preemption preemption
nested nested
late-resources
generics generics
full-syntax full-syntax
) )
......
...@@ -7,7 +7,7 @@ keywords = ["arm", "cortex-m"] ...@@ -7,7 +7,7 @@ keywords = ["arm", "cortex-m"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
name = "cortex-m-rtfm-macros" name = "cortex-m-rtfm-macros"
repository = "https://github.com/japaric/cortex-m-rtfm" repository = "https://github.com/japaric/cortex-m-rtfm"
version = "0.2.0" version = "0.2.1"
[dependencies] [dependencies]
error-chain = "0.10.0" error-chain = "0.10.0"
......
...@@ -19,11 +19,9 @@ mod analyze; ...@@ -19,11 +19,9 @@ mod analyze;
mod check; mod check;
mod trans; mod trans;
/// The `app!` macro, a macro used to specify the tasks and resources of a /// The `app!` macro, a macro used to specify the tasks and resources of a RTFM application.
/// RTFM application.
/// ///
/// The contents of this macro uses a `key: value` syntax. All the possible keys /// The contents of this macro uses a `key: value` syntax. All the possible keys are shown below:
/// are shown below:
/// ///
/// ``` text /// ``` text
/// app! { /// app! {
...@@ -41,14 +39,13 @@ mod trans; ...@@ -41,14 +39,13 @@ mod trans;
/// ///
/// # `device` /// # `device`
/// ///
/// The value of this key is a Rust path, like `foo::bar::baz`, that must point to /// The value of this key is a Rust path, like `foo::bar::baz`, that must point to a *device crate*,
/// a *device crate*, a crate generated using `svd2rust`. /// a crate generated using `svd2rust`.
/// ///
/// # `resources` /// # `resources`
/// ///
/// This key is optional. Its value is a list of `static` variables. These /// This key is optional. Its value is a list of `static` variables. These variables are the data
/// variables are the data that can be safely accessed, modified and shared by /// that can be safely accessed, modified and shared by tasks.
/// tasks.
/// ///
/// ``` text /// ``` text
/// resources: { /// resources: {
...@@ -56,15 +53,18 @@ mod trans; ...@@ -56,15 +53,18 @@ mod trans;
/// static B: i32 = 0; /// static B: i32 = 0;
/// static C: [u8; 16] = [0; 16]; /// static C: [u8; 16] = [0; 16];
/// static D: Thing = Thing::new(..); /// static D: Thing = Thing::new(..);
/// static E: Thing;
/// } /// }
/// ``` /// ```
/// ///
/// The initial value of a resource can be omitted. This means that the resource will be runtime
/// initialized.
///
/// If this key is omitted its value defaults to an empty list. /// If this key is omitted its value defaults to an empty list.
/// ///
/// # `init` /// # `init`
/// ///
/// This key is optional. Its value is a set of key values. All the possible /// This key is optional. Its value is a set of key values. All the possible keys are shown below:
/// keys are shown below:
/// ///
/// ``` text /// ``` text
/// init: { /// init: {
...@@ -74,15 +74,14 @@ mod trans; ...@@ -74,15 +74,14 @@ mod trans;
/// ///
/// ## `init.path` /// ## `init.path`
/// ///
/// This key is optional. Its value is a Rust path, like `foo::bar::baz`, that /// This key is optional. Its value is a Rust path, like `foo::bar::baz`, that points to the
/// points to the initialization function. /// initialization function.
/// ///
/// If the key is omitted its value defaults to `init`. /// If the key is omitted its value defaults to `init`.
/// ///
/// # `idle` /// # `idle`
/// ///
/// This key is optional. Its value is a set of key values. All the possible /// This key is optional. Its value is a set of key values. All the possible keys are shown below:
/// keys are shown below:
/// ///
/// ``` text /// ``` text
/// idle: { /// idle: {
...@@ -93,25 +92,24 @@ mod trans; ...@@ -93,25 +92,24 @@ mod trans;
/// ///
/// ## `idle.path` /// ## `idle.path`
/// ///
/// This key is optional. Its value is a Rust path, like `foo::bar::baz`, that /// This key is optional. Its value is a Rust path, like `foo::bar::baz`, that points to the idle
/// points to the idle loop function. /// loop function.
/// ///
/// If the key is omitted its value defaults to `idle`. /// If the key is omitted its value defaults to `idle`.
/// ///
/// ## `idle.resources` /// ## `idle.resources`
/// ///
/// This key is optional. Its value is a list of resources the `idle` loop has /// This key is optional. Its value is a list of resources the `idle` loop has access to. The
/// access to. The resources in this list can refer to the resources listed in /// resources in this list can refer to the resources listed in the top `resources` key. If the name
/// the top `resources` key. If the name doesn't match one of the resources /// doesn't match one of the resources /// listed in the top `resources` key the resource is assumed
/// listed in the top `resources` key the resource is assumed to be a /// to be a peripheral.
/// peripheral.
/// ///
/// If omitted its value defaults to an empty list. /// If omitted its value defaults to an empty list.
/// ///
/// # `tasks` /// # `tasks`
/// ///
/// This key is optional. Its value is a list of tasks. Each task itself is a /// This key is optional. Its value is a list of tasks. Each task itself is a set of key value pair.
/// set of key value pair. The full syntax is shown below: /// The full syntax is shown below:
/// ///
/// ``` text /// ``` text
/// tasks: { /// tasks: {
...@@ -128,39 +126,37 @@ mod trans; ...@@ -128,39 +126,37 @@ mod trans;
/// ///
/// ## `tasks.$TASK` /// ## `tasks.$TASK`
/// ///
/// The key must be either a Cortex-M exception or a device specific interrupt. /// The key must be either a Cortex-M exception or a device specific interrupt. `PENDSV`, `SVCALL`,
/// `PENDSV`, `SVCALL`, `SYS_TICK` are considered as exceptions. All other names /// `SYS_TICK` are considered as exceptions. All other names are assumed to be interrupts.
/// are assumed to be interrupts.
/// ///
/// ## `tasks.$TASK.enabled` /// ## `tasks.$TASK.enabled`
/// ///
/// This key is optional for interrupts and forbidden for exceptions. Its value /// This key is optional for interrupts and forbidden for exceptions. Its value must be a boolean
/// must be a boolean and indicates whether the interrupt will be enabled /// and indicates whether the interrupt will be enabled (`true`) or disabled (`false`) after `init`
/// (`true`) or disabled (`false`) after `init` ends and before `idle` starts. /// ends and before `idle` starts.
/// ///
/// If this key is omitted its value defaults to `true`. /// If this key is omitted its value defaults to `true`.
/// ///
/// ## `tasks.$TASK.path` /// ## `tasks.$TASK.path`
/// ///
/// The value of this key is a Rust path, like `foo::bar::baz`, that points to /// The value of this key is a Rust path, like `foo::bar::baz`, that points to the handler of this
/// the handler of this task. /// task.
/// ///
/// ## `tasks.$TASK.priority` /// ## `tasks.$TASK.priority`
/// ///
/// This key is optional. Its value is an integer with type `u8` that specifies /// This key is optional. Its value is an integer with type `u8` that specifies the priority of this
/// the priority of this task. The minimum valid priority is 1. The maximum /// task. The minimum valid priority is 1. The maximum valid priority depends on the number of the
/// valid priority depends on the number of the NVIC priority bits the device /// NVIC priority bits the device has; if the device has 4 priority bits the maximum allowed value
/// has; if the device has 4 priority bits the maximum allowed value would be /// would be 16.
/// 16.
/// ///
/// If this key is omitted its value defaults to `1`. /// If this key is omitted its value defaults to `1`.
/// ///
/// ## `tasks.$TASK.resources` /// ## `tasks.$TASK.resources`
/// ///
/// This key is optional. Its value is a list of resources this task has access /// This key is optional. Its value is a list of resources this task has access to. The resources in
/// to. The resources in this list can refer to the resources listed in the top /// this list can refer to the resources listed in the top `resources` key. If the name doesn't
/// `resources` key. If the name doesn't match one of the resources listed in /// match one of the resources listed in the top `resources` key the resource is assumed to be a
/// the top `resources` key the resource is assumed to be a peripheral. /// peripheral.
/// ///
/// If omitted its value defaults to an empty list. /// If omitted its value defaults to an empty list.
#[proc_macro] #[proc_macro]
......
//! Demonstrates initialization of resources in `init`.
//!
//! ```
//!
//! #![deny(unsafe_code)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
//! extern crate cortex_m_rtfm as rtfm;
//! extern crate stm32f103xx;
//!
//! use rtfm::{app, Threshold};
//!
//! app! {
//! device: stm32f103xx,
//!
//! resources: {
//! // Usually, resources are initialized with a constant initializer:
//! static ON: bool = false;
//!
//! // However, there are cases where this is not possible or not desired.
//! // For example, there may not be a sensible value to use, or the type may
//! // not be constructible in a constant (like `Vec`).
//! //
//! // While it is possible to use an `Option` in some cases, that requires
//! // you to properly initialize it and `.unwrap()` it at every use. It
//! // also consumes more memory.
//! //
//! // To solve this, it is possible to defer initialization of resources to
//! // `init` by omitting the initializer. Doing that will require `init` to
//! // return the values of all "late" resources.
//! static IP_ADDRESS: u32;
//!
//! // PORT is used by 2 tasks, making it a shared resource. This just tests
//! // another internal code path and is not important for the example.
//! static PORT: u16;
//! },
//!
//! idle: {
//! // Test that late resources can be used in idle
//! resources: [IP_ADDRESS],
//! },
//!
//! tasks: {
//! SYS_TICK: {
//! priority: 1,
//! path: sys_tick,
//! resources: [IP_ADDRESS, PORT, ON],
//! },
//!
//! EXTI0: {
//! priority: 2,
//! path: exti0,
//! resources: [PORT],
//! }
//! }
//! }
//!
//! // The signature of `init` is now required to have a specific return type.
//! fn init(_p: init::Peripherals, _r: init::Resources) -> init::LateResourceValues {
//! // `init::Resources` does not contain `IP_ADDRESS`, since it is not yet
//! // initialized.
//! //_r.IP_ADDRESS; // doesn't compile
//!
//! // ...obtain value for IP_ADDRESS from EEPROM/DHCP...
//! let ip_address = 0x7f000001;
//!
//! init::LateResourceValues {
//! // This struct will contain fields for all resources with omitted
//! // initializers.
//! IP_ADDRESS: ip_address,
//! PORT: 0,
//! }
//! }
//!
//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
//! // Other tasks can access late resources like any other, since they are
//! // guaranteed to be initialized when tasks are run.
//!
//! r.IP_ADDRESS;
//! }
//!
//! fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {}
//!
//! fn idle(_t: &mut Threshold, _r: idle::Resources) -> ! {
//! loop {
//! rtfm::wfi();
//! }
//! }
//! ```
// Auto-generated. Do not modify.
File moved
File moved
...@@ -5,5 +5,6 @@ pub mod _1_one_task; ...@@ -5,5 +5,6 @@ pub mod _1_one_task;
pub mod _2_two_tasks; pub mod _2_two_tasks;
pub mod _3_preemption; pub mod _3_preemption;
pub mod _4_nested; pub mod _4_nested;
pub mod _5_generics; pub mod _5_late_resources;
pub mod _6_full_syntax; pub mod _6_generics;
pub mod _7_full_syntax;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment