Skip to content

Commit 18033c0

Browse files
TheZoq2therealprof
authored andcommitted
Improve quick start docs (#172)
1 parent 358889f commit 18033c0

File tree

4 files changed

+132
-126
lines changed

4 files changed

+132
-126
lines changed

BluePillPinout.jpg

424 KB
Loading

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ version = "0.5.2"
1313

1414
[package.metadata.docs.rs]
1515
features = ["stm32f103", "rt", "stm32-usbd"]
16+
default-target = "x86_64-unknown-linux-gnu"
1617

1718
[[example]]
1819
name = "timer-interrupt-rtfm"

README.md

Lines changed: 115 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,119 @@
77
[![crates.io](https://img.shields.io/crates/v/stm32f1xx-hal.svg)](https://crates.io/crates/stm32f1xx-hal)
88
[![Released API docs](https://docs.rs/stm32f1xx-hal/badge.svg)](https://docs.rs/stm32f1xx-hal)
99

10-
## Usage
10+
## Quick start guide
11+
12+
Embedded Rust development requires a bit more setup than ordinary development.
13+
For this guide, we'll assume you're using a stm32 blue pill board (shown
14+
below), but if you have another f1 microcontroller, you should be able to adapt
15+
it.
16+
17+
![blue pill pinout](BluePillPinout.jpg "opt title")
18+
19+
You will also need a debug probe, for example an [stlink v3
20+
mini](https://www.st.com/en/development-tools/stlink-v3mini.html) for programming and debugging.
21+
(There are many different STLink probes out there, all of them _should_ work fine with this instructions given here, other JTAG or SWD debug probes will work as well but will need different software or configuration).
22+
23+
### Installing software
24+
25+
To program your microcontroller, you need to install:
26+
- [openocd](http://openocd.org/)
27+
- `arm-none-eabi-gdb`
28+
29+
Finally, you need to install arm target support for the Rust compiler. To do
30+
so, run
31+
```
32+
rustup target install thumbv7m-none-eabi
33+
```
34+
35+
36+
### Setting up your project
37+
38+
Create a new Rust project as you usually do with `cargo init`. The hello world
39+
of embedded development is usually to blink an LED and code to do so is
40+
available in [examples/blinky.rs](examples/blinky.rs). Copy that file to the
41+
`main.rs` of your project.
42+
43+
You also need to add some dependencies to your `Cargo.toml`:
44+
45+
```toml
46+
[dependencies]
47+
embedded-hal = "0.2.3"
48+
nb = "0.1.2"
49+
cortex-m = "0.6.2"
50+
cortex-m-rt = "0.6.11"
51+
# Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives
52+
panic-halt = "0.2.0"
53+
54+
[dependencies.stm32f1xx-hal]
55+
version = "0.5.2"
56+
features = ["rt", "stm32f103"]
57+
```
58+
59+
If you build your project now, you should get a single error: `error: language
60+
item required, but not found: eh_personality`. This unhelpful error message
61+
is fixed by compiling for the right target.
62+
63+
We also need to tell Rust how to link our executable, and how to lay out the
64+
result in memory. To accomplish all this, copy [.cargo/config](.cargo/config) and
65+
[memory.x](memory.x) from the stm32f1xx-hal repo to your project.
66+
67+
```bash
68+
cargo build
69+
```
70+
71+
If everything went well, your project should have built without errors.
72+
73+
74+
### Programming the microcontroller
75+
76+
It is now time to actually run the code on the hardware. To do so plug your
77+
debug probe into the blue pill and start `openocd` using
78+
```bash
79+
openocd -f interface/stlink-v3.cfg -f target/stm32f1x.cfg
80+
```
81+
If you are not using an stlink V3, change the interface accordingly.
82+
For more information, see the [embeddonomicon].
83+
84+
If all went well, it should detect your microcontroller and say `Info :
85+
stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints`. Keep it running in
86+
the background.
87+
88+
We will use gdb for uploading the compiled binary to the microcontroller and
89+
for debugging. Cargo will automatically start `gdb` thanks to the
90+
[.cargo/config](.cargo/config) you added earlier. `gdb` also needs to be told
91+
to connect to openocd which is done by copying [.gdbinit](.gdbinit) to the root
92+
of your project.
93+
94+
You may also need to tell `gdb` that it is safe to load `.gdbinit` from the
95+
working directory.
96+
- Linux
97+
```bash
98+
echo "set auto-load safe-path $(pwd)" >> ~/.gdbinit
99+
```
100+
- Windows
101+
```batch
102+
echo set auto-load safe-path %CD% >> %USERPROFILE%\.gdbinit
103+
```
104+
105+
If everything was successful, cargo should compile your project, start gdb,
106+
load your program and give you a prompt. If you type `continue` in the gdb
107+
prompt, your program should start and the green led on the blue pill should
108+
start blinking.
109+
110+
111+
### Going further
112+
113+
From here on, you can start adding more code to your project to make it do
114+
something more interesting. For crate documentation, see
115+
[docs.rs/stm32f1xx-hal](https://docs.rs/stm32f1xx-hal). There are also a lot
116+
more [examples](examples) available. If something is unclear in the docs or
117+
examples, please, open an issue and we will try to improve it.
118+
119+
120+
121+
122+
## Selecting a microcontroller
11123

12124
This crate supports multiple microcontrollers in the
13125
stm32f1 family. Which specific microcontroller you want to build for has to be
@@ -31,7 +143,7 @@ device) but check the datasheet or CubeMX to be sure.
31143
* `stm32f103`
32144

33145

34-
### Trying out the examples
146+
## Trying out the examples
35147

36148
You may need to give `cargo` permission to call `gdb` from the working directory.
37149
- Linux
@@ -62,7 +174,7 @@ an stlink V2, use `stlink-v2.cfg`. For more information, see the
62174

63175

64176

65-
### Using as a Dependency
177+
## Using as a Dependency
66178

67179
When using this crate as a dependency in your project, the microcontroller can
68180
be specified as part of the `Cargo.toml` definition.
@@ -73,65 +185,6 @@ version = "0.5.2"
73185
features = ["stm32f100", "rt"]
74186
```
75187

76-
## Blinky example
77-
78-
The following example blinks an LED connected to pin PC13. For instructions on
79-
how set up a project and run the example, see the [documentation]. For more
80-
examples, see the [examples](examples) directory.
81-
82-
[documentation]: https://docs.rs/stm32f1xx-hal/
83-
84-
```rust
85-
#![no_std]
86-
#![no_main]
87-
88-
extern crate panic_halt;
89-
90-
use nb::block;
91-
92-
use stm32f1xx_hal::{
93-
prelude::*,
94-
pac,
95-
timer::Timer,
96-
};
97-
use cortex_m_rt::entry;
98-
99-
#[entry]
100-
fn main() -> ! {
101-
// Get access to the core peripherals from the cortex-m crate
102-
let cp = cortex_m::Peripherals::take().unwrap();
103-
// Get access to the device specific peripherals from the peripheral access crate
104-
let dp = pac::Peripherals::take().unwrap();
105-
106-
// Take ownership over the raw flash and rcc devices and convert them into the corresponding
107-
// HAL structs
108-
let mut flash = dp.FLASH.constrain();
109-
let mut rcc = dp.RCC.constrain();
110-
111-
// Freeze the configuration of all the clocks in the system and store
112-
// the frozen frequencies in `clocks`
113-
let clocks = rcc.cfgr.freeze(&mut flash.acr);
114-
115-
// Acquire the GPIOC peripheral
116-
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
117-
118-
// Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function
119-
// in order to configure the port. For pins 0-7, crl should be passed instead.
120-
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
121-
// Configure the syst timer to trigger an update every second
122-
let mut timer = Timer::syst(cp.SYST, clocks)
123-
.start_count_down(1.hz());
124-
125-
// Wait for the timer to trigger an update and change the state of the LED
126-
loop {
127-
block!(timer.wait()).unwrap();
128-
led.set_high().unwrap();
129-
block!(timer.wait()).unwrap();
130-
led.set_low().unwrap();
131-
}
132-
}
133-
```
134-
135188
## Documentation
136189

137190
The documentation can be found at [docs.rs](https://docs.rs/stm32f1xx-hal/).

src/lib.rs

Lines changed: 16 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
//!
1010
//! ## Building an application (binary crate)
1111
//!
12-
//! Follow the [cortex-m-quickstart] instructions, add this crate as a dependency
13-
//! and make sure you enable the "rt" Cargo feature of this crate. Also select which
14-
//! microcontroller you will be using by using the corresponding feature. The currently
12+
//! A detailed usage guide can be found in the [README]
13+
//!
1514
//! supported microcontrollers are:
1615
//!
1716
//! - stm32f103
17+
//! - stm32f101
1818
//! - stm32f100
1919
//!
2020
//! ## Usage
@@ -44,71 +44,23 @@
4444
//!
4545
//! [cortex-m-quickstart]: https://docs.rs/cortex-m-quickstart/0.3.1
4646
//!
47-
//! ## Usage example
48-
//!
49-
//! The following example blinks an LED connected to PC13 which is where the LED is connected on the
50-
//! [blue_pill] board. If you are testing on a different breakout board, you may need
51-
//! to change the pin accordingly.
47+
//! ## Usage examples
5248
//!
49+
//! See the [examples] folder.
5350
//!
54-
//! ```rust
55-
//! #![no_std]
56-
//! #![no_main]
57-
//!
58-
//! use panic_halt as _;
59-
//!
60-
//! use nb::block;
61-
//!
62-
//! use stm32f1xx_hal::{
63-
//! prelude::*,
64-
//! pac,
65-
//! timer::Timer,
66-
//! };
67-
//! use cortex_m_rt::entry;
68-
//! use embedded_hal::digital::v2::OutputPin;
69-
//!
70-
//! #[entry]
71-
//! fn main() -> ! {
72-
//! // Get access to the core peripherals from the cortex-m crate
73-
//! let cp = cortex_m::Peripherals::take().unwrap();
74-
//! // Get access to the device specific peripherals from the peripheral access crate
75-
//! let dp = pac::Peripherals::take().unwrap();
76-
//!
77-
//! // Take ownership over the raw flash and rcc devices and convert them into the corresponding
78-
//! // HAL structs
79-
//! let mut flash = dp.FLASH.constrain();
80-
//! let mut rcc = dp.RCC.constrain();
81-
//!
82-
//! // Freeze the configuration of all the clocks in the system and store the frozen frequencies in
83-
//! // `clocks`
84-
//! let clocks = rcc.cfgr.freeze(&mut flash.acr);
85-
//!
86-
//! // Acquire the GPIOC peripheral
87-
//! let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
88-
//!
89-
//! // Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function
90-
//! // in order to configure the port. For pins 0-7, crl should be passed instead.
91-
//! let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
92-
//! // Configure the syst timer to trigger an update every second
93-
//! let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz());
94-
//!
95-
//! // Wait for the timer to trigger an update and change the state of the LED
96-
//! loop {
97-
//! block!(timer.wait()).unwrap();
98-
//! led.set_high().unwrap();
99-
//! block!(timer.wait()).unwrap();
100-
//! led.set_low().unwrap();
101-
//! }
102-
//! }
51+
//! Most of the examples require the following additional dependencies
52+
//! ```toml
53+
//! [dependencies]
54+
//! embedded-hal = "0.2.3"
55+
//! nb = "0.1.2"
56+
//! cortex-m = "0.6.2"
57+
//! cortex-m-rt = "0.6.11"
58+
//! # Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives
59+
//! panic-halt = "0.2.0"
10360
//! ```
10461
//!
105-
//! [blue_pill]: http://wiki.stm32duino.com/index.php?title=Blue_Pill
106-
//!
107-
//! # More examples
108-
//!
109-
//! See the [examples] folder.
110-
//!
111-
//! [examples]: https://github.com/stm32-rs/stm32f1xx-hal/tree/master/examples
62+
//! [examples]: https://github.com/stm32-rs/stm32f1xx-hal/tree/v0.5.2/examples
63+
//! [README]: https://github.com/stm32-rs/stm32f1xx-hal/tree/v0.5.2
11264
11365
#![no_std]
11466

0 commit comments

Comments
 (0)