143 Commits

Author SHA1 Message Date
Adam Greig
18bb680710 Merge pull request #100 from rubberduck203/master
Fixes #99: Disambiguates VSCode Tasks
2020-11-09 12:00:44 +00:00
Christopher J. McClellan
eb68e8bba9 Fixes #99: Disambiguates VSCode Tasks
Using the equivalent command line as the task name caused some confusion.
Users were under the impression that they could use any valid cargo command as a preLaunchTask in the launch configurations.
2020-11-09 06:23:51 -05:00
Daniel Egger
3cbcb9956a Merge pull request #98 from thalesfragoso/alloc-example
Fix alloc example
2020-10-13 08:49:11 +02:00
Thales Fragoso
5c6a17c0a6 Fix alloc example 2020-10-12 23:16:25 -03:00
Thales
be44af69cc Merge pull request #96 from hug-dev/add-armv8m-targets
Also add examples to target Armv8-M
2020-10-04 16:44:04 -03:00
Hugues de Valon
f18b5af0a2 Also add examples to target Armv8-M
Signed-off-by: Hugues de Valon <hugues.devalon@arm.com>
2020-10-04 19:55:23 +01:00
Daniel Egger
e1e98857af Merge pull request #95 from Dirbaio/Dirbaio-patch-1
Add --nmagic linker arg, for unaligned flash origin support.
2020-09-13 23:58:08 +02:00
Dario Nieuwenhuis
8047986061 Add --nmagic linker arg, for unaligned flash origin support.
Without this, the linker places some extra program header entries that can confuse flashing tools.

Many thanks to @jonas-schievink for pointing me to this flag in Matrix.
2020-09-03 22:07:01 +02:00
Daniel Egger
ae6ad14ad4 Merge pull request #92 from rust-embedded/readd-build
Re-add build script with note this time
2020-07-22 00:28:50 +02:00
Daniel Egger
541c7df215 Update build.rs
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
2020-07-22 00:27:48 +02:00
Adam Greig
4e9999f06f Re-add build script with note this time 2020-07-21 23:23:49 +01:00
Adam Greig
33034ee397 Merge pull request #89 from hyperslv/extern_crate_to_use
Replace unidiomatic 'extern crate' to 'use x as _'
2020-06-14 17:07:38 +01:00
hyperslv
b12af511b9 Replace unidiomatic 'extern crate' to 'use x as _' 2020-06-14 13:38:05 +03:00
Daniel Egger
3571fc9a79 Merge pull request #87 from rust-embedded/rm-build-rs
Remove unnecessary build.rs
2020-04-17 23:50:16 +02:00
Adam Greig
8e29b31da4 Remove unnecessary build.rs 2020-04-17 00:24:02 +01:00
Adam Greig
1a60c1d944 Merge pull request #84 from rubberduck203/update-vscode-docs
Update vscode docs to reflect fixes from PR #83
2020-03-05 12:10:50 +00:00
Christopher J. McClellan
888ddb7e0d Update vscode docs to reflect fixes from PR #83
9977613eac
6c26219611

https://github.com/rust-embedded/cortex-m-quickstart/pull/83
2020-03-05 07:02:29 -05:00
Adam Greig
23a74e9add Merge pull request #83 from david-boles/patch-1
Corrected default VSCode build task.
2020-03-05 11:29:07 +00:00
David Boles
9977613eac Corrected default VSCode clean task. 2020-03-04 19:02:05 -05:00
David Boles
6c26219611 Corrected default VSCode build task. 2020-03-04 14:07:32 -05:00
Adam Greig
cda24a671d Merge pull request #82 from rubberduck203/vscode
VS Code build tasks
2020-02-27 22:03:30 +00:00
Christopher J. McClellan
ee3eca20d3 Add vscode build tasks for examples and release 2020-02-07 19:22:11 -05:00
Daniel Egger
e7025922f8 Merge pull request #79 from rubberduck203/track-debug-conf
Track launch.json, tasks.json, md & svd files
2020-01-01 16:36:34 +01:00
Christopher J. McClellan
55bc69690a Add recommended extensions file 2020-01-01 08:02:15 -05:00
Christopher J. McClellan
b741ef37f5 Track launch.json, tasks.json, md & svd files
Ignoring the .vscode/ directory is good default behavior,
but it's probably best to track the files that define build tasks, debug
configs, documentation, and any system view description files.

The gitignore.io sample takes the same approach.
https://www.gitignore.io/api/visualstudiocode

> We in the VS Code team share debug and task specific settings as well because we want our team to have the same set of debug targets and task targets for VS Code.

https://stackoverflow.com/a/32979933/3198973

Even people who vehemently argue that .vscode shouldn't be track, agree
that complex debug configs should be tracked and shared.

> The only .vscode that makes sense to include are complex launch configs for debugging.

