Skip to content

Commit

Permalink
update examples and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
japaric committed Apr 26, 2018
1 parent 8e79d05 commit a35486b
Show file tree
Hide file tree
Showing 19 changed files with 625 additions and 427 deletions.
44 changes: 27 additions & 17 deletions examples/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,60 @@
#![feature(alloc)]
#![feature(global_allocator)]
#![feature(used)]
#![no_main]
#![no_std]

// This is the allocator crate; you can use a different one
extern crate alloc_cortex_m;
#[macro_use]
extern crate alloc;
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate cortex_m_semihosting;
extern crate panic_abort; // panicking behavior
#[macro_use]
extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh;
extern crate panic_abort;

use core::fmt::Write;

use alloc_cortex_m::CortexMHeap;
use cortex_m::asm;
use cortex_m_semihosting::hio;
use rt::ExceptionFrame;
use sh::hio;

#[global_allocator]
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();

extern "C" {
static mut _sheap: u32;
}

const HEAP_SIZE: usize = 1024; // in bytes

fn main() {
main!(main);

fn main() -> ! {
// Initialize the allocator
let start = unsafe { &mut _sheap as *mut u32 as usize };
unsafe { ALLOCATOR.init(start, HEAP_SIZE) }
unsafe { ALLOCATOR.init(rt::heap_start() as usize, HEAP_SIZE) }

// Growable array allocated on the heap
let xs = vec![0, 1, 2];

let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "{:?}", xs).unwrap();

loop {}
}

// As we are not using interrupts, we just register a dummy catch all handler
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
exception!(DefaultHandler, dh);

