109 Commits
v0.1.9 ... sh

Author SHA1 Message Date
Jorge Aparicio
55e61c3291 bump dependencies 2018-11-10 00:04:28 +01:00
Jorge Aparicio
e64e690512 use NVIC::pend
instead of the deprecated NVIC.set_pending
2018-11-10 00:02:00 +01:00
Jorge Aparicio
f7a943f480 fix the allocator example
importing alloc is a bit weird
2018-11-10 00:01:25 +01:00
Jorge Aparicio
9c6b290e12 use hprint macros 2018-11-10 00:00:57 +01:00
Emil Fresk
7e2bec66b7 Merge pull request #54 from Nicoretti/toml
Add additional meta data to improve crate experience
2018-10-28 23:48:50 +01:00
Emil Fresk
4295bccf0e Merge pull request #51 from rust-embedded/therealprof-extended-remote
Default to extended-remote instead of remote mode
2018-10-28 23:48:32 +01:00
Nicola Coretti
8f292e0f07 Add additional meta data to improve crate experience
* Add readme setting, so README.md is shown on https://crates.io/
2018-10-26 15:54:27 +02:00
Jonathan 'theJPster' Pallant
76d2e947a5 Merge pull request #53 from birkenfeld/patch-1
Add example moving .bss data into custom memory
2018-10-22 19:18:17 -07:00
Georg Brandl
76cdd6a95b fix example 2018-10-21 17:27:47 +02:00
Georg Brandl
314e48537c Add example moving .bss data into custom memory
We're using a STM32F429 and wanted to move stuff around in memory, notably put stack+data into CPU coupled memory, and put framebuffers for the integrated LCD controller into the normal SRAM.

Getting this right while not completely overriding the default `link.x` was quite tricky (especially finding the `INSERT AFTER` life-saver...) so I thought an example would not hurt here.

It should probably also be mentioned in other places (book/...)?
2018-10-21 13:04:40 +02:00
Daniel Egger
d5abcf6d2a Merge pull request #52 from jannic/patch-1
Update rust version requirements in README.md
2018-10-13 21:40:23 +02:00
Jan Niehusmann
b02a67b5f9 Update rust version requirements in README.md
As Cargo.toml now includes edition = "2018", it won't build with rust 1.30-stable. 1.31-stable will be the first stable version to have the edition feature enabled. (See https://internals.rust-lang.org/t/rust-2018-release-schedule-and-extended-beta/8076 for details.)

At the same time, remove the remark about 1.30-beta not being out yet, as it's out by now.
2018-10-13 21:37:17 +02:00
Daniel Egger
d7c22926f4 Default to extended-remote instead of remote mode
Extended remote allows a lot more features like attaching and detaching and much more fine-grained execution options. If a gdbserver implementation supports it (and OpenOCD sure does) it should be preferred over `remote`.
2018-10-13 02:17:35 +02:00
Jorge Aparicio
52f2e8c604 Merge pull request #49 from rust-embedded/main-itm
break on main; restore ITM configure
2018-09-24 07:22:22 +02:00
Jorge Aparicio
69700e1438 add commented out ITM configuration
this got lost in a previous commit
2018-09-24 03:56:39 +02:00
Jorge Aparicio
e6dabb3c34 try to break at main
the symbol is now stable. However, in optimized build it may be inlined into
Reset
2018-09-24 03:55:52 +02:00
Jorge Aparicio
a7f68f41cb Merge pull request #45 from rust-embedded/generate
[RFC] move to cargo-generate; start with QEMU
2018-09-18 01:04:37 +02:00
Jorge Aparicio
cffc15846a bump dependencies 2018-09-18 00:38:06 +02:00
Jorge Aparicio
3b8fede353 note that 1.30-beta is not out yet 2018-09-18 00:37:22 +02:00
Jorge Aparicio
4e6d85e9a1 minify 2018-09-18 00:33:26 +02:00
Jorge Aparicio
300338f29d quieter GDB 2018-09-15 03:15:32 +02:00
Jorge Aparicio
ac4dd36e94 change the link to the book
book.rust-embedded.org is pointing to an old version
2018-09-14 19:29:42 +02:00
Jorge Aparicio
728d57d002 openocd.cfg: add support for older revisions of the discovery 2018-09-14 19:04:27 +02:00
Jorge Aparicio
9facab2960 backport fixes from the book plus other small updates 2018-09-13 21:40:25 +02:00
Jorge Aparicio
7faeedd95a move out most of text
see https://github.com/rust-embedded/book/pull/20
2018-09-08 22:37:43 +02:00
Jorge Aparicio
77a0685a17 move to cargo-generate; start with QEMU 2018-09-08 22:36:55 +02:00
bors[bot]
8a8466a560 Merge #46
46: bump dependencies r=adamgreig a=japaric

r? @rust-embedded/cortex-m (anyone)

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-09-03 15:04:28 +00:00
Jorge Aparicio
666bf52748 bump dependencies 2018-09-03 16:57:03 +02:00
bors[bot]
7e36bbe1df Merge #44
44: dedup contents of .cargo/config; don't depend on auto-load-safe-path being set r=ithinuel a=japaric

see individual commit messages for details