https://stackoverflow.com/a/47668283/3198973
2020-01-01 07:43:32 -05:00
Jonathan 'theJPster' Pallant
a546d1b00c Merge pull request #78 from rubberduck203/vscode
VS Code Support
2019-12-27 17:49:21 +00:00
Christopher J. McClellan
57de818726 Add VS Code support
Adds basic configuration for VS Code for QEMU and STM32F3DISCOVERY.
2019-12-25 06:46:43 -05:00
Emil Fresk
3ca2bb9a46 Merge pull request #75 from rust-embedded/cortex-m-rt_fix
Update of cortex-m-rt for coming stable breakage
2019-08-13 20:17:27 +02:00
Emil Fresk
ac5d1fcb10 Update of cortex-m-rt for coming stable breakage 2019-08-13 20:13:09 +02:00
Emil Fresk
f5a8721006 Merge pull request #74 from rust-embedded/fix-73
Update instructions for device example, closes #73
2019-08-06 20:17:58 +02:00
Adam Greig
d018974c6f Update instructions for device example, closes #73 2019-07-23 20:59:12 -06:00
Daniel Egger
77e60809b5 Merge pull request #72 from ssendev/print-panic
add openocd.gdb hint how to print panic immediatly
2019-07-23 23:26:20 +02:00
Manuel Thomassen
97788b8215 add openocd.gdb hint how to print panic immediatly 2019-07-22 17:35:15 +02:00
Daniel Egger
08e6ba02f1 Merge pull request #71 from josephpenafiel/patch-1
added missing import
2019-07-10 00:09:51 +02:00
Joseph Penafiel
eae0512459 added missing import
NVIC wasn't imported from the stm32f30x crate
2019-07-09 10:08:51 -05:00
Adam Greig
9610e04635 Merge pull request #69 from rust-embedded/bump-everything
Bump dependency versions
2019-06-04 19:14:19 -06:00
Daniel Egger
cc52aef020 Bump dependency versions 2019-06-04 21:35:21 +02:00
Adam Greig
6919488412 Merge pull request #68 from rust-embedded/bt_limit
Added backtrace limit to mitigate infinite backtraces
2019-02-05 21:56:28 +00:00
Emil Fresk
73bae533c4 Added backtrace limit to mitigate infinite backtraces 2019-02-05 20:17:20 +01:00
Emil Fresk
ac344b967f Merge pull request #66 from jacobrosenthal/patch-1
update interrupt usage
2019-01-30 19:54:09 +01:00
Jacob Rosenthal
c6599f3686 update interrupt usage 2019-01-29 15:12:07 -07:00
Adam Greig
3aa5ea9fd3 Merge pull request #64 from sstelfox/fix_breakpoint
Adjust the default breakpoint name to match cortex-m-rt pull #144
2019-01-22 08:38:49 +00:00
Sam Stelfox
26baac1bf3 Adjust the default breakpoint name to match cortex-m-rt pull #144 2019-01-21 23:39:45 -05:00
Emil Fresk
2d7405fc04 Merge pull request #61 from rubberduck203/tests
Add example of writing tests that run on host machine
2019-01-01 11:34:22 +01:00
Christopher J. McClellan
e58549b2ec Add more documentation for testing on host 2018-12-31 07:01:16 -05:00
Emil Fresk
9ee8b84217 Merge pull request #62 from rubberduck203/coc
Fixes code of conduct link.
2018-12-31 11:35:55 +01:00
Christopher J. McClellan
0e2aadf8f2 Make sure we can actually test prod code 2018-12-30 19:55:24 -05:00
Christopher J. McClellan
e7138e0e2a Fixes code of conduct link.
Closes #60
2018-12-30 19:24:24 -05:00
Christopher J. McClellan
c142db6e23 Add example of writing tests that run on host machine 2018-12-30 19:17:58 -05:00
Emil Fresk
207bca35f4 Merge pull request #59 from rust-embedded/loop_crash_fix
Workaround for loop {} until it is fixed
2018-11-20 15:33:23 +01:00
Emil Fresk
f9570c7c65 Workaround for loop {} until it is fixed 2018-11-20 07:58:38 +01:00
Adam Greig
f47d1633af Merge pull request #57 from rust-embedded/sh
use hprint macros and NVIC::pend; fix allocator example
2018-11-10 00:10:46 +00:00
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
37 changed files with 814 additions and 1609 deletions

View File

@@ -1,31 +1,40 @@
[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] [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 = [ rustflags = [
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
# LLD (shipped with the Rust toolchain) is used as the default linker
"-C", "link-arg=-Tlink.x", "-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] [build]
runner = 'arm-none-eabi-gdb' # Pick ONE of these compilation targets
rustflags = [ # target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
"-C", "link-arg=-Tlink.x", target = "thumbv7m-none-eabi" # Cortex-M3
"-C", "linker=arm-none-eabi-ld", # target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
"-Z", "linker-flavor=ld", # target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
] # target = "thumbv8m.base-none-eabi" # Cortex-M23
# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU)
[target.thumbv7em-none-eabihf] # target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)
runner = 'arm-none-eabi-gdb'
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "linker=arm-none-eabi-ld",
"-Z", "linker-flavor=ld",
]

View File

@@ -1,21 +0,0 @@
target remote :3333
# print demangled symbols by default
set print asm-demangle on
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

9
.gitignore vendored
View File

@@ -1,4 +1,13 @@
**/*.rs.bk **/*.rs.bk
.#*
.gdb_history .gdb_history
Cargo.lock Cargo.lock
target/ target/
# editor files
.vscode/*
!.vscode/*.md
!.vscode/*.svd
!.vscode/launch.json
!.vscode/tasks.json
!.vscode/extensions.json

109
.vscode/README.md vendored Normal file
View File

@@ -0,0 +1,109 @@
# VS Code Configuration
Example configurations for debugging programs in-editor with VS Code.
This directory contains configurations for two platforms:
- `LM3S6965EVB` on QEMU
- `STM32F303x` via OpenOCD
## Required Extensions
If you have the `code` command in your path, you can run the following commands to install the necessary extensions.
```sh
code --install-extension rust-lang.rust
code --install-extension marus25.cortex-debug
```
Otherwise, you can use the Extensions view to search for and install them, or go directly to their marketplace pages and click the "Install" button.
- [Rust Language Server (RLS)](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust)
- [Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug)
## Use
The quickstart comes with two debug configurations.
Both are configured to build the project, using the default settings from `.cargo/config`, prior to starting a debug session.
1. QEMU: Starts a debug session using an emulation of the `LM3S6965EVB` mcu.
- This works on a fresh `cargo generate` without modification of any of the settings described above.
- Semihosting output will be written to the Output view `Adapter Output`.
- `ITM` logging does not work with QEMU emulation.
2. OpenOCD: Starts a debug session for a `STM32F3DISCOVERY` board (or any `STM32F303x` running at 8MHz).
- Follow the instructions above for configuring the build with `.cargo/config` and the `memory.x` linker script.
- `ITM` output will be written to the Output view `SWO: ITM [port: 0, type: console]` output.
### Git
Files in the `.vscode/` directory are `.gitignore`d by default because many files that may end up in the `.vscode/` directory should not be committed and shared.
If you would like to save this debug configuration to your repository and share it with your team, you'll need to explicitly `git add` the files to your repository.
```sh
git add -f .vscode/launch.json
git add -f .vscode/tasks.json
git add -f .vscode/*.svd
```
## Customizing for other targets
For full documentation, see the [Cortex-Debug][cortex-debug] repository.
### Device
Some configurations use this to automatically find the SVD file.
Replace this with the part number for your device.
```json
"device": "STM32F303VCT6",
```
### OpenOCD Config Files
The `configFiles` property specifies a list of files to pass to OpenOCD.
```json
"configFiles": [
"interface/stlink-v2-1.cfg",
"target/stm32f3x.cfg"
],
```
See the [OpenOCD config docs][openocd-config] for more information and the [OpenOCD repository for available configuration files][openocd-repo].
### SVD
The SVD file is a standard way of describing all registers and peripherals of an ARM Cortex-M mCU.
Cortex-Debug needs this file to display the current register values for the peripherals on the device.
You can probably find the SVD for your device on the vendor's website.
For example, the STM32F3DISCOVERY board uses an mcu from the `STM32F303x` line of processors.
All the SVD files for the STM32F3 series are available on [ST's Website][stm32f3].
Download the [stm32f3 SVD pack][stm32f3-svd], and copy the `STM32F303.svd` file into `.vscode/`.
This line of the config tells the Cortex-Debug plug in where to find the file.
```json
"svdFile": "${workspaceRoot}/.vscode/STM32F303.svd",
```
For other processors, simply copy the correct `*.svd` file into the project and update the config accordingly.
### CPU Frequency
If your device is running at a frequency other than 8MHz, you'll need to modify this line of `launch.json` for the `ITM` output to work correctly.
```json
"cpuFrequency": 8000000,
```
### Other GDB Servers
For information on setting up GDB servers other than OpenOCD, see the [Cortex-Debug repository][cortex-debug].
[cortex-debug]: https://github.com/Marus/cortex-debug
[stm32f3]: https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-mainstream-mcus/stm32f3-series.html#resource
[stm32f3-svd]: https://www.st.com/resource/en/svd/stm32f3_svd.zip
[openocd-config]: http://openocd.org/doc/html/Config-File-Guidelines.html
[openocd-repo]: https://sourceforge.net/p/openocd/code/ci/master/tree/tcl/

14
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,14 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"rust-lang.rust",
"marus25.cortex-debug",
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
]
}

52
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,52 @@
{
/*
* Requires the Rust Language Server (RLS) and Cortex-Debug extensions
* https://marketplace.visualstudio.com/items?itemName=rust-lang.rust
* https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug
*/
"version": "0.2.0",
"configurations": [
{
"type": "cortex-debug",
"request": "launch",
"name": "Debug (QEMU)",
"servertype": "qemu",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Cargo Build (debug)",
"runToMain": true,
"executable": "./target/thumbv7m-none-eabi/debug/{{project-name}}",
/* Run `cargo build --example hello` and uncomment this line to run semi-hosting example */
//"executable": "./target/thumbv7m-none-eabi/debug/examples/hello",
"cpu": "cortex-m3",
"machine": "lm3s6965evb",
},
{
/* Configuration for the STM32F303 Discovery board */
"type": "cortex-debug",
"request": "launch",
"name": "Debug (OpenOCD)",
"servertype": "openocd",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Cargo Build (debug)",
"runToMain": true,
"executable": "./target/thumbv7em-none-eabihf/debug/{{project-name}}",
/* Run `cargo build --example itm` and uncomment this line to run itm example */
// "executable": "./target/thumbv7em-none-eabihf/debug/examples/itm",
"device": "STM32F303VCT6",
"configFiles": [
"interface/stlink-v2-1.cfg",
"target/stm32f3x.cfg"
],
"svdFile": "${workspaceRoot}/.vscode/STM32F303.svd",
"swoConfig": {
"enabled": true,
"cpuFrequency": 8000000,
"swoFrequency": 2000000,
"source": "probe",
"decoders": [
{ "type": "console", "label": "ITM", "port": 0 }
]
}
}
]
}

63
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,63 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
/*
* This is the default cargo build task,
* but we need to provide a label for it,
* so we can invoke it from the debug launcher.
*/
"label": "Cargo Build (debug)",
"type": "process",
"command": "cargo",
"args": ["build"],
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Cargo Build (release)",
"type": "process",
"command": "cargo",
"args": ["build", "--release"],
"problemMatcher": [
"$rustc"
],
"group": "build"
},
{
"label": "Cargo Build Examples (debug)",
"type": "process",
"command": "cargo",
"args": ["build","--examples"],
"problemMatcher": [
"$rustc"
],
"group": "build"
},
{
"label": "Cargo Build Examples (release)",
"type": "process",
"command": "cargo",
"args": ["build","--examples", "--release"],
"problemMatcher": [
"$rustc"
],
"group": "build"
},
{
"label": "Cargo Clean",
"type": "process",
"command": "cargo",
"args": ["clean"],
"problemMatcher": [],
"group": "build"
},
]
}

