Skip to content

Commit a35486b

Browse files
committed
update examples and docs
1 parent 8e79d05 commit a35486b

19 files changed

+625
-427
lines changed

examples/allocator.rs

+27-17
Original file line numberDiff line numberDiff line change
@@ -11,50 +11,60 @@
1111
1212
#![feature(alloc)]
1313
#![feature(global_allocator)]
14-
#![feature(used)]
14+
#![no_main]
1515
#![no_std]
1616

1717
// This is the allocator crate; you can use a different one
1818
extern crate alloc_cortex_m;
1919
#[macro_use]
2020
extern crate alloc;
2121
extern crate cortex_m;
22-
extern crate cortex_m_rt;
23-
extern crate cortex_m_semihosting;
24-
extern crate panic_abort; // panicking behavior
22+
#[macro_use]
23+
extern crate cortex_m_rt as rt;
24+
extern crate cortex_m_semihosting as sh;
25+
extern crate panic_abort;
2526

2627
use core::fmt::Write;
2728

2829
use alloc_cortex_m::CortexMHeap;
2930
use cortex_m::asm;
30-
use cortex_m_semihosting::hio;
31+
use rt::ExceptionFrame;
32+
use sh::hio;
3133

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

35-
extern "C" {
36-
static mut _sheap: u32;
37-
}
38-
3937
const HEAP_SIZE: usize = 1024; // in bytes
4038

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

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

4948
let mut stdout = hio::hstdout().unwrap();
5049
writeln!(stdout, "{:?}", xs).unwrap();
50+
51+
loop {}
5152
}
5253

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

58-
extern "C" fn default_handler() {
56+
#[inline(always)]
57+
fn dh(_nr: u8) {
5958
asm::bkpt();
6059
}
60+
61+
exception!(HardFault, hf);
62+
63+
#[inline(always)]
64+
fn hf(_ef: &ExceptionFrame) -> ! {
65+
asm::bkpt();
66+
67+
loop {}
68+
}
69+
70+
interrupts!(DefaultHandler);

examples/crash.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
extern crate cortex_m;
7575
#[macro_use]
7676
extern crate cortex_m_rt as rt;
77-
extern crate panic_abort; // panicking behavior
77+
extern crate panic_abort;
7878

7979
use core::ptr;
8080

examples/device.rs

+55-53
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! Using a device crate
22
//!
33
//! Crates generated using [`svd2rust`] are referred to as device crates. These crates provides an
4-
//! API to access the peripherals of a device. When you depend on one of these crates and the "rt"
5-
//! feature is enabled you don't need link to the cortex-m-rt crate.
4+
//! API to access the peripherals of a device.
65
//!
76
//! [`svd2rust`]: https://crates.io/crates/svd2rust
87
//!
9-
//! Device crates also provide an `interrupt!` macro to register interrupt handlers.
8+
//! Device crates also provide an `interrupt!` macro (behind the "rt" feature) to register interrupt
9+
//! handlers.
1010
//!
1111
//! This example depends on the [`stm32f103xx`] crate so you'll have to add it to your Cargo.toml.
1212
//!
@@ -16,80 +16,82 @@
1616
//! $ edit Cargo.toml && tail $_
1717
//! [dependencies.stm32f103xx]
1818
//! features = ["rt"]
19-
//! version = "0.9.0"
19+
//! version = "0.10.0"
2020
//! ```
2121
//!
22+
//! The `stm32f103xx` crate provides an `interrupts.x` file so you must remove the one in the root
23+
//! of this crate.
24+
//!
2225
//! ---
2326
24-
#![deny(warnings)]
25-
#![feature(const_fn)]
27+
#![no_main]
2628
#![no_std]
2729

2830
extern crate cortex_m;
29-
// extern crate cortex_m_rt; // included in the device crate
30-
extern crate cortex_m_semihosting;
31-
#[macro_use(exception, interrupt)]
31+
#[macro_use]
32+
extern crate cortex_m_rt as rt;
33+
extern crate cortex_m_semihosting as sh;
34+
#[macro_use]
3235
extern crate stm32f103xx;
33-
extern crate panic_abort; // panicking behavior
36+
extern crate panic_abort;
3437

35-
use core::cell::RefCell;
3638
use core::fmt::Write;
3739

38-
use cortex_m::interrupt::{self, Mutex};
40+
use cortex_m::asm;
3941
use cortex_m::peripheral::syst::SystClkSource;
40-
use cortex_m_semihosting::hio::{self, HStdout};
42+
use rt::ExceptionFrame;
43+
use sh::hio::{self, HStdout};
4144
use stm32f103xx::Interrupt;
4245

43-
static HSTDOUT: Mutex<RefCell<Option<HStdout>>> = Mutex::new(RefCell::new(None));
46+
main!(main);
47+
48+
fn main() -> ! {
49+
let p = cortex_m::Peripherals::take().unwrap();
4450

45-
static NVIC: Mutex<RefCell<Option<cortex_m::peripheral::NVIC>>> = Mutex::new(RefCell::new(None));
51+
let mut syst = p.SYST;
52+
let mut nvic = p.NVIC;
4653

47-
fn main() {
48-
let global_p = cortex_m::Peripherals::take().unwrap();
49-
interrupt::free(|cs| {
50-
let hstdout = HSTDOUT.borrow(cs);
51-
if let Ok(fd) = hio::hstdout() {
52-
*hstdout.borrow_mut() = Some(fd);
53-
}
54+
nvic.enable(Interrupt::EXTI0);
5455

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

59-
let mut syst = global_p.SYST;
60-
syst.set_clock_source(SystClkSource::Core);
61-
syst.set_reload(8_000_000); // 1s
62-
syst.enable_counter();
63-
syst.enable_interrupt();
64-
});
60+
loop {
61+
// busy wait until the timer wraps around
62+
while !syst.has_wrapped() {}
63+
64+
// trigger the `EXTI0` interrupt
65+
nvic.set_pending(Interrupt::EXTI0);
66+
}
6567
}
6668

67-
exception!(SYS_TICK, tick);
69+
interrupt!(EXTI0, exti0, state: Option<HStdout> = None);
6870

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

76-
if let Some(nvic) = NVIC.borrow(cs).borrow_mut().as_mut() {
77-
nvic.set_pending(Interrupt::TIM2);
78-
}
79-
});
76+
if let Some(hstdout) = state.as_mut() {
77+
hstdout.write_str(".").unwrap();
78+
}
8079
}
8180