unfortunately this didn't come up as nice as I expected because there seems to
be a bug around `target.cfg.runner` (rust-lang/cargo#5946). Still, I think this
is an improvement.

r? @rust-embedded/cortex-m

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-08-29 22:26:27 +00:00
Jorge Aparicio
4265e01ef7 add a comment indicating which core each target maps to 2018-08-29 16:55:50 +02:00
Jorge Aparicio
98137712a5 workaround rust-lang/cargo#5946 2018-08-29 15:15:40 +02:00
Jorge Aparicio
065efc83fb be explicit about the GDB script to use
with this change the user doesn't need to set an [auto-load-safe-path]

[auto-load-safe-path]: https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html
2018-08-29 14:26:24 +02:00
Jorge Aparicio
b43bd7d20d deduplicate the contents .cargo/config
using `cfg`s. Also add all the possible compilation targets to .cargo/config.
2018-08-29 14:23:25 +02:00
bors[bot]
3da03fc6b8 Merge #43
43: add CHANGELOG for v0.3.4 r=adamgreig a=japaric

r? @rust-embedded/cortex-m (anyone)

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-08-28 19:51:15 +00:00
Jorge Aparicio
1fdaec36bd add CHANGELOG for v0.3.4 2018-08-28 21:41:37 +02:00
bors[bot]
217ebb3a79 Merge #42
42: v0.3.4 r=therealprof a=japaric

a few more updates before the next release

r? @rust-embedded/cortex-m

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-08-28 14:07:43 +00:00
Jorge Aparicio
5063e90960 v0.3.4 2018-08-28 15:56:49 +02:00
bors[bot]
73ced50a21 Merge #41
41: use LLD as the default linker r=therealprof a=japaric

closes #39

I added instructions on how to switch to a different linker to .cargo/config but
I don't think that's too visible. Beginners are unlikely to look into that file
if they run into problems with the default linker. Any suggestions to improve
the visibility of that information?

Also, don't merge this until the default linker changes for the Cortex-M targets
on nightly as this relies on that change.

r? @rust-embedded/cortex-m

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-08-28 13:15:12 +00:00
Jorge Aparicio
b89c76e3fc use size instead of arm-none-eabi-size 2018-08-28 14:55:02 +02:00
Jorge Aparicio
7bb74b2123 fix some warnings 2018-08-28 14:54:40 +02:00
Jorge Aparicio
0eaa0de3c6 update the minimal example 2018-08-27 22:52:02 +02:00
Jorge Aparicio
3e39a0b927 publish docs on GH pages 2018-08-27 17:44:55 +02:00
Jorge Aparicio
a79ea9bee7 bump dependencies to not depend on arm-none-eabi-gcc 2018-08-27 17:39:07 +02:00
Jorge Aparicio
34d34975c3 update symptom for the 'overwrite .cargo/config' problem 2018-08-27 15:19:48 +02:00
Jorge Aparicio
72e914069c use LLD as the default linker
closes #39
2018-08-25 19:32:28 +02:00
Jorge Aparicio
014dab642a tweak bors.toml 2018-08-11 19:37:39 -05:00
bors[bot]
cb68ff7248 Merge #40
40: v0.3.3 r=adamgreig a=japaric

changes required to publish a new version

r? @adamgreig (chosen at random)

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-08-07 22:33:55 +00:00
Jorge Aparicio
55f44f21be v0.3.3 2018-08-07 17:25:15 -05:00
bors[bot]
f38979def1 Merge #27
27: Clarify purpose of rerun-if-changed in build.rs r=japaric a=adamgreig

The current `build.rs` contains
```rust
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=memory.x");
```

This causes the build script to be re-run if (and *only if*) `build.rs` or `memory.x` change. The line for `build.rs` is redundant: the Cargo guide [says](https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script) the build script is always rerun when `build.rs` changes, so we can drop that line.

The remaining line caused me a bit of confusion when adding other functionality to my project's build script, before I realised it tells Cargo to *only* rerun the build script when `memory.x` changes, as opposed to the default behaviour which is to rerun it on every build. The comment helps clarify the point of this line, so if users add other functionality to their build scripts it is hopefully easier to notice.

Co-authored-by: Adam Greig <adam@adamgreig.com>
2018-08-07 21:14:34 +00:00
Adam Greig
ba27df0b57 Update comment on rerun-if-changed to better reflect what it does 2018-08-07 20:58:00 +01:00
Adam Greig
f39fa8ebef Add comment to build script about rerun-if-changed, and remove redundant line for build.rs 2018-08-07 20:57:02 +01:00
Jorge Aparicio
5832d097c6 README: mention the CoC and who maintains this repo 2018-08-07 00:25:15 -05:00
Jorge Aparicio
2a2879a3b0 add CODEOWNERS, CoC; tweak bors and Travis 2018-08-06 21:41:02 -05:00
bors[bot]
daea420f17 Merge #38
38: stop recommending LLD r=japaric a=japaric

until https://bugs.llvm.org/show_bug.cgi?id=38435 is fixed

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-08-03 02:39:19 +00:00
Jorge Aparicio
b7884948b2 fix the allocator example 2018-08-02 21:38:42 -05:00
Jorge Aparicio
01e9a597c1 stop recommending LLD
until https://bugs.llvm.org/show_bug.cgi?id=38435 is fixed
2018-08-02 21:12:11 -05:00
Jorge Aparicio
ae503ee8fb v0.3.2 2018-06-19 19:53:30 -05:00
bors[bot]
4a398df058 Merge #33
33: Update panic-semihosting dependency to 0.3.0 r=japaric a=plaes

This is due to #[lang = "panic_fmt"] -> #[panic_implementation] breakage

Co-authored-by: Priit Laes <plaes@plaes.org>
2018-06-20 00:46:27 +00:00
Priit Laes
efb84ccf53 Update panic-semihosting dependency to 0.3.0
This is due to #[lang = "panic_fmt"] -> #[panic_implementation] breakage
2018-06-17 09:23:23 +03:00
Jorge Aparicio
a462ab027d Merge pull request #30 from MrBuddyCasino/master
minor doc fix: git => cargo
2018-05-16 12:50:57 +02:00
Michael Böckling
6da25bced8 Update lib.rs
fixed doc: clone command should be cargo, not git
2018-05-16 11:00:33 +02:00
Jorge Aparicio
7cb137968b v0.3.1 2018-05-13 13:41:59 +02:00
Jorge Aparicio
7ae7245956 document the no #![no_main] issue 2018-05-13 12:02:37 +02:00
Jorge Aparicio
91a894e369 v0.3.0 2018-05-12 21:06:19 +02:00
bors[bot]
f7cf8de167 Merge #29
29: use less unstable dependencies r=japaric a=japaric

This PR and the ones at the bottom reduce the number of unstable features needed for Cortex-M development to a single one: `lang = "panic_fmt"`, which already has a path towards stabilization and which we hope to get on stable by 1.28.

[Check out the temporary documentation](https://japaric.github.io/cortex-m-quickstart/cortex_m_quickstart/index.html) (we still need more docs) to try out this preview. 

We would love your input on [these unresolved questions](https://github.com/japaric/cortex-m-rt/pull/69#issuecomment-384488537)

This PR depends on:

- japaric/cortex-m-rt#69
- japaric/cortex-m#88
- japaric/panic-semihosting#2
- japaric/svd2rust#203
- japaric/stm32f103xx#24

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-05-12 18:58:57 +00:00
Jorge Aparicio
66c0c588b0 fix tests 2018-05-12 20:51:52 +02:00
Jorge Aparicio
0f139c386b use published versions, doc up, update CHANGELOG 2018-05-12 20:41:42 +02:00
Jorge Aparicio
3a4a5be709 TODO: drop opt-level=s 2018-04-26 07:57:34 +02:00
Jorge Aparicio
a35486b2f4 update examples and docs 2018-04-26 07:37:15 +02:00
Jorge Aparicio
8e79d05cc4 drop linker-flavor, port more examples 2018-04-26 05:27:03 +02:00
Jorge Aparicio
0e2ec97ce6 make the hello example work 2018-04-25 07:54:05 +02:00
Jorge Aparicio
f6988f1ced use less unstable dependencies 2018-04-24 20:56:52 +02:00
bors[bot]
43acbc4e12 Merge #28
28: bump the cortex-m-rt to v0.4.0 r=japaric a=japaric



Co-authored-by: Jorge Aparicio <jorge@japaric.io>
2018-04-24 00:49:55 +00:00
Jorge Aparicio
a18a2fe64b don't call ci/after_success.sh 2018-04-24 02:49:32 +02:00
Jorge Aparicio
3b2e5699f3 remove panic-itm dependency 2018-04-24 02:13:15 +02:00
Jorge Aparicio
72b23f0e85 ci: don't install cargo-edit 2018-04-24 01:42:13 +02:00
Jorge Aparicio
2cd4ea31e5 bump the cortex-m-rt to v0.4.0 2018-04-24 01:24:06 +02:00
Jorge Aparicio
6f62705eaf v0.2.6 2018-04-09 00:11:59 +02:00
Jorge Aparicio
1d3d6e708c Merge pull request #26 from japaric/bye-xargo
remove all mentions of Xargo
2018-04-09 00:09:33 +02:00
Jorge Aparicio
fb3f403be5 remove all mentions of Xargo
as you can use plain Cargo to do ARM Cortex-M development
2018-04-09 00:06:24 +02:00
Jorge Aparicio
578dfc7f86 v0.2.5 2018-02-26 22:31:17 +01:00
Jorge Aparicio
23ae289bf4 fix the allocator example 2018-02-26 22:27:52 +01:00
Jorge Aparicio
5206ef79d2 examples/panic: add column information 2018-02-26 21:55:25 +01:00
Jorge Aparicio
46c97c6cee remove unused #[allow] 2018-02-26 21:49:45 +01:00
Jorge Aparicio
ba8994a2ed use stable release of alloc-cortex-m 2018-02-26 21:49:25 +01:00
Jorge Aparicio
7ebac078c0 Merge pull request #23 from kitling/update-examples
Update examples
2018-02-26 21:48:47 +01:00
Kitlith
d002e0f239 Add comments to Cargo.toml/Xargo.toml.
This should make it easier to comment/uncomment stuff for the various
examples.
2018-02-24 18:28:53 -08:00
Kitlith
9f573d73b2 Update examples to newer svd2rust api.
Similarly, the cortex-m crate API was also updated.
2018-02-24 18:26:31 -08:00
Jorge Aparicio
bf91f60d40 v0.2.4 2018-01-26 11:39:18 +01:00
Jorge Aparicio
682fe4e77c v0.2.3 2018-01-20 11:27:24 +01:00
Jorge Aparicio
d60563ff45 update the CHANGELOG 2018-01-17 14:46:18 +01:00
Jorge Aparicio
48ce24b303 document workaround for "Ignoring packet error" 2018-01-17 14:42:13 +01:00
Jorge Aparicio
3dc0cf09db disable incremental compilation and parallel codegen in dev mode 2018-01-17 14:27:57 +01:00
Jorge Aparicio
59b8b866c7 bump the cortex-m-rt dependency 2018-01-17 14:26:42 +01:00
Jorge Aparicio
1bb99c92f1 Merge pull request #20 from japaric/demangle
gdbinit: print demangled symbols by default
2017-11-25 01:12:55 +01:00
Jorge Aparicio
d41dd6a4c7 gdbinit: print demangled symbols by default
this change turns this:

``` console
(gdb) x/4 0x200003f0
0x200003f0 <_ZN3app2XS17h4b49405669958fd2E+1008>:       0x20000400      0x080004f5      0x00000000      0x00000001
```

into this:

``` console
(gdb) x/4 0x200003f0
0x200003f0 <app::XS+1008>:      0x20000400      0x080004f5      0x00000000      0x00000001
```
2017-11-25 01:12:17 +01:00
Jorge Aparicio
a8a02d9162 v0.2.1 2017-07-14 21:53:54 -05:00
Jorge Aparicio
affd24f2bb document another common error
overwriting the `.cargo/config` file instead of appending text to it
2017-07-14 21:48:05 -05:00
Jorge Aparicio
67003f069c enable the "mem" feature of the compiler-builtins crate
turns out it *is* required if your application ends up requiring a `memcmp`
operation.
2017-07-14 21:36:34 -05:00
Jorge Aparicio
51f4b4e7ed Merge pull request #16 from japaric/device
expand the device example
2017-07-14 21:26:25 -05:00
Jorge Aparicio
8890c461d6 expand the device example 2017-07-11 19:01:40 -05:00
Jorge Aparicio
3f66a585a8 Merge pull request #14 from protomors/upstream-builtins
Build compiler-builtins from rust source instead of github repository.
2017-07-10 19:03:43 -05:00
protomors
ba1263e7a1 Build compiler-builtins from rust source instead of github repository. 2017-07-09 12:05:26 +03:00
Jorge Aparicio
4b1a2f3811 fix CHANGELOG 2017-07-07 20:11:05 -05:00
Jorge Aparicio
805b63afb1 v0.2.0 2017-07-07 18:34:47 -05:00
Jorge Aparicio
6780d81e4d Merge pull request #13 from japaric/dev
Revert "Remove 'monitor tpiu itm port 0 on' from .gdbinit"
2017-06-17 17:21:12 -05:00
Jorge Aparicio
59a780d0c4 Revert "Remove 'monitor tpiu itm port 0 on' from .gdbinit"
This reverts commit f88a44fd78.

It's required on OpenOCD 0.10.0
2017-06-17 17:18:48 -05:00
Jorge Aparicio
c03bded663 Merge pull request #12 from adamgreig/patch-1
Remove 'monitor tpiu itm port 0 on' from .gdbinit
2017-06-10 12:25:02 -05:00
Adam Greig
f88a44fd78 Remove 'monitor tpiu itm port 0 on' from .gdbinit
This happens automatically when openocd sets up the tpiu; see openocd manual 16.5.4.
2017-06-09 22:22:53 +01:00
33 changed files with 518 additions and 1326 deletions

View File

@@ -1,31 +1,33 @@
[target.thumbv6m-none-eabi]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]
[target.thumbv7m-none-eabi]
runner = 'arm-none-eabi-gdb'
# uncomment this to make `cargo run` execute programs on QEMU
# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"
rustflags = [
# LLD (shipped with the Rust toolchain) is used as the default linker
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
# if you run into problems with LLD switch to the GNU linker by commenting out
# this line
# "-C", "linker=arm-none-eabi-ld",
# if you need to link to pre-compiled C libraries provided by a C toolchain
# use GCC as the linker by commenting out both lines above and then
# uncommenting the three lines below
# "-C", "linker=arm-none-eabi-gcc",
# "-C", "link-arg=-Wl,-Tlink.x",
# "-C", "link-arg=-nostartfiles",
]
[target.thumbv7em-none-eabi]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]
[target.thumbv7em-none-eabihf]
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]
[build]
# Pick ONE of these compilation targets
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