View File

@@ -1,108 +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.2.1] - 2017-07-14
### Added
- Troubleshooting documentation: how to fix the error of overwriting the
`.cargo/config` file when you meant to append text to it.
### Changed
- Xargo.toml: Changed the source of the `compiler-builtins` crate from git to
the `rust-src` component.
- Expanded the `device` example to do some I/O.
## [v0.2.0] - 2017-07-07
### Changed
- [breaking-change] Bumped the cortex-m and cortex-m-rt versions to v0.3.0.
## [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.2.0...HEAD
[v0.2.0]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.8...v0.2.0
[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,27 +1,36 @@
[package] [package]
authors = ["Jorge Aparicio <jorge@japaric.io>"] authors = ["{{authors}}"]
categories = ["embedded", "no-std"] edition = "2018"
description = "A template for building applications for ARM Cortex-M microcontrollers" readme = "README.md"
keywords = ["arm", "cortex-m", "template"] name = "{{project-name}}"
license = "MIT OR Apache-2.0" version = "0.1.0"
name = "cortex-m-quickstart"
repository = "https://github.com/japaric/cortex-m-quickstart"
version = "0.2.2"
[dependencies] [dependencies]
cortex-m = "0.3.0" cortex-m = "0.6.0"
cortex-m-semihosting = "0.2.0" cortex-m-rt = "0.6.10"
cortex-m-semihosting = "0.3.3"
panic-halt = "0.2.0"
[dependencies.cortex-m-rt] # Uncomment for the panic example.
features = ["abort-on-panic"] # panic-itm = "0.4.1"
version = "0.3.12"
# disable both incremental compilation and parallel codegen to reduce the chances of running into # Uncomment for the allocator example.
# rust-lang/rust#47074 # alloc-cortex-m = "0.4.0"
[profile.dev]
codegen-units = 1 # Uncomment for the device example.
incremental = false # Update `memory.x`, set target to `thumbv7em-none-eabihf` in `.cargo/config`,
# and then use `cargo build --examples device` to build it.
# [dependencies.stm32f3]
# features = ["stm32f303", "rt"]
# version = "0.7.1"
# this lets you use `cargo fix`!
[[bin]]
name = "{{project-name}}"
test = false
bench = false
[profile.release] [profile.release]
debug = true codegen-units = 1 # better optimizations
lto = true 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.

117
README.md
View File

@@ -2,11 +2,115 @@
> A template for building applications for ARM Cortex-M microcontrollers > 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
```
## VS Code
This template includes launch configurations for debugging CortexM programs with Visual Studio Code located in the `.vscode/` directory.
See [.vscode/README.md](./.vscode/README.md) for more information.
If you're not using VS Code, you can safely delete the directory from the generated project.
# License # License
Licensed under either of This template is licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0) http://www.apache.org/licenses/LICENSE-2.0)
@@ -20,3 +124,12 @@ at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted 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 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. 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]: https://www.rust-lang.org/policies/code-of-conduct
[team]: https://github.com/rust-embedded/wg#the-cortex-m-team

View File

@@ -1,6 +0,0 @@
[dependencies.core]
stage = 0
[dependencies.compiler_builtins]
features = ["mem"]
stage = 1

View File

@@ -1,10 +1,21 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
fn main() { fn main() {
// Put the linker script somewhere the linker can find it // Put `memory.x` in our output directory and ensure it's
// on the linker search path.
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x")) File::create(out.join("memory.x"))
.unwrap() .unwrap()
@@ -12,6 +23,9 @@ fn main() {
.unwrap(); .unwrap();
println!("cargo:rustc-link-search={}", out.display()); println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rerun-if-changed=build.rs"); // By default, Cargo will re-run a build script whenever
// any file in the project changes. By specifying `memory.x`
// here, we ensure the build script is only re-run when
// `memory.x` is changed.
println!("cargo:rerun-if-changed=memory.x"); println!("cargo:rerun-if-changed=memory.x");
} }

View File

@@ -1,22 +1,6 @@
//! How to use the heap and a dynamic memory allocator //! How to use the heap and a dynamic memory allocator
//! //!
//! To compile this example you'll need to build the collections crate as part //! This example depends on the alloc-cortex-m crate so you'll have to add it to your Cargo.toml:
//! of the Xargo sysroot. To do that change the Xargo.toml file to look like
//! this:
//!
//! ``` text
//! [dependencies.core]
//! stage = 0
//!
//! [dependencies.collections] # NEW
//! stage = 0
//!
//! [dependencies.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 //! ``` text
//! # or edit the Cargo.toml file manually //! # or edit the Cargo.toml file manually
@@ -25,55 +9,48 @@
//! //!
//! --- //! ---
#[allow(deprecated)] #![feature(alloc_error_handler)]
#![feature(collections)] #![no_main]
#![feature(used)]
#![no_std] #![no_std]
// This is the allocator crate; you can use a different one extern crate alloc;
extern crate alloc_cortex_m; use panic_halt as _;
#[macro_use]
extern crate collections;
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate cortex_m_semihosting;
use core::fmt::Write; use self::alloc::vec;
use core::alloc::Layout;
use alloc_cortex_m::CortexMHeap;
use cortex_m::asm; use cortex_m::asm;
use cortex_m_semihosting::hio; use cortex_m_rt::entry;
use cortex_m_semihosting::{hprintln, debug};
fn main() { // this is the allocator the application will use
// Initialize the allocator #[global_allocator]
unsafe { static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
extern "C" {
// Start of the heap
static mut _sheap: usize;
}
// Size of the heap in words (1 word = 4 bytes) const HEAP_SIZE: usize = 1024; // in bytes
// NOTE 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 #[entry]
let _eheap = (&mut _sheap as *mut _).offset(SIZE); fn main() -> ! {
// Initialize the allocator BEFORE you use it
alloc_cortex_m::init(&mut _sheap, _eheap); unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE) }
}
// Growable array allocated on the heap // Growable array allocated on the heap
let xs = vec![0, 1, 2]; let xs = vec![0, 1, 2];
let mut stdout = hio::hstdout().unwrap(); hprintln!("{:?}", xs).unwrap();
writeln!(stdout, "{:?}", 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 // define what happens in an Out Of Memory (OOM) condition
#[link_section = ".vector_table.interrupts"] #[alloc_error_handler]
#[used] fn alloc_error(_layout: Layout) -> ! {
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt(); asm::bkpt();
loop {}
} }

