Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • KLEE/cortex-m-rtfm-klee
  • grammers/cortex-m-rtfm-klee
2 results
Select Git revision
Loading items
Show changes
Commits on Source (12)
Showing
with 167 additions and 69 deletions
......@@ -5,6 +5,33 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
## [v0.3.1] - 2018-01-16
### Fixed
- Documentation link
## [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 +83,9 @@ 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.1...HEAD
[v0.3.1]: https://github.com/japaric/cortex-m-rtfm/compare/v0.3.0...v0.3.1
[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
......
......@@ -10,27 +10,24 @@ keywords = ["arm", "cortex-m"]
license = "MIT OR Apache-2.0"
name = "cortex-m-rtfm"
repository = "https://github.com/japaric/cortex-m-rtfm"
version = "0.3.0"
version = "0.3.1"
[dependencies]
cortex-m = { git = "https://github.com/japaric/cortex-m" }
cortex-m = "0.4.0"
cortex-m-rtfm-macros = { path = "macros", version = "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.4"
compiletest_rs = { git = "https://github.com/dwrensha/compiletest-rs", branch = "rustup" }
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"]
......
......@@ -43,7 +43,7 @@ app! {
}
}
fn init(p: init::Peripherals, r: init::Resources) {
fn init(mut p: init::Peripherals, r: init::Resources) {
// `init` can modify all the `resources` declared in `app!`
r.ON;
......
......@@ -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() -> ! {
......
......@@ -11,6 +11,7 @@ main() {
preemption
nested
late-resources
safe-static-mut-ref
generics
full-syntax
)
......
......@@ -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]
......
......@@ -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]
......
......@@ -370,10 +370,10 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
});
}
Kind::Interrupt { enabled } => {
// Interrupt. These can be enabled / disabled through the NVIC
// Interrupt. These are enabled / disabled through the NVIC
if interrupts.is_empty() {
interrupts.push(quote! {
let nvic = &*#device::NVIC::ptr();
let mut nvic: #device::NVIC = core::mem::transmute(());
});
}
......
......@@ -2,6 +2,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! // IMPORTANT always include this feature gate
//! #![feature(proc_macro)]
//! #![no_std]
......@@ -27,8 +28,9 @@
//! // this function.
//! fn init(p: init::Peripherals) {
//! // This function has access to all the peripherals of the device
//! p.GPIOA;
//! p.RCC;
//! p.core.SYST;
//! p.device.GPIOA;
//! p.device.RCC;
//! // ..
//! }
//!
......
......@@ -2,6 +2,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......@@ -9,8 +10,9 @@
//! extern crate cortex_m_rtfm as rtfm;
//! extern crate stm32f103xx;
//!
//! use cortex_m::peripheral::SystClkSource;
//! use cortex_m::peripheral::syst::SystClkSource;
//! use rtfm::{app, Threshold};
//! use stm32f103xx::GPIOC;
//!
//! app! {
//! device: stm32f103xx,
......@@ -37,31 +39,31 @@
//!
//! // These are the resources this task has access to.
//! //
//! // A resource can be a peripheral like `GPIOC` or a static variable
//! // like `ON`
//! resources: [GPIOC, ON],
//! // The resources listed here must also appear in `app.resources`
//! resources: [ON],
//! },
//! }
//! }
//!
//! fn init(p: init::Peripherals, r: init::Resources) {
//! fn init(mut p: init::Peripherals, r: init::Resources) {
//! // `init` can modify all the `resources` declared in `app!`
//! r.ON;
//!
//! // power on GPIOC
//! p.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
//! p.device.RCC.apb2enr.modify(|_, w| w.iopcen().enabled());
//!
//! // configure PC13 as output
//! p.GPIOC.bsrr.write(|w| w.bs13().set());
//! p.GPIOC
//! p.device.GPIOC.bsrr.write(|w| w.bs13().set());
//! p.device
//! .GPIOC
//! .crh
//! .modify(|_, w| w.mode13().output().cnf13().push());
//!
//! // configure the system timer to generate one interrupt every second
//! p.SYST.set_clock_source(SystClkSource::Core);
//! p.SYST.set_reload(8_000_000); // 1s
//! p.SYST.enable_interrupt();
//! p.SYST.enable_counter();
//! p.core.SYST.set_clock_source(SystClkSource::Core);
//! p.core.SYST.set_reload(8_000_000); // 1s
//! p.core.SYST.enable_interrupt();
//! p.core.SYST.enable_counter();
//! }
//!
//! fn idle() -> ! {
......@@ -76,16 +78,23 @@
//! //
//! // `r` is the set of resources this task has access to. `SYS_TICK::Resources`
//! // has one field per resource declared in `app!`.
//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
//! #[allow(unsafe_code)]
//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
//! // toggle state
//! **r.ON = !**r.ON;
//! *r.ON = !*r.ON;
//!
//! if **r.ON {
//! if *r.ON {
//! // set the pin PC13 high
//! r.GPIOC.bsrr.write(|w| w.bs13().set());
//! // NOTE(unsafe) atomic write to a stateless register
//! unsafe {
//! (*GPIOC::ptr()).bsrr.write(|w| w.bs13().set());
//! }
//! } else {
//! // set the pin PC13 low
//! r.GPIOC.bsrr.write(|w| w.br13().reset());
//! // NOTE(unsafe) atomic write to a stateless register
//! unsafe {
//! (*GPIOC::ptr()).bsrr.write(|w| w.br13().reset());
//! }
//! }
//! }
//! ```
......
......@@ -2,6 +2,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......@@ -43,18 +44,18 @@
//!
//! // As both tasks are running at the same priority one can't preempt the other.
//! // Thus both tasks have direct access to the resource
//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
//! // ..
//!
//! **r.COUNTER += 1;
//! *r.COUNTER += 1;
//!
//! // ..
//! }
//!
//! fn tim2(_t: &mut Threshold, r: TIM2::Resources) {
//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) {
//! // ..
//!
//! **r.COUNTER += 1;
//! *r.COUNTER += 1;
//!
//! // ..
//! }
......
......@@ -2,6 +2,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......@@ -43,12 +44,12 @@
//! }
//! }
//!
//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
//! // ..
//!
//! // This task can't be preempted by `tim2` so it has direct access to the
//! // resource data
//! **r.COUNTER += 1;
//! *r.COUNTER += 1;
//!
//! // ..
//! }
......@@ -62,7 +63,7 @@
//! // lead to undefined behavior.
//! r.COUNTER.claim_mut(t, |counter, _t| {
//! // `claim_mut` creates a critical section
//! **counter += 1;
//! *counter += 1;
//! });
//!
//! // ..
......
......@@ -5,6 +5,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......
//! Demonstrates initialization of resources in `init`.
//!
//! ```
//!
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......
//! 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.
......@@ -2,6 +2,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......@@ -14,6 +15,11 @@
//! app! {
//! device: stm32f103xx,
//!
//! resources: {
//! static GPIOA: GPIOA;
//! static SPI1: SPI1;
//! },
//!
//! tasks: {
//! EXTI0: {
//! path: exti0,
......@@ -29,7 +35,12 @@
//! },
//! }
//!
//! fn init(_p: init::Peripherals) {}
//! fn init(p: init::Peripherals) -> init::LateResources {
//! init::LateResources {
//! GPIOA: p.device.GPIOA,
//! SPI1: p.device.SPI1,
//! }
//! }
//!
//! fn idle() -> ! {
//! loop {
......@@ -61,7 +72,7 @@
//!
//! // This task has direct access to the resources
//! fn exti1(t: &mut Threshold, r: EXTI1::Resources) {
//! work(t, r.GPIOA, r.SPI1);
//! work(t, &r.GPIOA, &r.SPI1);
//! }
//! ```
// Auto-generated. Do not modify.
......@@ -2,6 +2,7 @@
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
......@@ -64,24 +65,24 @@
//! *r.OWNED != *r.OWNED;
//!
//! if *r.OWNED {
//! if r.SHARED.claim(t, |shared, _| **shared) {
//! if r.SHARED.claim(t, |shared, _| *shared) {
//! rtfm::wfi();
//! }
//! } else {
//! r.SHARED.claim_mut(t, |shared, _| **shared = !**shared);
//! r.SHARED.claim_mut(t, |shared, _| *shared = !*shared);
//! }
//! }
//! }
//! }
//!
//! fn sys_tick(_t: &mut Threshold, r: SYS_TICK::Resources) {
//! **r.ON = !**r.ON;
//! fn sys_tick(_t: &mut Threshold, mut r: SYS_TICK::Resources) {
//! *r.ON = !*r.ON;
//!
//! **r.CO_OWNED += 1;
//! *r.CO_OWNED += 1;
//! }
//!
//! fn tim2(_t: &mut Threshold, r: TIM2::Resources) {
//! **r.CO_OWNED += 1;
//! fn tim2(_t: &mut Threshold, mut r: TIM2::Resources) {
//! *r.CO_OWNED += 1;
//! }
//! ```
// Auto-generated. Do not modify.
......@@ -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;
......@@ -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 [`<cpu>`]
//! information.
//!
//! [`svd2rust`]: https://docs.rs/svd2rust/0..0/svd2rust/
//! [`svd2rust`]: https://docs.rs/svd2rust/0.12.0/svd2rust/
//! [`<cpu>`]: 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.3.0/cortex_m_rtfm_macros/fn.app.html
//!
//! # Important: Cortex-M7 devices
//!
......@@ -87,15 +87,16 @@ extern crate cortex_m_rtfm_macros;
extern crate rtfm_core;
extern crate untagged_option;
use core::u8;
use core::{mem, u8};
pub use rtfm_core::{Resource, Threshold};
pub use cortex_m::asm::{bkpt, wfi};
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;
......@@ -165,6 +166,6 @@ where
I: Nr,
{
// NOTE(safe) atomic write
let nvic = unsafe { &*cortex_m::peripheral::NVIC::ptr() };
let mut nvic: NVIC = unsafe { mem::transmute(()) };
nvic.set_pending(interrupt);
}