View File

@@ -1,18 +0,0 @@
target remote :3333
monitor arm semihosting enable
# # send captured ITM to the file itm.fifo
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
# # 8000000 must match the core clock frequency
# monitor tpiu config internal itm.fifo uart off 8000000
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
# # 2000000 is the frequency of the SWO pin
# monitor tpiu config external uart off 8000000 2000000
# # enable ITM port 0
# monitor itm port 0 on
load
step

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
**/*.rs.bk
.#*
.gdb_history
Cargo.lock
target/

View File

@@ -1,87 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
## [v0.1.8] - 2017-05-30
### Changed
- Bumped the cortex-m-rt dependency to v0.2.3, and documented the `_stext`
symbol (see memory.x).
## [v0.1.7] - 2017-05-27
### Added
- Documentation and an example about how to use the heap and a dynamic memory
allocator.
### Changed
- Bumped the `cortex-m-rt` dependency to v0.2.2
- Bumped the `cortex-m` dependency to v0.2.7
## [v0.1.6] - 2017-05-26
### Added
- Set the default runner in .cargo/config to `arm-none-eabi-gdb`. Now `xargo
run` will build the program and start a debug session.
## [v0.1.5] - 2017-05-16
### Added
- A warning about using CARGO_INCREMENTAL to the how to use and the
troubleshooting sections.
## [v0.1.4] - 2017-05-13
### Added
- A dependencies section to the documentation
### Changed
- Extend troubleshooting section
## [v0.1.3] - 2017-05-13
### Added
- A troubleshooting section to the documentation
### Changed
- Bumped the cortex-m crate version to v0.2.6
## [v0.1.2] - 2017-05-07
### Fixed
- .gdbinit: jump to reset handler after loading the program.
## [v0.1.1] - 2017-04-27
### Changed
- Bumped the version of the `cortex-m-rt` dependency to v0.2.0. NOTE that the
instantiation steps have slightly changed, the `memory.x` file changed,
because of this.
## v0.1.0 - 2017-04-25
- Initial release
[Unreleased]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.8...HEAD
[v0.1.8]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.7...v0.1.8
[v0.1.7]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.6...v0.1.7
[v0.1.6]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.5...v0.1.6
[v0.1.5]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.4...v0.1.5
[v0.1.4]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.3...v0.1.4
[v0.1.3]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.2...v0.1.3
[v0.1.2]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.1...v0.1.2
[v0.1.1]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.0...v0.1.1

View File

@@ -1,20 +1,34 @@
[package]
authors = ["Jorge Aparicio <jorge@japaric.io>"]
categories = ["embedded", "no-std"]
description = "A template for building applications for ARM Cortex-M microcontrollers"
keywords = ["arm", "cortex-m", "template"]
license = "MIT OR Apache-2.0"
name = "cortex-m-quickstart"
repository = "https://github.com/japaric/cortex-m-quickstart"
version = "0.1.9"
authors = ["{{authors}}"]
edition = "2018"
readme = "README.md"
name = "{{project-name}}"
version = "0.1.0"
[dependencies]
cortex-m = "0.2.7"
cortex-m-rt = "0.2.3"
cortex-m = "0.5.8"
cortex-m-rt = "0.6.5"
cortex-m-semihosting = "0.3.2"
panic-halt = "0.2.0"
[profile.dev]
codegen-units = 1
# Uncomment for the panic example.
# panic-itm = "0.4.0"
# Uncomment for the allocator example.
# alloc-cortex-m = "0.3.5"
# Uncomment for the device example.
# [dependencies.stm32f30x]
# features = ["rt"]
# version = "0.7.1"
# this lets you use `cargo fix`!
[[bin]]
name = "{{project-name}}"
test = false
bench = false
[profile.release]
lto = true
debug = true
codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,25 +0,0 @@
Copyright (c) 2017 {{toml-escape author}}
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

111
README.md
View File

@@ -2,11 +2,109 @@
> A template for building applications for ARM Cortex-M microcontrollers
# [Documentation](https://docs.rs/cortex-m-quickstart)
This project is developed and maintained by the [Cortex-M team][team].
## Dependencies
To build embedded programs using this template you'll need:
- Rust 1.31, 1.30-beta, nightly-2018-09-13 or a newer toolchain. e.g. `rustup
default beta`
- The `cargo generate` subcommand. [Installation
instructions](https://github.com/ashleygwilliams/cargo-generate#installation).
- `rust-std` components (pre-compiled `core` crate) for the ARM Cortex-M
targets. Run:
``` console
$ rustup target add thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf
```
## Using this template
**NOTE**: This is the very short version that only covers building programs. For
the long version, which additionally covers flashing, running and debugging
programs, check [the embedded Rust book][book].
[book]: https://rust-embedded.github.io/book
0. Before we begin you need to identify some characteristics of the target
device as these will be used to configure the project:
- The ARM core. e.g. Cortex-M3.
- Does the ARM core include an FPU? Cortex-M4**F** and Cortex-M7**F** cores do.
- How much Flash memory and RAM does the target device has? e.g. 256 KiB of
Flash and 32 KiB of RAM.
- Where are Flash memory and RAM mapped in the address space? e.g. RAM is
commonly located at address `0x2000_0000`.
You can find this information in the data sheet or the reference manual of your
device.
In this example we'll be using the STM32F3DISCOVERY. This board contains an
STM32F303VCT6 microcontroller. This microcontroller has:
- A Cortex-M4F core that includes a single precision FPU
- 256 KiB of Flash located at address 0x0800_0000.
- 40 KiB of RAM located at address 0x2000_0000. (There's another RAM region but
for simplicity we'll ignore it).
1. Instantiate the template.
``` console
$ cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
Project Name: app
Creating project called `app`...
Done! New project created /tmp/app
$ cd app
```
2. Set a default compilation target. There are four options as mentioned at the
bottom of `.cargo/config`. For the STM32F303VCT6, which has a Cortex-M4F
core, we'll pick the `thumbv7em-none-eabihf` target.
``` console
$ tail -n6 .cargo/config
```
``` toml
[build]
# Pick ONE of these compilation targets
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
# target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
```
3. Enter the memory region information into the `memory.x` file.
``` console
$ cat memory.x
/* Linker script for the STM32F303VCT6 */
MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 40K
}
```
4. Build the template application or one of the examples.
``` console
$ cargo build
```
# License
Licensed under either of
This template is licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
@@ -20,3 +118,12 @@ at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
## Code of Conduct
Contribution to this crate is organized under the terms of the [Rust Code of
Conduct][CoC], the maintainer of this crate, the [Cortex-M team][team], promises
to intervene to uphold that code of conduct.
[CoC]: CODE_OF_CONDUCT.md
[team]: https://github.com/rust-embedded/wg#the-cortex-m-team

View File

@@ -1,6 +0,0 @@
[dependencies.core]
[dependencies.compiler_builtins]
features = ["mem"]
git = "https://github.com/rust-lang-nursery/compiler-builtins"
stage = 1

View File

@@ -12,6 +12,7 @@ fn main() {
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rerun-if-changed=build.rs");
// Only re-run the build script when memory.x is changed,
// instead of when any part of the source code changes.
println!("cargo:rerun-if-changed=memory.x");
}

View File

@@ -1,71 +1,57 @@
//! How to use the heap and a dynamic memory allocator
//!
//! To compile this example you'll need to build the collections crate as part
//! of the Xargo sysroot. To do that change the Xargo.toml file to look like
//! this:
//!
//! ``` text
//! [dependencies.core]
//! [dependencies.collections] # new
//!
//! [dependencies.compiler_builtins]
//! features = ["mem"]
//! git = "https://github.com/rust-lang-nursery/compiler-builtins"
//! stage = 1
//! ```
//!
//! This example depends on the alloc-cortex-m crate so you'll have to add it
//! to your Cargo.toml:
//! This example depends on the alloc-cortex-m crate so you'll have to add it to your Cargo.toml:
//!
//! ``` text
//! # or edit the Cargo.toml file manually
//! $ cargo add alloc-cortex-m
//! ```
//!
//! ---
#![feature(collections)]
#![feature(used)]
#![feature(alloc)]
#![feature(alloc_error_handler)]
#![no_main]
#![no_std]
// This is the allocator crate; you can use a different one
extern crate alloc_cortex_m;
#[macro_use]
extern crate collections;
#[macro_use]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate alloc;
extern crate panic_halt;
use self::alloc::vec;
use core::alloc::Layout;
use alloc_cortex_m::CortexMHeap;
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
fn main() {
// Initialize the allocator
unsafe {
extern "C" {
// Start of the heap
static mut _sheap: usize;
}
// this is the allocator the application will use
#[global_allocator]
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
// Size of the heap in words (1 word = 4 bytes)
// WARNING: The bigger the heap the greater the chance to run into a
// stack overflow (collision between the stack and the heap)
const SIZE: isize = 256;
const HEAP_SIZE: usize = 1024; // in bytes
// End of the heap
let _eheap = (&mut _sheap as *mut _).offset(SIZE);
alloc_cortex_m::init(&mut _sheap as *mut _, _eheap);
}
#[entry]
fn main() -> ! {
// Initialize the allocator BEFORE you use it
unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE) }
// Growable array allocated on the heap
let xs = vec![0, 1, 2];
hprintln!("{:?}", xs);
hprintln!("{:?}", xs).unwrap();
// exit QEMU
// NOTE do not run this on hardware; it can corrupt OpenOCD state
debug::exit(debug::EXIT_SUCCESS);
loop {}
}
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
// define what happens in an Out Of Memory (OOM) condition
#[alloc_error_handler]
fn alloc_error(_layout: Layout) -> ! {
asm::bkpt();
loop {}
}