View File

@@ -1,85 +1,96 @@
//! Debugging a crash (exception) //! Debugging a crash (exception)
//! //!
//! The `cortex-m-rt` crate provides functionality for this through a default //! Most crash conditions trigger a hard fault exception, whose handler is defined via
//! exception handler. When an exception is hit, the default handler will //! `exception!(HardFault, ..)`. The `HardFault` handler has access to the exception frame, a
//! trigger a breakpoint and in this debugging context the stacked registers //! snapshot of the CPU registers at the moment of the exception.
//! are accessible.
//! //!
//! In you run the example below, you'll be able to inspect the state of your //! This program crashes and the `HardFault` handler prints to the console the contents of the
//! program under the debugger using these commands: //! `ExceptionFrame` and then triggers a breakpoint. From that breakpoint one can see the backtrace
//! that led to the exception.
//! //!
//! ``` text //! ``` text
//! (gdb) # Exception frame = program state during the crash //! (gdb) continue
//! (gdb) print/x *ef //! Program received signal SIGTRAP, Trace/breakpoint trap.
//! $1 = cortex_m::exception::ExceptionFrame { //! __bkpt () at asm/bkpt.s:3
//! r0 = 0x2fffffff, //! 3 bkpt
//! r1 = 0x2fffffff,
//! r2 = 0x0,
//! r3 = 0x0,
//! r12 = 0x0,
//! lr = 0x8000481,
//! pc = 0x8000460,
//! xpsr = 0x61000000,
//! }
//! //!
//! (gdb) # Where did we come from?
//! (gdb) backtrace //! (gdb) backtrace
//! #0 cortex_m_rt::default_handler (ef=0x20004f54) at (..) //! #0 __bkpt () at asm/bkpt.s:3
//! #1 <signal handler called> //! #1 0x080030b4 in cortex_m::asm::bkpt () at $$/cortex-m-0.5.0/src/asm.rs:19
//! #2 0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..) //! #2 rust_begin_unwind (args=..., file=..., line=99, col=5) at $$/panic-semihosting-0.2.0/src/lib.rs:87
//! #3 0x08000480 in crash::main () at examples/crash.rs:68 //! #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?)
//! ```
//! //!
//! (gdb) # Nail down the location of the crash //! In the console output one will find the state of the Program Counter (PC) register at the time
//! (gdb) disassemble/m ef.pc //! of the exception.
//! Dump of assembler code for function core::ptr::read_volatile<u32>:
//! 408 pub unsafe fn read_volatile<T>(src: *const T) -> T {
//! 0x08000454 <+0>: sub sp, #20
//! 0x08000456 <+2>: mov r1, r0
//! 0x08000458 <+4>: str r0, [sp, #8]
//! 0x0800045a <+6>: ldr r0, [sp, #8]
//! 0x0800045c <+8>: str r0, [sp, #12]
//! //!
//! 409 intrinsics::volatile_load(src) //! ``` text
//! 0x0800045e <+10>: ldr r0, [sp, #12] //! panicked at 'HardFault at ExceptionFrame {
//! 0x08000460 <+12>: ldr r0, [r0, #0] //! r0: 0x2fffffff,
//! 0x08000462 <+14>: str r0, [sp, #16] //! r1: 0x2fffffff,
//! 0x08000464 <+16>: ldr r0, [sp, #16] //! r2: 0x080051d4,
//! 0x08000466 <+18>: str r1, [sp, #4] //! r3: 0x080051d4,
//! 0x08000468 <+20>: str r0, [sp, #0] //! r12: 0x20000000,
//! 0x0800046a <+22>: b.n 0x800046c <core::ptr::read_volatile<u32>+24> //! lr: 0x08000435,
//! pc: 0x08000ab6,
//! xpsr: 0x61000000
//! }', examples/crash.rs:106:5
//! ```
//! //!
//! 410 } //! This register contains the address of the instruction that caused the exception. In GDB one can
//! 0x0800046c <+24>: ldr r0, [sp, #0] //! disassemble the program around this address to observe the instruction that caused the
//! 0x0800046e <+26>: add sp, #20 //! exception.
//! 0x08000470 <+28>: bx lr //!
//! ``` 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. //! 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] #![no_std]
extern crate cortex_m; use panic_halt as _;
extern crate cortex_m_rt;
use core::ptr; use core::ptr;
use cortex_m::asm; use cortex_m_rt::entry;
fn main() { #[entry]
// Read an invalid memory address fn main() -> ! {
unsafe { unsafe {
// read an address outside of the RAM region; this causes a HardFault exception
ptr::read_volatile(0x2FFF_FFFF as *const u32); ptr::read_volatile(0x2FFF_FFFF as *const u32);
} }
}
// As we are not using interrupts, we just register a dummy catch all handler loop {}
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
} }