82-
interrupt!(TIM2, tock, locals: {
83-
tocks: u32 = 0;
84-
});
81+
exception!(DefaultHandler, deh);
8582

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

89-
interrupt::free(|cs| {
90-
let hstdout = HSTDOUT.borrow(cs);
91-
if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
92-
writeln!(*hstdout, "Tock ({})", l.tocks).ok();
93-
}
94-
});
88+
exception!(HardFault, hf);
89+
90+
#[inline(always)]
91+
fn hf(_ef: &ExceptionFrame) -> ! {
92+
asm::bkpt();
93+
94+
loop {}
9595
}
96+
97+
interrupts!(DefaultHandler);

examples/hello.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ extern crate cortex_m;
99
#[macro_use]
1010
extern crate cortex_m_rt as rt;
1111
extern crate cortex_m_semihosting as sh;
12-
extern crate panic_abort; // panicking behavior
12+
extern crate panic_abort;
1313

1414
use core::fmt::Write;
1515

examples/minimal.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,40 @@
1+
//! Minimal Cortex-M program
2+
//!
3+
//! All Cortex-M programs need to:
4+
//!
5+
//! - Contain the `#![no_main]` and `#![no_std]` attributes. Embedded programs don't use the
6+
//! standard Rust `main` interface or the Rust standard (`std`) library.
7+
//!
8+
//! - Define their entry point using `main!`. The entry point doesn't need to be called `main` and
9+
//! it doesn't need to be in the root of the crate.
10+
//!
11+
//! - Define their panicking behavior, i.e. what happens when `panic!` is called. The easiest way to
12+
//! define a panicking behavior is to link to a [panic implementation crate][0]
13+
//!
14+
//! [0]: https://crates.io/keywords/panic-impl
15+
//!
16+
//! - Define the `HardFault` handler. This function is called when a hard fault exception is raised
17+
//! by the hardware.
18+
//!
19+
//! - Define a default handler. This function will be used to handle all interrupts and exceptions
20+
//! which have not been assigned a specific handler.
21+
//!
22+
//! - Define the device specific interrupt handlers. `interrupts!` can be used to create a generic
23+
//! program that works for all Cortex-M devices by binding all the possible interrupt handlers to
24+
//! the `DefaultHandler`.
25+
126
#![no_main] // <- IMPORTANT!
227
#![no_std]
328