View File

@@ -1,58 +1,96 @@
//! Debugging a crash (exception)
//!
//! The `cortex-m-rt` crate provides functionality for this through a default
//! exception handler. When an exception is hit, the default handler will
//! trigger a breakpoint and in this debugging context the stacked registers
//! are accessible.
//! Most crash conditions trigger a hard fault exception, whose handler is defined via
//! `exception!(HardFault, ..)`. The `HardFault` handler has access to the exception frame, a
//! snapshot of the CPU registers at the moment of the exception.
//!
//! In you run the example below, you'll be able to inspect the state of your
//! program under the debugger using these commands:
//! This program crashes and the `HardFault` handler prints to the console the contents of the
//! `ExceptionFrame` and then triggers a breakpoint. From that breakpoint one can see the backtrace
//! that led to the exception.
//!
//! ```
//! (gdb) # Stacked registers = program state during the crash
//! (gdb) print/x *_sr
//! $1 = cortex_m::exception::StackedRegisters {
//! r0 = 0x2fffffff,
//! r1 = 0x2fffffff,
//! r2 = 0x0,
//! r3 = 0x0,
//! r12 = 0x0,
//! lr = 0x8000443,
//! pc = 0x8000190,
//! xpsr = 0x61000200,
//! }
//! ``` text
//! (gdb) continue
//! Program received signal SIGTRAP, Trace/breakpoint trap.
//! __bkpt () at asm/bkpt.s:3
//! 3 bkpt
//!
//! (gdb) # What exception was triggered?
//! (gdb) print _e
//! $2 = cortex_m::exception::Exception::HardFault
//!
//! (gdb) # Where did we come from?
//! (gdb) backtrace
//! #0 __bkpt () at asm/bkpt.s:3
//! #1 0x080030b4 in cortex_m::asm::bkpt () at $$/cortex-m-0.5.0/src/asm.rs:19
//! #2 rust_begin_unwind (args=..., file=..., line=99, col=5) at $$/panic-semihosting-0.2.0/src/lib.rs:87
//! #3 0x08001d06 in core::panicking::panic_fmt () at libcore/panicking.rs:71
//! #4 0x080004a6 in crash::hard_fault (ef=0x20004fa0) at examples/crash.rs:99
//! #5 0x08000548 in UserHardFault (ef=0x20004fa0) at <exception macros>:10
//! #6 0x0800093a in HardFault () at asm.s:5
//! Backtrace stopped: previous frame identical to this frame (corrupt stack?)
//! ```
//!
//! In the console output one will find the state of the Program Counter (PC) register at the time
//! of the exception.
//!
//! ``` text
//! panicked at 'HardFault at ExceptionFrame {
//! r0: 0x2fffffff,
//! r1: 0x2fffffff,
//! r2: 0x080051d4,
//! r3: 0x080051d4,
//! r12: 0x20000000,
//! lr: 0x08000435,
//! pc: 0x08000ab6,
//! xpsr: 0x61000000
//! }', examples/crash.rs:106:5
//! ```
//!
//! This register contains the address of the instruction that caused the exception. In GDB one can
//! disassemble the program around this address to observe the instruction that caused the
//! exception.
//!
//! ``` text
//! (gdb) disassemble/m 0x08000ab6
//! Dump of assembler code for function core::ptr::read_volatile:
//! 451 pub unsafe fn read_volatile<T>(src: *const T) -> T {
//! 0x08000aae <+0>: sub sp, #16
//! 0x08000ab0 <+2>: mov r1, r0
//! 0x08000ab2 <+4>: str r0, [sp, #8]
//!
//! 452 intrinsics::volatile_load(src)
//! 0x08000ab4 <+6>: ldr r0, [sp, #8]
//! -> 0x08000ab6 <+8>: ldr r0, [r0, #0]
//! 0x08000ab8 <+10>: str r0, [sp, #12]
//! 0x08000aba <+12>: ldr r0, [sp, #12]
//! 0x08000abc <+14>: str r1, [sp, #4]
//! 0x08000abe <+16>: str r0, [sp, #0]
//! 0x08000ac0 <+18>: b.n 0x8000ac2 <core::ptr::read_volatile+20>
//!
//! 453 }
//! 0x08000ac2 <+20>: ldr r0, [sp, #0]
//! 0x08000ac4 <+22>: add sp, #16
//! 0x08000ac6 <+24>: bx lr
//!
//! End of assembler dump.
//! ```
//!
//! `ldr r0, [r0, #0]` caused the exception. This instruction tried to load (read) a 32-bit word
//! from the address stored in the register `r0`. Looking again at the contents of `ExceptionFrame`
//! we see that the `r0` contained the address `0x2FFF_FFFF` when this instruction was executed.
//!
//! ---
#![feature(used)]
#![no_main]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate panic_halt;
use core::ptr;
use cortex_m::asm;
use cortex_m_rt::entry;
fn main() {
// Read an invalid memory address
#[entry]
fn main() -> ! {
unsafe {
// read an address outside of the RAM region; this causes a HardFault exception
ptr::read_volatile(0x2FFF_FFFF as *const u32);
}
}
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
loop {}
}