View File

@@ -1,93 +1,62 @@
//! Using a device crate //! Using a device crate
//! //!
//! Crates generated using [`svd2rust`] are referred to as device crates. These //! Crates generated using [`svd2rust`] are referred to as device crates. These crates provide an
//! crates provides an API to access the peripherals of a device. When you //! API to access the peripherals of a device.
//! depend on one of these crates and the "rt" feature is enabled you don't need
//! link to the cortex-m-rt crate.
//! //!
//! [`svd2rust`]: https://crates.io/crates/svd2rust //! [`svd2rust`]: https://crates.io/crates/svd2rust
//! //!
//! Device crates also provide an `interrupt!` macro to register interrupt //! This example depends on the [`stm32f3`] crate so you'll have to
//! handlers. //! uncomment it in your Cargo.toml.
//! //!
//! This example depends on the [`stm32f103xx`] crate so you'll have to add it //! [`stm32f3`]: https://crates.io/crates/stm32f3
//! to your Cargo.toml.
//!
//! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx
//! //!
//! ``` //! ```
//! $ edit Cargo.toml && cat $_ //! $ edit Cargo.toml && tail $_
//! [dependencies.stm32f103xx] //! [dependencies.stm32f3]
//! features = ["rt"] //! features = ["stm32f303", "rt"]
//! version = "0.7.0" //! version = "0.7.1"
//! ``` //! ```
//! //!
//! You also need to set the build target to thumbv7em-none-eabihf,
//! typically by editing `.cargo/config` and uncommenting the relevant target line.
//!
//! --- //! ---
#![deny(warnings)] #![no_main]
#![feature(const_fn)]
#![no_std] #![no_std]
extern crate cortex_m; #[allow(unused_extern_crates)]
extern crate cortex_m_semihosting; use panic_halt as _;
#[macro_use(exception, interrupt)]
extern crate stm32f103xx;
use core::cell::RefCell; use cortex_m::peripheral::syst::SystClkSource;
use core::fmt::Write; use cortex_m_rt::entry;
use cortex_m_semihosting::hprint;
use stm32f3::stm32f303::{interrupt, Interrupt, NVIC};
use cortex_m::interrupt::{self, Mutex}; #[entry]
use cortex_m::peripheral::SystClkSource; fn main() -> ! {
use cortex_m_semihosting::hio::{self, HStdout}; let p = cortex_m::Peripherals::take().unwrap();
use stm32f103xx::Interrupt;
static HSTDOUT: Mutex<RefCell<Option<HStdout>>> = let mut syst = p.SYST;
Mutex::new(RefCell::new(None)); let mut nvic = p.NVIC;
fn main() { nvic.enable(Interrupt::EXTI0);
interrupt::free(|cs| {
let hstdout = HSTDOUT.borrow(cs);
if let Ok(fd) = hio::hstdout() {
*hstdout.borrow_mut() = Some(fd);
}
let nvic = stm32f103xx::NVIC.borrow(cs); // configure the system timer to wrap around every second
nvic.enable(Interrupt::TIM2);
let syst = stm32f103xx::SYST.borrow(cs);
syst.set_clock_source(SystClkSource::Core); syst.set_clock_source(SystClkSource::Core);
syst.set_reload(8_000_000); // 1s syst.set_reload(8_000_000); // 1s
syst.enable_counter(); syst.enable_counter();
syst.enable_interrupt();
}); loop {
// busy wait until the timer wraps around
while !syst.has_wrapped() {}
// trigger the `EXTI0` interrupt
NVIC::pend(Interrupt::EXTI0);
}
} }
exception!(SYS_TICK, tick); #[interrupt]
fn EXTI0() {
fn tick() { hprint!(".").unwrap();
interrupt::free(|cs| {
let hstdout = HSTDOUT.borrow(cs);
if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
writeln!(*hstdout, "Tick").ok();
}
let nvic = stm32f103xx::NVIC.borrow(cs);
nvic.set_pending(Interrupt::TIM2);
});
}
interrupt!(TIM2, tock, locals: {
tocks: u32 = 0;
});
fn tock(l: &mut TIM2::Locals) {
l.tocks += 1;
interrupt::free(|cs| {
let hstdout = HSTDOUT.borrow(cs);
if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
writeln!(*hstdout, "Tock ({})", l.tocks).ok();
}
});
} }

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]
use panic_halt as _;
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,29 +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] #![no_std]
extern crate cortex_m; use panic_halt as _;
extern crate cortex_m_rt;
extern crate cortex_m_semihosting;
use core::fmt::Write; use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
use cortex_m::asm; #[entry]
use cortex_m_semihosting::hio; fn main() -> ! {
hprintln!("Hello, world!").unwrap();
fn main() { // exit QEMU
let mut stdout = hio::hstdout().unwrap(); // NOTE do not run this on hardware; it can corrupt OpenOCD state
writeln!(stdout, "Hello, world!").unwrap(); debug::exit(debug::EXIT_SUCCESS);
}
loop {}
// As we are not using interrupts, we just register a dummy catch all handler
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
} }