429
extern crate cortex_m;
5-
#[macro_use]
30+
#[macro_use(main, exception, interrupts)]
631
extern crate cortex_m_rt as rt;
7-
extern crate panic_abort;
32+
extern crate panic_abort; // panicking behavior
833

934
use cortex_m::asm;
1035
use rt::ExceptionFrame;
1136

12-
// user entry point
37+
// the program entry point
1338
main!(main);
1439

1540
#[inline(always)]

src/examples/_0_hello.rs

-34
This file was deleted.

src/examples/_0_minimal.rs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//! Minimal Cortex-M program
2+
//!
3+
//! All Cortex-M programs need to:
4+
//!
5+
//! - Contain the `#![no_main]` and `#![no_std]` attributes. Embedded programs don't use the
6+
//! standard Rust `main` interface or the Rust standard (`std`) library.
7+
//!
8+
//! - Define their entry point using `main!`. The entry point doesn't need to be called `main` and
9+
//! it doesn't need to be in the root of the crate.
10+
//!
11+
//! - Define their panicking behavior, i.e. what happens when `panic!` is called. The easiest way to
12+
//! define a panicking behavior is to link to a [panic implementation crate][0]
13+
//!
14+
//! [0]: https://crates.io/keywords/panic-impl
15+
//!
16+
//! - Define the `HardFault` handler. This function is called when a hard fault exception is raised
17+
//! by the hardware.
18+
//!
19+
//! - Define a default handler. This function will be used to handle all interrupts and exceptions
20+
//! which have not been assigned a specific handler.
21+
//!
22+
//! - Define the device specific interrupt handlers. `interrupts!` can be used to create a generic
23+
//! program that works for all Cortex-M devices by binding all the possible interrupt handlers to
24+
//! the `DefaultHandler`.
25+
//!
26+
//! ```
27+
//!
28+
//! #![no_main] // <- IMPORTANT!
29+
//! #![no_std]
30+
//!
31+
//! extern crate cortex_m;
32+
//! #[macro_use(main, exception, interrupts)]
33+
//! extern crate cortex_m_rt as rt;
34+
//! extern crate panic_abort; // panicking behavior
35+
//!
36+
//! use cortex_m::asm;
37+
//! use rt::ExceptionFrame;
38+
//!
39+
//! // the program entry point
40+
//! main!(main);
41+
//!
42+
//! #[inline(always)]
43+
//! fn main() -> ! {
44+
//! asm::bkpt();
45+
//!
46+
//! loop {}
47+
//! }
48+
//!
49+
//! // define the default exception handler
50+
//! exception!(DefaultHandler, deh);
51+
//!
52+
//! #[inline(always)]
53+
//! fn deh(_nr: u8) {
54+
//! asm::bkpt();
55+
//! }
56+
//!
57+
//! // define the hard fault handler
58+
//! exception!(HardFault, hf);
59+
//!
60+
//! #[inline(always)]
61+
//! fn hf(_ef: &ExceptionFrame) -> ! {
62+
//! asm::bkpt();
63+
//!
64+
//! loop {}
65+
//! }
66+
//!
67+
//! // bind all interrupts to the default exception handler
68+
//! interrupts!(DefaultHandler);
69+
//! ```
70+
// Auto-generated. Do not modify.

0 commit comments

Comments
 (0)