63
examples/device.rs Normal file
View File

@@ -0,0 +1,63 @@
//! Using a device crate
//!
//! Crates generated using [`svd2rust`] are referred to as device crates. These crates provide an
//! API to access the peripherals of a device.
//!
//! [`svd2rust`]: https://crates.io/crates/svd2rust
//!
//! 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.
//!
//! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx
//!
//! ```
//! $ edit Cargo.toml && tail $_
//! [dependencies.stm32f103xx]
//! features = ["rt"]
//! version = "0.10.0"
//! ```
//!
//! ---
#![no_main]
#![no_std]
#[allow(unused_extern_crates)]
extern crate panic_halt;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprint;
use stm32f30x::{interrupt, Interrupt};
#[entry]
fn main() -> ! {
let p = cortex_m::Peripherals::take().unwrap();
let mut syst = p.SYST;
let mut nvic = p.NVIC;
nvic.enable(Interrupt::EXTI0);
// configure the system timer to wrap around every second
syst.set_clock_source(SystClkSource::Core);
syst.set_reload(8_000_000); // 1s
syst.enable_counter();
loop {
// busy wait until the timer wraps around
while !syst.has_wrapped() {}
// trigger the `EXTI0` interrupt
NVIC::pend(Interrupt::EXTI0);
}
}
// try commenting out this line: you'll end in `default_handler` instead of in `exti0`
interrupt!(EXTI0, exti0);
fn exti0() {
hprint!(".").unwrap();
}

37
examples/exception.rs Normal file
View File

@@ -0,0 +1,37 @@
//! Overriding an exception handler
//!
//! You can override an exception handler using the [`#[exception]`][1] attribute.
//!
//! [1]: https://rust-embedded.github.io/cortex-m-rt/0.6.1/cortex_m_rt_macros/fn.exception.html
//!
//! ---
#![deny(unsafe_code)]
#![no_main]
#![no_std]
extern crate panic_halt;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::Peripherals;
use cortex_m_rt::{entry, exception};
use cortex_m_semihosting::hprint;
#[entry]
fn main() -> ! {
let p = Peripherals::take().unwrap();
let mut syst = p.SYST;
// configures the system timer to trigger a SysTick exception every second
syst.set_clock_source(SystClkSource::Core);
syst.set_reload(8_000_000); // period = 1s
syst.enable_counter();
syst.enable_interrupt();
loop {}
}
#[exception]
fn SysTick() {
hprint!(".").unwrap();
}

View File

@@ -1,24 +1,20 @@
//! Prints "Hello, world!" on the OpenOCD console using semihosting
//! Prints "Hello, world!" on the host console using semihosting
#![feature(used)]
#![no_main]
#![no_std]
#[macro_use]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate panic_halt;
use cortex_m::asm;
use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
fn main() {
hprintln!("Hello, world!");
}
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
#[entry]
fn main() -> ! {
hprintln!("Hello, world!").unwrap();
// exit QEMU
// NOTE do not run this on hardware; it can corrupt OpenOCD state
debug::exit(debug::EXIT_SUCCESS);
loop {}
}

View File

@@ -1,41 +1,33 @@
//! Sends "Hello, world!" through the ITM port 0
//!
//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the
//! microcontroller's SWO pin to the SWD interface. Note that some development
//! boards don't provide this option.
//!
//! ITM is much faster than semihosting. Like 4 orders of magnitude or so.
//!
//! You'll need [`itmdump`] to receive the message on the host plus you'll need
//! to uncomment OpenOCD's ITM support in `.gdbinit`.
//! **NOTE** Cortex-M0 chips don't support ITM.
//!
//! [`itmdump`]: https://docs.rs/itm/0.1.1/itm/
//! You'll have to connect the microcontroller's SWO pin to the SWD interface. Note that some
//! development boards don't provide this option.
//!
//! You'll need [`itmdump`] to receive the message on the host plus you'll need to uncomment two
//! `monitor` commands in the `.gdbinit` file.
//!
//! [`itmdump`]: https://docs.rs/itm/0.2.1/itm/
//!
//! ---
#![feature(used)]
#![no_main]
#![no_std]
#[macro_use]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate panic_halt;
use cortex_m::{asm, interrupt, peripheral};
use cortex_m::{iprintln, Peripherals};
use cortex_m_rt::entry;
fn main() {
interrupt::free(
|cs| {
let itm = peripheral::ITM.borrow(&cs);
#[entry]
fn main() -> ! {
let mut p = Peripherals::take().unwrap();
let stim = &mut p.ITM.stim[0];
iprintln!(&itm.stim[0], "Hello, world!");
},
);
}
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
iprintln!(stim, "Hello, world!");
loop {}
}

View File