View File

@@ -1,40 +1,33 @@
//! Sends "Hello, world!" through the ITM port 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. //! 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 //! **NOTE** Cortex-M0 chips don't support ITM.
//! to uncomment the `monitor` commands in the `.gdbinit` file.
//! //!
//! [`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] #![no_std]
#[macro_use] use panic_halt as _;
extern crate cortex_m;
extern crate cortex_m_rt;
use cortex_m::{asm, interrupt, peripheral}; use cortex_m::{iprintln, Peripherals};
use cortex_m_rt::entry;
fn main() { #[entry]
interrupt::free(|cs| { fn main() -> ! {
let itm = peripheral::ITM.borrow(&cs); let mut p = Peripherals::take().unwrap();
let stim = &mut p.ITM.stim[0];
iprintln!(&itm.stim[0], "Hello, world!"); iprintln!(stim, "Hello, world!");
});
} loop {}
// As we are not using interrupts, we just register a dummy catch all handler
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
} }

View File

@@ -1,47 +0,0 @@
//! Overriding an exception handler
//!
//! You can override an exception handler using the [`exception!`][1] macro.
//!
//! [1]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.exception.html
//!
//! The default exception handler can be overridden using the
//! [`default_handler!`][2] macro
//!
//! [2]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.default_handler.html
//!
//! ---
#![feature(used)]
#![no_std]
extern crate cortex_m;
#[macro_use(exception)]
extern crate cortex_m_rt;
use core::ptr;
use cortex_m::asm;
fn main() {
unsafe {
// Invalid memory access
ptr::read_volatile(0x2FFF_FFFF as *const u32);
}
}
exception!(HARD_FAULT, handler);
fn handler() {
// You'll hit this breakpoint rather than the one in cortex-m-rt
asm::bkpt()
}
// As we are not using interrupts, we just register a dummy catch all handler
#[allow(dead_code)]
#[used]
#[link_section = ".vector_table.interrupts"]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
}

View File

@@ -1,58 +1,28 @@
//! Defining the panic handler //! Changing the panicking behavior
//! //!
//! The panic handler can be defined through the `panic_fmt` [language item][1]. //! The easiest way to change the panicking behavior is to use a different [panic handler crate][0].
//! Make sure that the "abort-on-panic" feature of the cortex-m-rt crate is
//! disabled to avoid redefining the language item.
//! //!
//! [1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html //! [0]: https://crates.io/keywords/panic-impl
//!
//! ---
#![feature(core_intrinsics)] #![no_main]
#![feature(lang_items)]
#![feature(used)]
#![no_std] #![no_std]
extern crate cortex_m; // Pick one of these panic handlers:
extern crate cortex_m_rt;
extern crate cortex_m_semihosting;
use core::fmt::Write; // `panic!` halts execution; the panic message is ignored
use core::intrinsics; use panic_halt as _;
use cortex_m::asm; // Reports panic messages to the host stderr using semihosting
use cortex_m_semihosting::hio; // NOTE to use this you need to uncomment the `panic-semihosting` dependency in Cargo.toml
// use panic_semihosting as _;
fn main() { // Logs panic messages using the ITM (Instrumentation Trace Macrocell)
panic!("Oops"); // NOTE to use this you need to uncomment the `panic-itm` dependency in Cargo.toml
} // use panic_itm as _;
#[lang = "panic_fmt"] use cortex_m_rt::entry;
#[no_mangle]
unsafe extern "C" fn rust_begin_unwind( #[entry]
args: core::fmt::Arguments, fn main() -> ! {
file: &'static str, panic!("Oops")
line: u32,
col: u32,
) -> ! {
if let Ok(mut stdout) = hio::hstdout() {
write!(stdout, "panicked at '")
.and_then(|_| {
stdout
.write_fmt(args)
.and_then(|_| writeln!(stdout, "', {}:{}", file, line))
})
.ok();
}
intrinsics::abort()
}
// As we are not using interrupts, we just register a dummy catch all handler
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
extern "C" fn default_handler() {
asm::bkpt();
} }

57
examples/test_on_host.rs Normal file
View File