extern "C" fn default_handler() {
#[inline(always)]
fn dh(_nr: u8) {
asm::bkpt();
}

exception!(HardFault, hf);

#[inline(always)]
fn hf(_ef: &ExceptionFrame) -> ! {
asm::bkpt();

loop {}
}

interrupts!(DefaultHandler);
2 changes: 1 addition & 1 deletion examples/crash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
extern crate cortex_m;
#[macro_use]
extern crate cortex_m_rt as rt;
extern crate panic_abort; // panicking behavior
extern crate panic_abort;

use core::ptr;

Expand Down
108 changes: 55 additions & 53 deletions examples/device.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! Using a device crate
//!
//! Crates generated using [`svd2rust`] are referred to as device crates. These crates provides an
//! API to access the peripherals of a device. When you depend on one of these crates and the "rt"
//! feature is enabled you don't need link to the cortex-m-rt crate.
//! API to access the peripherals of a device.
//!
//! [`svd2rust`]: https://crates.io/crates/svd2rust
//!
//! Device crates also provide an `interrupt!` macro to register interrupt handlers.
//! Device crates also provide an `interrupt!` macro (behind the "rt" feature) to register interrupt
//! handlers.
//!
//! This example depends on the [`stm32f103xx`] crate so you'll have to add it to your Cargo.toml.
//!
Expand All @@ -16,80 +16,82 @@
//! $ edit Cargo.toml && tail $_
//! [dependencies.stm32f103xx]
//! features = ["rt"]
//! version = "0.9.0"
//! version = "0.10.0"
//! ```
//!
//! The `stm32f103xx` crate provides an `interrupts.x` file so you must remove the one in the root
//! of this crate.
//!
//! ---
#![deny(warnings)]
#![feature(const_fn)]
#![no_main]
#![no_std]

extern crate cortex_m;
// extern crate cortex_m_rt; // included in the device crate
extern crate cortex_m_semihosting;
#[macro_use(exception, interrupt)]
#[macro_use]
extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh;
#[macro_use]
extern crate stm32f103xx;
extern crate panic_abort; // panicking behavior
extern crate panic_abort;

use core::cell::RefCell;
use core::fmt::Write;

use cortex_m::interrupt::{self, Mutex};
use cortex_m::asm;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m_semihosting::hio::{self, HStdout};
use rt::ExceptionFrame;
use sh::hio::{self, HStdout};
use stm32f103xx::Interrupt;

static HSTDOUT: Mutex<RefCell<Option<HStdout>>> = Mutex::new(RefCell::new(None));
main!(main);

fn main() -> ! {
let p = cortex_m::Peripherals::take().unwrap();

static NVIC: Mutex<RefCell<Option<cortex_m::peripheral::NVIC>>> = Mutex::new(RefCell::new(None));
let mut syst = p.SYST;
let mut nvic = p.NVIC;

fn main() {
let global_p = cortex_m::Peripherals::take().unwrap();
interrupt::free(|cs| {
let hstdout = HSTDOUT.borrow(cs);
if let Ok(fd) = hio::hstdout() {
*hstdout.borrow_mut() = Some(fd);
}
nvic.enable(Interrupt::EXTI0);

let mut nvic = global_p.NVIC;
nvic.enable(Interrupt::TIM2);
*NVIC.borrow(cs).borrow_mut() = Some(nvic);
syst.set_clock_source(SystClkSource::Core);
syst.set_reload(8_000_000); // 1s
syst.enable_counter();

let mut syst = global_p.SYST;
syst.set_clock_source(SystClkSource::Core);
syst.set_reload(8_000_000); // 1s
syst.enable_counter();
syst.enable_interrupt();
});
loop {
// busy wait until the timer wraps around
while !syst.has_wrapped() {}

// trigger the `EXTI0` interrupt
nvic.set_pending(Interrupt::EXTI0);
}
}

exception!(SYS_TICK, tick);
interrupt!(EXTI0, exti0, state: Option<HStdout> = None);

fn tick() {
interrupt::free(|cs| {
let hstdout = HSTDOUT.borrow(cs);
if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
writeln!(*hstdout, "Tick").ok();
}
fn exti0(state: &mut Option<HStdout>) {
if state.is_none() {
*state = Some(hio::hstdout().unwrap());
}

if let Some(nvic) = NVIC.borrow(cs).borrow_mut().as_mut() {
nvic.set_pending(Interrupt::TIM2);
}
});
if let Some(hstdout) = state.as_mut() {
hstdout.write_str(".").unwrap();
}
}

interrupt!(TIM2, tock, locals: {
tocks: u32 = 0;
});
exception!(DefaultHandler, deh);

fn tock(l: &mut TIM2::Locals) {
l.tocks += 1;
#[inline(always)]
fn deh(_nr: u8) {
asm::bkpt();
}

interrupt::free(|cs| {
let hstdout = HSTDOUT.borrow(cs);
if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
writeln!(*hstdout, "Tock ({})", l.tocks).ok();
}
});
exception!(HardFault, hf);

#[inline(always)]
fn hf(_ef: &ExceptionFrame) -> ! {
asm::bkpt();

loop {}
}

interrupts!(DefaultHandler);
2 changes: 1 addition & 1 deletion examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern crate cortex_m;
#[macro_use]
extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh;
extern crate panic_abort; // panicking behavior
extern crate panic_abort;

use core::fmt::Write;

Expand Down
31 changes: 28 additions & 3 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
//! Minimal Cortex-M program
//!
//! All Cortex-M programs need to:
//!
//! - Contain the `#![no_main]` and `#![no_std]` attributes. Embedded programs don't use the
//! standard Rust `main` interface or the Rust standard (`std`) library.
//!
//! - Define their entry point using `main!`. The entry point doesn't need to be called `main` and
//! it doesn't need to be in the root of the crate.
//!
//! - Define their panicking behavior, i.e. what happens when `panic!` is called. The easiest way to
//! define a panicking behavior is to link to a [panic implementation crate][0]
//!
//! [0]: https://crates.io/keywords/panic-impl
//!
//! - Define the `HardFault` handler. This function is called when a hard fault exception is raised
//! by the hardware.
//!
//! - Define a default handler. This function will be used to handle all interrupts and exceptions
//! which have not been assigned a specific handler.
//!
//! - Define the device specific interrupt handlers. `interrupts!` can be used to create a generic
//! program that works for all Cortex-M devices by binding all the possible interrupt handlers to
//! the `DefaultHandler`.
#![no_main] // <- IMPORTANT!
#![no_std]

extern crate cortex_m;
#[macro_use]
#[macro_use(main, exception, interrupts)]
extern crate cortex_m_rt as rt;
extern crate panic_abort;
extern crate panic_abort; // panicking behavior

use cortex_m::asm;
use rt::ExceptionFrame;

// user entry point
// the program entry point
main!(main);

#[inline(always)]
Expand Down
34 changes: 0 additions & 34 deletions src/examples/_0_hello.rs

This file was deleted.

70 changes: 70 additions & 0 deletions src/examples/_0_minimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//! Minimal Cortex-M program
//!
//! All Cortex-M programs need to:
//!
//! - Contain the `#![no_main]` and `#![no_std]` attributes. Embedded programs don't use the
//! standard Rust `main` interface or the Rust standard (`std`) library.
//!
//! - Define their entry point using `main!`. The entry point doesn't need to be called `main` and
//! it doesn't need to be in the root of the crate.
//!
//! - Define their panicking behavior, i.e. what happens when `panic!` is called. The easiest way to
//! define a panicking behavior is to link to a [panic implementation crate][0]
//!
//! [0]: https://crates.io/keywords/panic-impl
//!
//! - Define the `HardFault` handler. This function is called when a hard fault exception is raised
//! by the hardware.
//!
//! - Define a default handler. This function will be used to handle all interrupts and exceptions
//! which have not been assigned a specific handler.
//!
//! - Define the device specific interrupt handlers. `interrupts!` can be used to create a generic
//! program that works for all Cortex-M devices by binding all the possible interrupt handlers to
//! the `DefaultHandler`.
//!
//! ```
//!
//! #![no_main] // <- IMPORTANT!
//! #![no_std]
//!
//! extern crate cortex_m;
//! #[macro_use(main, exception, interrupts)]
//! extern crate cortex_m_rt as rt;
//! extern crate panic_abort; // panicking behavior
//!
//! use cortex_m::asm;
//! use rt::ExceptionFrame;
//!
//! // the program entry point
//! main!(main);
//!
//! #[inline(always)]
//! fn main() -> ! {
//! asm::bkpt();
//!
//! loop {}
//! }
//!
//! // define the default exception handler
//! exception!(DefaultHandler, deh);
//!
//! #[inline(always)]
//! fn deh(_nr: u8) {
//! asm::bkpt();
//! }
//!
//! // define the hard fault handler
//! exception!(HardFault, hf);
//!
//! #[inline(always)]
//! fn hf(_ef: &ExceptionFrame) -> ! {
//! asm::bkpt();
//!
//! loop {}
//! }
//!
//! // bind all interrupts to the default exception handler
//! interrupts!(DefaultHandler);
//! ```
// Auto-generated. Do not modify.
Loading

0 comments on commit a35486b

Please sign in to comment.