@@ -1,46 +0,0 @@
//! Overriding an exception
//!
//! **NOTE** You have to disable the `cortex-m-rt` crate's "exceptions" feature
//! to make this work.
#![feature(used)]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rt;
use core::ptr;
use cortex_m::{asm, exception};
fn main() {
unsafe {
// Invalid memory access
ptr::read_volatile(0x2FFF_FFFF as *const u32);
}
}
extern "C" fn hard_fault(_: exception::HardFault) {
// You'll hit this breakpoint rather than the one in cortex-m-rt
asm::bkpt()
}
// When the "exceptions" feature is disabled, you'll have to provide this symbol
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.exceptions"]
static EXCEPTIONS: exception::Handlers = exception::Handlers {
// This is the exception handler override
hard_fault: hard_fault,
..exception::DEFAULT_HANDLERS
};
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
}

View File

@@ -1,35 +1,28 @@
//! Redirecting `panic!` messages
//! Changing the panicking behavior
//!
//! The `cortex-m-rt` crate provides two options to redirect `panic!` messages
//! through these two Cargo features:
//! The easiest way to change the panicking behavior is to use a different [panic handler crate][0].
//!
//! - `panic-over-semihosting`. `panic!` messages will be printed to the OpenOCD
//! console using semihosting. This is slow.
//!
//! - `panic-over-itm`. `panic!` messages will be send through the ITM port 0.
//! This is much faster but requires ITM support on the device.
//!
//! If neither of these options is specified then the `panic!` message will be
//! lost. Note that all `panic!`s will trigger a debugger breakpoint.
//! [0]: https://crates.io/keywords/panic-impl
#![feature(used)]
#![no_main]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rt;
// Pick one of these panic handlers:
use cortex_m::asm;
// `panic!` halts execution; the panic message is ignored
extern crate panic_halt;
fn main() {
panic!("Oops");
}
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
// Reports panic messages to the host stderr using semihosting
// NOTE to use this you need to uncomment the `panic-semihosting` dependency in Cargo.toml
// extern crate panic_semihosting;
// Logs panic messages using the ITM (Instrumentation Trace Macrocell)
// NOTE to use this you need to uncomment the `panic-itm` dependency in Cargo.toml
// extern crate panic_itm;
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
panic!("Oops")
}

View File

@@ -1,36 +0,0 @@
//! Register an interrupt handler
//!
//! NOTE Requires a device crate generated using `svd2rust`
#![feature(used)]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rt;
// NOTE this is the device crate
extern crate stm32f30x;
use cortex_m::asm;
use stm32f30x::interrupt;
fn main() {}
// NOTE each interrupt handler has a different signature
extern "C" fn my_interrupt_handler(_ctxt: interrupt::Tim7) {
asm::bkpt();
}
extern "C" fn another_interrupt_handler(_ctxt: interrupt::Exti0) {
asm::bkpt();
}
// Here we override only two interrupt handlers, the rest of interrupt are
// handled by the same interrupt handler
#[allow(dead_code)]
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: interrupt::Handlers = interrupt::Handlers {
Tim7: my_interrupt_handler,
Exti0: another_interrupt_handler,
..interrupt::DEFAULT_HANDLERS
};

View File