@@ -0,0 +1,57 @@
//! Conditionally compiling tests with std and our executable with no_std.
//!
//! Rust's built in unit testing framework requires the standard library,
//! but we need to build our final executable with no_std.
//! The testing framework also generates a `main` method, so we need to only use the `#[entry]`
//! annotation when building our final image.
//! For more information on why this example works, see this excellent blog post.
//! https://os.phil-opp.com/unit-testing/
//!
//! Running this example:
//!
//! Ensure there are no targets specified under `[build]` in `.cargo/config`
//! In order to make this work, we lose the convenience of having a default target that isn't the
//! host.
//!
//! cargo build --example test_on_host --target thumbv7m-none-eabi
//! cargo test --example test_on_host
#![cfg_attr(test, allow(unused_imports))]
#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(test), no_main)]
// pick a panicking behavior
#[cfg(not(test))]
use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
// use panic_abort as _; // requires nightly
// use panic_itm as _; // logs messages over ITM; requires ITM support
// use panic_semihosting as _; // logs messages to the host stderr; requires a debugger
use cortex_m::asm;
use cortex_m_rt::entry;
#[cfg(not(test))]
#[entry]
fn main() -> ! {
asm::nop(); // To not have main optimize to abort in release mode, remove when you add code
loop {
// your code goes here
}
}
fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn foo() {
println!("tests work!");
assert!(2 == add(1,1));
}
}

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
override-exception-handler
device
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,9 +1,10 @@
MEMORY MEMORY
{ {
/* NOTE K = KiBi = 1024 bytes */ /* NOTE 1 K = 1 KiBi = 1024 bytes */
/* TODO Adjust these memory regions to match your device memory layout */ /* TODO Adjust these memory regions to match your device memory layout */
FLASH : ORIGIN = 0xBAAAAAAD, LENGTH = 0K /* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
RAM : ORIGIN = 0xBAAAAAAD, LENGTH = 0K FLASH : ORIGIN = 0x00000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
} }
/* This is where the call stack will be allocated. */ /* This is where the call stack will be allocated. */
@@ -18,3 +19,16 @@ MEMORY
/* This is required only on microcontrollers that store some configuration right /* This is required only on microcontrollers that store some configuration right
after the vector table */ after the vector table */
/* _stext = ORIGIN(FLASH) + 0x400; */ /* _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]

40
openocd.gdb Normal file
View File

@@ -0,0 +1,40 @@
target extended-remote :3333
# print demangled symbols
set print asm-demangle on
# set backtrace limit to not have infinite backtrace loops
set backtrace limit 32
# detect unhandled exceptions, hard faults and panics
break DefaultHandler
break HardFault
break rust_begin_unwind
# # run the next few lines so the panic message is printed immediately
# # the number needs to be adjusted for your panic handler
# commands $bpnum
# next 4
# end
# *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,33 +0,0 @@
//! Prints "Hello, world!" on the OpenOCD console using semihosting
//!
//! ---
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//! extern crate cortex_m_semihosting;
//!
//! use core::fmt::Write;
//!
//! use cortex_m::asm;
//! use cortex_m_semihosting::hio;
//!
//! fn main() {
//! let mut stdout = hio::hstdout().unwrap();
//! writeln!(stdout, "Hello, world!").unwrap();
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[link_section = ".vector_table.interrupts"]
//! #[used]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,44 +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 the `monitor` commands in the `.gdbinit` file.
//!
//! [`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
//! #[link_section = ".vector_table.interrupts"]
//! #[used]
//! 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 @@
//! Defining the panic handler
//!
//! The panic handler can be defined through the `panic_fmt` [language item][1].
//! Make sure that the "abort-on-panic" feature of the cortex-m-rt crate is
//! disabled to avoid redefining the language item.
//!
//! [1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html
//!
//! ---
//!
//! ```
//!
//! #![feature(core_intrinsics)]
//! #![feature(lang_items)]
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//! extern crate cortex_m_semihosting;
//!
//! use core::fmt::Write;
//! use core::intrinsics;
//!
//! use cortex_m::asm;
//! use cortex_m_semihosting::hio;
//!
//! fn main() {
//! panic!("Oops");
//! }
//!
//! #[lang = "panic_fmt"]
//! #[no_mangle]
//! unsafe extern "C" fn rust_begin_unwind(
//! args: core::fmt::Arguments,
//! file: &'static str,
//! line: u32,
//! col: u32,
//! ) -> ! {
//! if let Ok(mut stdout) = hio::hstdout() {
//! write!(stdout, "panicked at '")
//! .and_then(|_| {
//! stdout
//! .write_fmt(args)
//! .and_then(|_| writeln!(stdout, "', {}:{}", file, line))
//! })
//! .ok();
//! }
//!
//! intrinsics::abort()
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[link_section = ".vector_table.interrupts"]
//! #[used]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,89 +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:
//!
//! ``` text
//! (gdb) # Exception frame = program state during the crash
//! (gdb) print/x *ef
//! $1 = cortex_m::exception::ExceptionFrame {
//! r0 = 0x2fffffff,
//! r1 = 0x2fffffff,
//! r2 = 0x0,
//! r3 = 0x0,
//! r12 = 0x0,
//! lr = 0x8000481,
//! pc = 0x8000460,
//! xpsr = 0x61000000,
//! }
//!
//! (gdb) # Where did we come from?
//! (gdb) backtrace
//! #0 cortex_m_rt::default_handler (ef=0x20004f54) at (..)
//! #1 <signal handler called>
//! #2 0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..)
//! #3 0x08000480 in crash::main () at examples/crash.rs:68
//!
//! (gdb) # Nail down the location of the crash
//! (gdb) disassemble/m ef.pc
//! Dump of assembler code for function core::ptr::read_volatile<u32>:
//! 408 pub unsafe fn read_volatile<T>(src: *const T) -> T {
//! 0x08000454 <+0>: sub sp, #20
//! 0x08000456 <+2>: mov r1, r0
//! 0x08000458 <+4>: str r0, [sp, #8]
//! 0x0800045a <+6>: ldr r0, [sp, #8]
//! 0x0800045c <+8>: str r0, [sp, #12]
//!
//! 409 intrinsics::volatile_load(src)
//! 0x0800045e <+10>: ldr r0, [sp, #12]
//! 0x08000460 <+12>: ldr r0, [r0, #0]
//! 0x08000462 <+14>: str r0, [sp, #16]
//! 0x08000464 <+16>: ldr r0, [sp, #16]
//! 0x08000466 <+18>: str r1, [sp, #4]
//! 0x08000468 <+20>: str r0, [sp, #0]
//! 0x0800046a <+22>: b.n 0x800046c <core::ptr::read_volatile<u32>+24>
//!
//! 410 }
//! 0x0800046c <+24>: ldr r0, [sp, #0]
//! 0x0800046e <+26>: add sp, #20
//! 0x08000470 <+28>: bx lr
//!
//! End of assembler dump.
//! ```
//!
//! ---
//!
//! ```
//!
//! #![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
//! #[link_section = ".vector_table.interrupts"]
//! #[used]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! extern "C" fn default_handler() {
//! asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,51 +0,0 @@
//! Overriding an exception handler
//!
//! You can override an exception handler using the [`exception!`][1] macro.
//!
//! [1]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.exception.html
//!
//! The default exception handler can be overridden using the
//! [`default_handler!`][2] macro
//!
//! [2]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.default_handler.html
//!
//! ---
//!
//! ```
//!
//! #![feature(used)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! #[macro_use(exception)]
//! extern crate cortex_m_rt;
//!
//! use core::ptr;
//!
//! use cortex_m::asm;
//!
//! fn main() {
//! unsafe {
//! // Invalid memory access
//! ptr::read_volatile(0x2FFF_FFFF as *const u32);
//! }
//! }
//!
//! exception!(HARD_FAULT, handler);
//!
//! fn handler() {
//! // You'll hit this breakpoint rather than the one in cortex-m-rt
//! asm::bkpt()
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[allow(dead_code)]
//! #[used]
//! #[link_section = ".vector_table.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,97 +0,0 @@
//! Using a device crate
//!
//! Crates generated using [`svd2rust`] are referred to as device crates. These
//! crates provides an API to access the peripherals of a device. When you
//! depend on one of these crates and the "rt" feature is enabled you don't need
//! link to the cortex-m-rt crate.
//!
//! [`svd2rust`]: https://crates.io/crates/svd2rust
//!
//! Device crates also provide an `interrupt!` macro 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 && cat $_
//! [dependencies.stm32f103xx]
//! features = ["rt"]
//! version = "0.7.0"
//! ```
//!
//! ---
//!
//! ```
//!
//! #![deny(warnings)]
//! #![feature(const_fn)]
//! #![no_std]
//!
//! extern crate cortex_m;
//! extern crate cortex_m_semihosting;
//! #[macro_use(exception, interrupt)]
//! extern crate stm32f103xx;
//!
//! use core::cell::RefCell;
//! use core::fmt::Write;
//!
//! use cortex_m::interrupt::{self, Mutex};
//! use cortex_m::peripheral::SystClkSource;
//! use cortex_m_semihosting::hio::{self, HStdout};
//! use stm32f103xx::Interrupt;
//!
//! static HSTDOUT: Mutex<RefCell<Option<HStdout>>> =
//! Mutex::new(RefCell::new(None));
//!
//! fn main() {
//! interrupt::free(|cs| {
//! let hstdout = HSTDOUT.borrow(cs);
//! if let Ok(fd) = hio::hstdout() {
//! *hstdout.borrow_mut() = Some(fd);
//! }
//!
//! let nvic = stm32f103xx::NVIC.borrow(cs);
//! nvic.enable(Interrupt::TIM2);
//!
//! let syst = stm32f103xx::SYST.borrow(cs);
//! syst.set_clock_source(SystClkSource::Core);
//! syst.set_reload(8_000_000); // 1s
//! syst.enable_counter();
//! syst.enable_interrupt();
//! });
//! }
//!
//! exception!(SYS_TICK, tick);
//!
//! fn tick() {
//! interrupt::free(|cs| {
//! let hstdout = HSTDOUT.borrow(cs);
//! if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
//! writeln!(*hstdout, "Tick").ok();
//! }
//!
//! let nvic = stm32f103xx::NVIC.borrow(cs);
//!
//! nvic.set_pending(Interrupt::TIM2);
//! });
//! }
//!
//! interrupt!(TIM2, tock, locals: {
//! tocks: u32 = 0;
//! });
//!
//! fn tock(l: &mut TIM2::Locals) {
//! l.tocks += 1;
//!
//! interrupt::free(|cs| {
//! let hstdout = HSTDOUT.borrow(cs);
//! if let Some(hstdout) = hstdout.borrow_mut().as_mut() {
//! writeln!(*hstdout, "Tock ({})", l.tocks).ok();
//! }
//! });
//! }
//! ```
// Auto-generated. Do not modify.

View File

@@ -1,83 +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]
//! stage = 0
//!
//! [dependencies.collections] # NEW
//! stage = 0
//!
//! [dependencies.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
//! ```
//!
//! ---
//!
//! ```
//!
//! #[allow(deprecated)]
//! #![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;
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//! extern crate cortex_m_semihosting;
//!
//! use core::fmt::Write;
//!
//! use cortex_m::asm;
//! use cortex_m_semihosting::hio;
//!
//! 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)
//! // NOTE 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, _eheap);
//! }
//!
//! // Growable array allocated on the heap
//! let xs = vec![0, 1, 2];
//!
//! let mut stdout = hio::hstdout().unwrap();
//! writeln!(stdout, "{:?}", xs).unwrap();
//! }
//!
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[link_section = ".vector_table.interrupts"]
//! #[used]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//!
//! 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_override_exception_handler;
pub mod _5_device;
pub mod _6_allocator;

View File

@@ -1,347 +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
//! }
//! ```
//!
//! - 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 stm32f103xx
//!
//! # add a board support crate
//! $ cargo add blue-pill --git https://github.com/japaric/blue-pill
//! ```
//!
//! - 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 a debug session in another terminal
//! $ 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`.
//!
//! ## Overwrote the original `.cargo/config` file
//!
//! Error message:
//!
//! ``` text
//! error: linking with `arm-none-eabi-gcc` failed: exit code: 1
//! |
//! = note: (..)
//! (..)
//! (..)/crt0.o: In function `_start':
//! (.text+0x90): undefined reference to `memset'
//! (..)/crt0.o: In function `_start':
//! (.text+0xd0): undefined reference to `atexit'
//! (..)/crt0.o: In function `_start':
//! (.text+0xd4): undefined reference to `__libc_init_array'
//! (..)/crt0.o: In function `_start':
//! (.text+0xe4): undefined reference to `exit'
//! (..)/crt0.o: In function `_start':
//! (.text+0x100): undefined reference to `__libc_fini_array'
//! collect2: error: ld returned 1 exit status
//! ```
//!
//! Solution: You probably overwrote the original `.cargo/config` instead of
//! appending the default build target (e.g. `cat >` instead of `cat >>`). The
//! less error prone way to fix this is to remove the `.cargo` directory, clone
//! a new copy of the template and then copy the `.cargo` directory from that
//! fresh template into your current project. Don't forget to *append* the
//! default build target to `.cargo/config`.
//!
//! ## 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/..`
//!
//! # Used a named piped for `itm.fifo`
//!
//! Error message:
//!
//! ``` text
//! $ xargo run [--example ..]
//!
//! Reading symbols from target/thumbv7em-none-eabihf/debug/cortex-m-quickstart...done.
//! cortex_m_rt::reset_handler ()
//! at $REGISTRY/cortex-m-rt-0.3.12/src/lib.rs:330
//! 330 unsafe extern "C" fn reset_handler() -> ! {
//! semihosting is enabled
//! Ignoring packet error, continuing...
//! Ignoring packet error, continuing...
//! ```
//!
//! Note that when you reach this point OpenOCD will become unresponsive and you'll have to kill it
//! and start a new OpenOCD process before you can invoke `xargo run` / start GDB.
//!
//! Cause: You uncommented the `monitor tpiu ..` line in `.gdbinit` and are using a named pipe to
//! receive the ITM data (i.e. you ran `mkfifo itm.fifo`). This error occurs when `itmdump -f
//! itm.fifo` (or equivalent, e.g. `cat itm.fifo`) is not running.
//!
//! Solution: Run `itmdump -f itm.fifo` (or equivalently `cat itm.fifo`) *before* invoking `xargo
//! run` / starting GDB. Note that sometimes `itmdump` will exit when the GDB session ends. In that
//! case you'll have to run `itmdump` before you start the next GDB session.
//!
//! Alternative solution: Use a plain text file instead of a named pipe. In this scenario you omit
//! the `mkfifo itm.dump` command. You can use `itmdump`'s *follow* mode (-F) to get named pipe like
//! output.
#![no_std]
pub mod examples;

20
src/main.rs Normal file
View File

@@ -0,0 +1,20 @@
#![no_std]
#![no_main]
// pick a panicking behavior
use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
// use panic_abort as _; // requires nightly
// use panic_itm as _; // logs messages over ITM; requires ITM support
// use panic_semihosting as _; // logs messages to the host stderr; requires a debugger
use cortex_m::asm;
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
asm::nop(); // To not have main optimize to abort in release mode, remove when you add code
loop {
// your code goes here
}
}