@@ -1,55 +0,0 @@
# Converts the examples in the `examples` directory into documentation in the
# `examples` module (`src/examples/*.rs`)
set -ex
main() {
local examples=(
hello
itm
panic
crash
register-interrupt-handler
override-exception-handler
allocator
)
rm -rf src/examples
mkdir src/examples
cat >src/examples/mod.rs <<'EOF'
//! Examples
// Auto-generated. Do not modify.
EOF
local i=0 out=
for ex in ${examples[@]}; do
name=_${i}_${ex//-/_}
out=src/examples/${name}.rs
echo "pub mod $name;" >> src/examples/mod.rs
grep '//!' examples/$ex.rs > $out
echo '//!' >> $out
echo '//! ```' >> $out
grep -v '//!' examples/$ex.rs | (
IFS=''
while read line; do
echo "//! $line" >> $out;
done
)
echo '//! ```' >> $out
echo '// Auto-generated. Do not modify.' >> $out
chmod -x $out
i=$(( i + 1 ))
done
chmod -x src/examples/mod.rs
}
main

View File

@@ -1,19 +1,34 @@
MEMORY
{
/* NOTE K = KiBi = 1024 bytes */
/* NOTE 1 K = 1 KiBi = 1024 bytes */
/* TODO Adjust these memory regions to match your device memory layout */
FLASH : ORIGIN = 0xBAAAAAAD, LENGTH = 0K
RAM : ORIGIN = 0xBAAAAAAD, LENGTH = 0K
/* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
/* You may want to use this variable to locate the call stack and static
variables in different memory regions. Below is shown the default value */
/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */
/* You can use this symbol to customize the location of the .text section */
/* If omitted the .text section will be placed right after the .vector_table
section */
/* This is required only on some microcontrollers that store some configuration
right after the vector table */
/* This is required only on microcontrollers that store some configuration right
after the vector table */
/* _stext = ORIGIN(FLASH) + 0x400; */
/* Example of putting non-initialized variables into custom RAM locations. */
/* This assumes you have defined a region RAM2 above, and in the Rust
sources added the attribute `#[link_section = ".ram2bss"]` to the data
you want to place there. */
/* Note that the section will not be zero-initialized by the runtime! */
/* SECTIONS {
.ram2bss (NOLOAD) : ALIGN(4) {
*(.ram2bss);
. = ALIGN(4);
} > RAM2
} INSERT AFTER .bss;
*/

12
openocd.cfg Normal file
View File

@@ -0,0 +1,12 @@
# Sample OpenOCD configuration for the STM32F3DISCOVERY development board
# Depending on the hardware revision you got you'll have to pick ONE of these
# interfaces. At any time only one interface should be commented out.
# Revision C (newer revision)
source [find interface/stlink-v2-1.cfg]
# Revision A and B (older revisions)
# source [find interface/stlink-v2.cfg]
source [find target/stm32f3x.cfg]

32
openocd.gdb Normal file
View File

@@ -0,0 +1,32 @@
target extended-remote :3333
# print demangled symbols
set print asm-demangle on
# detect unhandled exceptions, hard faults and panics
break DefaultHandler
break UserHardFault
break rust_begin_unwind
# *try* to stop at the user entry point (it might be gone due to inlining)
break main
monitor arm semihosting enable
# # send captured ITM to the file itm.fifo
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
# # 8000000 must match the core clock frequency
# monitor tpiu config internal itm.txt uart off 8000000
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
# # 8000000 must match the core clock frequency
# # 2000000 is the frequency of the SWO pin
# monitor tpiu config external uart off 8000000 2000000
# # enable ITM port 0
# monitor itm port 0 on
load
# start the process but immediately halt the processor
stepi

View File

@@ -1,28 +0,0 @@
//! Prints "Hello, world!" on the OpenOCD console using semihosting
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! #[macro_use]
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//!
//! use cortex_m::asm;
//!
//! fn main() {
//! hprintln!("Hello, world!");
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,45 +0,0 @@
//! Sends "Hello, world!" through the ITM port 0
//!
//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the
//! microcontroller's SWO pin to the SWD interface. Note that some development
//! boards don't provide this option.
//!
//! ITM is much faster than semihosting. Like 4 orders of magnitude or so.
//!
//! You'll need [`itmdump`] to receive the message on the host plus you'll need
//! to uncomment OpenOCD's ITM support in `.gdbinit`.
//!
//! [`itmdump`]: https://docs.rs/itm/0.1.1/itm/
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! #[macro_use]
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//!
//! use cortex_m::{asm, interrupt, peripheral};
//!
//! fn main() {
//! interrupt::free(
//! |cs| {
//! let itm = peripheral::ITM.borrow(&cs);
//!
//! iprintln!(&itm.stim[0], "Hello, world!");
//! },
//! );
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,39 +0,0 @@
//! Redirecting `panic!` messages
//!
//! The `cortex-m-rt` crate provides two options to redirect `panic!` messages
//! through these two Cargo features:
//!
//! - `panic-over-semihosting`. `panic!` messages will be printed to the OpenOCD
//! console using semihosting. This is slow.
//!
//! - `panic-over-itm`. `panic!` messages will be send through the ITM port 0.
//! This is much faster but requires ITM support on the device.
//!
//! If neither of these options is specified then the `panic!` message will be
//! lost. Note that all `panic!`s will trigger a debugger breakpoint.
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//!
//! use cortex_m::asm;
//!
//! fn main() {
//! panic!("Oops");
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,62 +0,0 @@
//! Debugging a crash (exception)
//!
//! The `cortex-m-rt` crate provides functionality for this through a default
//! exception handler. When an exception is hit, the default handler will
//! trigger a breakpoint and in this debugging context the stacked registers
//! are accessible.
//!
//! In you run the example below, you'll be able to inspect the state of your
//! program under the debugger using these commands:
//!
//! ```
//! (gdb) # Stacked registers = program state during the crash
//! (gdb) print/x *_sr
//! $1 = cortex_m::exception::StackedRegisters {
//! r0 = 0x2fffffff,
//! r1 = 0x2fffffff,
//! r2 = 0x0,
//! r3 = 0x0,
//! r12 = 0x0,
//! lr = 0x8000443,
//! pc = 0x8000190,
//! xpsr = 0x61000200,
//! }
//!
//! (gdb) # What exception was triggered?
//! (gdb) print _e
//! $2 = cortex_m::exception::Exception::HardFault
//!
//! (gdb) # Where did we come from?
//! (gdb) backtrace
//! ```
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//!
//! use core::ptr;
//!
//! use cortex_m::asm;
//!
//! fn main() {
//! // Read an invalid memory address
//! unsafe {
//! ptr::read_volatile(0x2FFF_FFFF as *const u32);
//! }
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,40 +0,0 @@
//! Register an interrupt handler
//!
//! NOTE Requires a device crate generated using `svd2rust`
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//! // NOTE this is the device crate
//! extern crate stm32f30x;
//!
//! use cortex_m::asm;
//! use stm32f30x::interrupt;
//!
//! fn main() {}
//!
//! // NOTE each interrupt handler has a different signature
//! extern "C" fn my_interrupt_handler(_ctxt: interrupt::Tim7) {
//! asm::bkpt();
//! }
//!
//! extern "C" fn another_interrupt_handler(_ctxt: interrupt::Exti0) {
//! asm::bkpt();
//! }
//!
//! // Here we override only two interrupt handlers, the rest of interrupt are
//! // handled by the same interrupt handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: interrupt::Handlers = interrupt::Handlers {
//! Tim7: my_interrupt_handler,
//! Exti0: another_interrupt_handler,
//! ..interrupt::DEFAULT_HANDLERS
//! };
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,50 +0,0 @@
//! Overriding an exception
//!
//! **NOTE** You have to disable the `cortex-m-rt` crate's "exceptions" feature
//! to make this work.
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//!
//! use core::ptr;
//!
//! use cortex_m::{asm, exception};
//!
//! fn main() {
//! unsafe {
//! // Invalid memory access
//! ptr::read_volatile(0x2FFF_FFFF as *const u32);
//! }
//! }
//!
//! extern "C" fn hard_fault(_: exception::HardFault) {
//! // You'll hit this breakpoint rather than the one in cortex-m-rt
//! asm::bkpt()
//! }
//!
//! // When the "exceptions" feature is disabled, you'll have to provide this symbol
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.exceptions"]
//! static EXCEPTIONS: exception::Handlers = exception::Handlers {
//! // This is the exception handler override
//! hard_fault: hard_fault,
//! ..exception::DEFAULT_HANDLERS
//! };
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,75 +0,0 @@
//! How to use the heap and a dynamic memory allocator
//!
//! To compile this example you'll need to build the collections crate as part
//! of the Xargo sysroot. To do that change the Xargo.toml file to look like
//! this:
//!
//! ``` text
//! [dependencies.core]
//! [dependencies.collections] # new
//!
//! [dependencies.compiler_builtins]
//! features = ["mem"]
//! git = "https://github.com/rust-lang-nursery/compiler-builtins"
//! stage = 1
//! ```
//!
//! This example depends on the alloc-cortex-m crate so you'll have to add it
//! to your Cargo.toml:
//!
//! ``` text
//! # or edit the Cargo.toml file manually
//! $ cargo add alloc-cortex-m
//! ```
//!
//! ```
//!
//! #![feature(collections)]
//! #![feature(used)]
//! #![no_std]
//!
//! // This is the allocator crate; you can use a different one
//! extern crate alloc_cortex_m;
//! #[macro_use]
//! extern crate collections;
//! #[macro_use]
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//!
//! use cortex_m::asm;
//!
//! fn main() {
//! // Initialize the allocator
//! unsafe {
//! extern "C" {
//! // Start of the heap
//! static mut _sheap: usize;
//! }
//!
//! // Size of the heap in words (1 word = 4 bytes)
//! // WARNING: The bigger the heap the greater the chance to run into a
//! // stack overflow (collision between the stack and the heap)
//! const SIZE: isize = 256;
//!
//! // End of the heap
//! let _eheap = (&mut _sheap as *mut _).offset(SIZE);
//!
//! alloc_cortex_m::init(&mut _sheap as *mut _, _eheap);
//! }
//!
//! // Growable array allocated on the heap
//! let xs = vec![0, 1, 2];
//! hprintln!("{:?}", xs);
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".rodata.interrupts"]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,9 +0,0 @@
//! Examples
// Auto-generated. Do not modify.
pub mod _0_hello;
pub mod _1_itm;
pub mod _2_panic;
pub mod _3_crash;
pub mod _4_register_interrupt_handler;
pub mod _5_override_exception_handler;
pub mod _6_allocator;

View File

@@ -1,292 +0,0 @@
//! A template for building applications for ARM Cortex-M microcontrollers
//!
//! # Dependencies
//!
//! - Nightly Rust toolchain: `rustup default nightly`
//! - ARM linker: `sudo apt-get install binutils-arm-none-eabi`
//! - Cargo `clone` subcommand: `cargo install cargo-clone`
//! - GDB: `sudo apt-get install gdb-arm-none-eabi`
//! - OpenOCD: `sudo apt-get install OpenOCD`
//! - Xargo: `cargo install xargo`
//! - [Optional] Cargo `add` subcommand: `cargo install cargo-edit`
//!
//! # Usage
//!
//! - Clone this crate
//!
//! ``` text
//! $ cargo clone cortex-m-quickstart && cd $_
//! ```
//!
//! - Change the crate name, author and version
//!
//! ``` text
//! $ edit Cargo.toml && head $_
//! [package]
//! authors = ["Jorge Aparicio <jorge@japaric.io>"]
//! name = "demo"
//! version = "0.1.0"
//! ```
//!
//! - Specify the memory layout of the target device
//!
//! (Note that some board support crates may provide this file for you (check
//! the crate documentation). If you are using one that does that then remove
//! *both* the `memory.x` and `build.rs` files.)
//!
//! ``` text
//! $ edit memory.x && cat $_
//! MEMORY
//! {
//! /* NOTE K = KiBi = 1024 bytes */
//! FLASH : ORIGIN = 0x08000000, LENGTH = 256K
//! RAM : ORIGIN = 0x20000000, LENGTH = 40K
//! }
//!
//! /* This is where the call stack will be allocated. */
//! /* The stack is of the full descending type. */
//! /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
//! _stack_start = ORIGIN(RAM) + LENGTH(RAM);
//! ```
//!
//! - Optionally, set a default build target
//!
//! ``` text
//! $ cat >>.cargo/config <<'EOF'
//! [build]
//! target = "thumbv7em-none-eabihf"
//! EOF
//! ```
//!
//! - Very likely, depend on a device or a BSP (Board Support Package) crate.
//!
//! ``` text
//! # add a device crate, or
//! $ cargo add stm32f30x
//!
//! # add a board support crate
//! $ cargo add f3
//! ```
//!
//! - Write the application or start from one of the examples
//!
//! ``` text
//! $ rm -r src/* && cp examples/hello.rs src/main.rs
//! ```
//!
//! - Disable incremental compilation. It doesn't work for embedded development.
//! You'll hit nonsensical linker errors if you use it.
//!
//! ``` text
//! $ unset CARGO_INCREMENTAL
//! ```
//!
//! - Build the application
//!
//! ``` text
//! # NOTE this command requires `arm-none-eabi-ld` to be in $PATH
//! $ xargo build --release
//!
//! $ arm-none-eabi-readelf -A target/thumbv7em-none-eabihf/release/demo
//! Attribute Section: aeabi
//! File Attributes
//! Tag_conformance: "2.09"
//! Tag_CPU_arch: v7E-M
//! Tag_CPU_arch_profile: Microcontroller
//! Tag_THUMB_ISA_use: Thumb-2
//! Tag_FP_arch: VFPv4-D16
//! Tag_ABI_PCS_GOT_use: direct
//! Tag_ABI_FP_denormal: Needed
//! Tag_ABI_FP_exceptions: Needed
//! Tag_ABI_FP_number_model: IEEE 754
//! Tag_ABI_align_needed: 8-byte
//! Tag_ABI_align_preserved: 8-byte, except leaf SP
//! Tag_ABI_HardFP_use: SP only
//! Tag_ABI_VFP_args: VFP registers
//! Tag_ABI_optimization_goals: Aggressive Speed
//! Tag_CPU_unaligned_access: v6
//! Tag_FP_HP_extension: Allowed
//! Tag_ABI_FP_16bit_format: IEEE 754
//! ```
//!
//! - Flash the program
//!
//! ``` text
//! # Launch OpenOCD on a terminal
//! $ openocd -f (..)
//! ```
//!
//! ``` text
//! # Start debug session
//! $ arm-none-eabi-gdb target/..
//! ```
//!
//! **NOTE** As of nightly-2017-05-14 or so and cortex-m-quickstart v0.1.6 you
//! can simply run `cargo run` or `cargo run --example $example` to build the
//! program, and immediately start a debug session. IOW, it lets you omit the
//! `arm-none-eabi-gdb` command.
//!
//! ``` text
//! $ cargo run --example hello
//! > # drops you into a GDB session
//! ```
//!
//! # Examples
//!
//! Check the [examples module](./examples/index.html)
//!
//! # Troubleshooting
//!
//! This section contains fixes for common errors encountered when the
//! `cortex-m-quickstart` template is misused.
//!
//! ## Forgot to launch an OpenOCD instance
//!
//! Error message:
//!
//! ``` text
//! $ arm-none-eabi-gdb target/..
//! Reading symbols from hello...done.
//! .gdbinit:1: Error in sourced command file:
//! :3333: Connection timed out.
//! ```
//!
//! Solution: Launch OpenOCD on other terminal. See [Usage] section.
//!
//! [Usage]: ./index.html#usage
//!
//! ## Didn't modify the `memory.x` linker script
//!
//! Error message:
//!
//! ``` text
//! $ xargo build
//! Compiling demo v0.1.0 (file:///home/japaric/tmp/demo)
//! error: linking with `arm-none-eabi-ld` failed: exit code: 1
//! |
//! = note: "arm-none-eabi-ld" "-L" (..)
//! = note: arm-none-eabi-ld: address 0xbaaab838 of hello section `.text' is ..
//! arm-none-eabi-ld: address 0xbaaab838 of hello section `.text' is ..
//! arm-none-eabi-ld:
//! Invalid '.rodata.exceptions' section.
//! Make sure to place a static with type `cortex_m::exception::Handlers`
//! in that section (cf. #[link_section]) ONLY ONCE.
//! ```
//!
//! Solution: Specify your device memory layout in the `memory.x` linker script.
//! See [Usage] section.
//!
//! ## Forgot to set a default build target
//!
//! Error message:
//!
//! ``` text
//! $ xargo build
//! (..)
//! Compiling cortex-m-semihosting v0.1.3
//! error[E0463]: can't find crate for `std`
//!
//! error: aborting due to previous error
//! ```
//!
//! Solution: Set a default build target in the `.cargo/config` file
//! (see [Usage] section), or call Xargo with `--target` flag:
//! `xargo build --target thumbv7em-none-eabi`.
//!
//! ## Called OpenOCD with wrong arguments
//!
//! Error message:
//!
//! ``` text
//! $ openocd -f ..
//! (..)
//! Error: open failed
//! in procedure 'init'
//! in procedure 'ocd_bouncer'
//! ```
//!
//! Solution: Correct the OpenOCD arguments. Check the
//! `/usr/share/openocd/scripts` directory (exact location varies per
//! distribution / OS) for a list of scripts that can be used.
//!
//! ## Used Cargo instead of Xargo
//!
//! Error message:
//!
//! ``` text
//! $ cargo build
//! Compiling cortex-m-rt v0.2.0
//! error[E0463]: can't find crate for `core`
//! |
//! = note: the `thumbv7em-none-eabihf` target may not be installed
//!
//! error: aborting due to previous error
//! ```
//!
//! Solution: Use `xargo build`.
//!
//! ## Used the stable toolchain
//!
//! Error message:
//!
//! ``` text
//! $ xargo build
//! error: failed to run `rustc` to learn about target-specific information
//!
//! To learn more, run the command again with --verbose.
//! ```
//!
//! Solution: Switch to the nightly toolchain with `rustup default nightly`.
//!
//! ## Used `CARGO_INCREMENTAL=1`
//!
//! Error message:
//!
//! ``` text
//! $ xargo build
//! error: linking with `arm-none-eabi-ld` failed: exit code: 1
//! |
//! = note: "arm-none-eabi-ld" (..)
//! = note: arm-none-eabi-ld:
//! You must specify the exception handlers.
//! Create a non `pub` static variable with type
//! `cortex_m::exception::Handlers` and place it in the
//! '.rodata.exceptions' section. (cf. #[link_section]). Apply the
//! `#[used]` attribute to the variable to make it reach the linker.
//! arm-none-eabi-ld:
//! Invalid '.rodata.exceptions' section.
//! Make sure to place a static with type `cortex_m::exception::Handlers`
//! in that section (cf. #[link_section]) ONLY ONCE.
//! ```
//!
//! Solution: `$ unset CARGO_INCREMENAL`. And to be on the safe side, call
//! `cargo clean` and thrash the Xargo sysroot: `$ rm -rf ~/.xargo`
//!
//! ## Used `gdb` instead of `arm-none-eabi-gdb`
//!
//! Error message:
//!
//! ``` text
//! $ gdb target/..
//! Reading symbols from hello...done.
//! warning: Architecture rejected target-supplied description
//! warning: Cannot convert floating-point register value to ..
//! value has been optimized out
//! Cannot write the dashboard
//! Traceback (most recent call last):
//! File "<string>", line 353, in render
//! File "<string>", line 846, in lines
//! gdb.error: Frame is invalid.
//! 0x00000000 in ?? ()
//! semihosting is enabled
//! Loading section .text, size 0xd88 lma 0x8000000
//! Start address 0x8000000, load size 3464
//! .gdbinit:6: Error in sourced command file:
//! Remote connection closed
//! ```
//!
//! Solution: Use `arm-none-eabi-gdb target/..`
#![no_std]
pub mod examples;

17
src/main.rs Normal file
View File

@@ -0,0 +1,17 @@
#![no_std]
#![no_main]
// pick a panicking behavior
extern crate panic_halt; // you can put a breakpoint on `rust_begin_unwind` to catch panics
// extern crate panic_abort; // requires nightly
// extern crate panic_itm; // logs messages over ITM; requires ITM support
// extern crate panic_semihosting; // logs messages to the host stderr; requires a debugger
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
loop {
// your code goes here
}
}