Initial commit
Much of the content here is a direct port from https://github.com/japaric/discovery
This commit is contained in:
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Rust ignores
|
||||||
|
/target/
|
||||||
|
Cargo.lock
|
||||||
|
**/*.rs.bk
|
||||||
|
|
||||||
|
# mdBook ignores
|
||||||
|
*.org
|
||||||
|
.#*
|
||||||
|
.gdb_history
|
||||||
|
/template
|
||||||
|
book/
|
||||||
32
.travis.yml
Normal file
32
.travis.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
language: rust
|
||||||
|
rust: nightly
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- gcc-arm-none-eabi
|
||||||
|
|
||||||
|
install:
|
||||||
|
- bash ci/install.sh
|
||||||
|
|
||||||
|
script:
|
||||||
|
- bash ci/script.sh
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- bash ci/after-success.sh
|
||||||
|
|
||||||
|
cache: cargo
|
||||||
|
|
||||||
|
before_cache:
|
||||||
|
# Travis can't cache files that are not readable by "others"
|
||||||
|
- chmod -R a+r $HOME/.cargo
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- staging
|
||||||
|
- trying
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
on_success: never
|
||||||
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"src/getting-started",
|
||||||
|
]
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
codegen-units = 1
|
||||||
|
incremental = false
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
lto = true
|
||||||
218
LICENSE-APACHE
Normal file
218
LICENSE-APACHE
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
Copyright 2018 Michael Droogleever
|
||||||
|
Copyright 2016 Jorge Aparicio
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
395
LICENSE-CC-BY
Normal file
395
LICENSE-CC-BY
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
Attribution 4.0 International
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||||
|
does not provide legal services or legal advice. Distribution of
|
||||||
|
Creative Commons public licenses does not create a lawyer-client or
|
||||||
|
other relationship. Creative Commons makes its licenses and related
|
||||||
|
information available on an "as-is" basis. Creative Commons gives no
|
||||||
|
warranties regarding its licenses, any material licensed under their
|
||||||
|
terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the
|
||||||
|
fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and
|
||||||
|
conditions that creators and other rights holders may use to share
|
||||||
|
original works of authorship and other material subject to copyright
|
||||||
|
and certain other rights specified in the public license below. The
|
||||||
|
following considerations are for informational purposes only, are not
|
||||||
|
exhaustive, and do not form part of our licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are
|
||||||
|
intended for use by those authorized to give the public
|
||||||
|
permission to use material in ways otherwise restricted by
|
||||||
|
copyright and certain other rights. Our licenses are
|
||||||
|
irrevocable. Licensors should read and understand the terms
|
||||||
|
and conditions of the license they choose before applying it.
|
||||||
|
Licensors should also secure all rights necessary before
|
||||||
|
applying our licenses so that the public can reuse the
|
||||||
|
material as expected. Licensors should clearly mark any
|
||||||
|
material not subject to the license. This includes other CC-
|
||||||
|
licensed material, or material used under an exception or
|
||||||
|
limitation to copyright. More considerations for licensors:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public
|
||||||
|
licenses, a licensor grants the public permission to use the
|
||||||
|
licensed material under specified terms and conditions. If
|
||||||
|
the licensor's permission is not necessary for any reason--for
|
||||||
|
example, because of any applicable exception or limitation to
|
||||||
|
copyright--then that use is not regulated by the license. Our
|
||||||
|
licenses grant only permissions under copyright and certain
|
||||||
|
other rights that a licensor has authority to grant. Use of
|
||||||
|
the licensed material may still be restricted for other
|
||||||
|
reasons, including because others have copyright or other
|
||||||
|
rights in the material. A licensor may make special requests,
|
||||||
|
such as asking that all changes be marked or described.
|
||||||
|
Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More_considerations
|
||||||
|
for the public:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Attribution 4.0 International Public License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree
|
||||||
|
to be bound by the terms and conditions of this Creative Commons
|
||||||
|
Attribution 4.0 International Public License ("Public License"). To the
|
||||||
|
extent this Public License may be interpreted as a contract, You are
|
||||||
|
granted the Licensed Rights in consideration of Your acceptance of
|
||||||
|
these terms and conditions, and the Licensor grants You such rights in
|
||||||
|
consideration of benefits the Licensor receives from making the
|
||||||
|
Licensed Material available under these terms and conditions.
|
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar
|
||||||
|
Rights that is derived from or based upon the Licensed Material
|
||||||
|
and in which the Licensed Material is translated, altered,
|
||||||
|
arranged, transformed, or otherwise modified in a manner requiring
|
||||||
|
permission under the Copyright and Similar Rights held by the
|
||||||
|
Licensor. For purposes of this Public License, where the Licensed
|
||||||
|
Material is a musical work, performance, or sound recording,
|
||||||
|
Adapted Material is always produced where the Licensed Material is
|
||||||
|
synched in timed relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright
|
||||||
|
and Similar Rights in Your contributions to Adapted Material in
|
||||||
|
accordance with the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||||
|
closely related to copyright including, without limitation,
|
||||||
|
performance, broadcast, sound recording, and Sui Generis Database
|
||||||
|
Rights, without regard to how the rights are labeled or
|
||||||
|
categorized. For purposes of this Public License, the rights
|
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||||
|
Rights.
|
||||||
|
|
||||||
|
d. Effective Technological Measures means those measures that, in the
|
||||||
|
absence of proper authority, may not be circumvented under laws
|
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||||
|
Treaty adopted on December 20, 1996, and/or similar international
|
||||||
|
agreements.
|
||||||
|
|
||||||
|
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||||
|
any other exception or limitation to Copyright and Similar Rights
|
||||||
|
that applies to Your use of the Licensed Material.
|
||||||
|
|
||||||
|
f. Licensed Material means the artistic or literary work, database,
|
||||||
|
or other material to which the Licensor applied this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
g. Licensed Rights means the rights granted to You subject to the
|
||||||
|
terms and conditions of this Public License, which are limited to
|
||||||
|
all Copyright and Similar Rights that apply to Your use of the
|
||||||
|
Licensed Material and that the Licensor has authority to license.
|
||||||
|
|
||||||
|
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||||
|
under this Public License.
|
||||||
|
|
||||||
|
i. Share means to provide material to the public by any means or
|
||||||
|
process that requires permission under the Licensed Rights, such
|
||||||
|
as reproduction, public display, public performance, distribution,
|
||||||
|
dissemination, communication, or importation, and to make material
|
||||||
|
available to the public including in ways that members of the
|
||||||
|
public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
j. Sui Generis Database Rights means rights other than copyright
|
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of
|
||||||
|
the Council of 11 March 1996 on the legal protection of databases,
|
||||||
|
as amended and/or succeeded, as well as other essentially
|
||||||
|
equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
k. You means the individual or entity exercising the Licensed Rights
|
||||||
|
under this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License,
|
||||||
|
the Licensor hereby grants You a worldwide, royalty-free,
|
||||||
|
non-sublicensable, non-exclusive, irrevocable license to
|
||||||
|
exercise the Licensed Rights in the Licensed Material to:
|
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or
|
||||||
|
in part; and
|
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||||
|
Exceptions and Limitations apply to Your use, this Public
|
||||||
|
License does not apply, and You do not need to comply with
|
||||||
|
its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section
|
||||||
|
6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The
|
||||||
|
Licensor authorizes You to exercise the Licensed Rights in
|
||||||
|
all media and formats whether now known or hereafter created,
|
||||||
|
and to make technical modifications necessary to do so. The
|
||||||
|
Licensor waives and/or agrees not to assert any right or
|
||||||
|
authority to forbid You from making technical modifications
|
||||||
|
necessary to exercise the Licensed Rights, including
|
||||||
|
technical modifications necessary to circumvent Effective
|
||||||
|
Technological Measures. For purposes of this Public License,
|
||||||
|
simply making modifications authorized by this Section 2(a)
|
||||||
|
(4) never produces Adapted Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every
|
||||||
|
recipient of the Licensed Material automatically
|
||||||
|
receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
b. No downstream restrictions. You may not offer or impose
|
||||||
|
any additional or different terms or conditions on, or
|
||||||
|
apply any Effective Technological Measures to, the
|
||||||
|
Licensed Material if doing so restricts exercise of the
|
||||||
|
Licensed Rights by any recipient of the Licensed
|
||||||
|
Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or
|
||||||
|
may be construed as permission to assert or imply that You
|
||||||
|
are, or that Your use of the Licensed Material is, connected
|
||||||
|
with, or sponsored, endorsed, or granted official status by,
|
||||||
|
the Licensor or others designated to receive attribution as
|
||||||
|
provided in Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not
|
||||||
|
licensed under this Public License, nor are publicity,
|
||||||
|
privacy, and/or other similar personality rights; however, to
|
||||||
|
the extent possible, the Licensor waives and/or agrees not to
|
||||||
|
assert any such rights held by the Licensor to the limited
|
||||||
|
extent necessary to allow You to exercise the Licensed
|
||||||
|
Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to
|
||||||
|
collect royalties from You for the exercise of the Licensed
|
||||||
|
Rights, whether directly or through a collecting society
|
||||||
|
under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly
|
||||||
|
reserves any right to collect such royalties.
|
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the
|
||||||
|
following conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified
|
||||||
|
form), You must:
|
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor
|
||||||
|
with the Licensed Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed
|
||||||
|
Material and any others designated to receive
|
||||||
|
attribution, in any reasonable manner requested by
|
||||||
|
the Licensor (including by pseudonym if
|
||||||
|
designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of
|
||||||
|
warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the
|
||||||
|
extent reasonably practicable;
|
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and
|
||||||
|
retain an indication of any previous modifications; and
|
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this
|
||||||
|
Public License, and include the text of, or the URI or
|
||||||
|
hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||||
|
reasonable manner based on the medium, means, and context in
|
||||||
|
which You Share the Licensed Material. For example, it may be
|
||||||
|
reasonable to satisfy the conditions by providing a URI or
|
||||||
|
hyperlink to a resource that includes the required
|
||||||
|
information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the
|
||||||
|
information required by Section 3(a)(1)(A) to the extent
|
||||||
|
reasonably practicable.
|
||||||
|
|
||||||
|
4. If You Share Adapted Material You produce, the Adapter's
|
||||||
|
License You apply must not prevent recipients of the Adapted
|
||||||
|
Material from complying with this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that
|
||||||
|
apply to Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||||
|
to extract, reuse, reproduce, and Share all or a substantial
|
||||||
|
portion of the contents of the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database
|
||||||
|
contents in a database in which You have Sui Generis Database
|
||||||
|
Rights, then the database in which You have Sui Generis Database
|
||||||
|
Rights (but not its individual contents) is Adapted Material; and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share
|
||||||
|
all or a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not
|
||||||
|
replace Your obligations under this Public License where the Licensed
|
||||||
|
Rights include other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided
|
||||||
|
above shall be interpreted in a manner that, to the extent
|
||||||
|
possible, most closely approximates an absolute disclaimer and
|
||||||
|
waiver of all liability.
|
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and
|
||||||
|
Similar Rights licensed here. However, if You fail to comply with
|
||||||
|
this Public License, then Your rights under this Public License
|
||||||
|
terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under
|
||||||
|
Section 6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided
|
||||||
|
it is cured within 30 days of Your discovery of the
|
||||||
|
violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||||
|
right the Licensor may have to seek remedies for Your violations
|
||||||
|
of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the
|
||||||
|
Licensed Material under separate terms or conditions or stop
|
||||||
|
distributing the Licensed Material at any time; however, doing so
|
||||||
|
will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different
|
||||||
|
terms or conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the
|
||||||
|
Licensed Material not stated herein are separate from and
|
||||||
|
independent of the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and
|
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||||
|
conditions on any use of the Licensed Material that could lawfully
|
||||||
|
be made without permission under this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is
|
||||||
|
deemed unenforceable, it shall be automatically reformed to the
|
||||||
|
minimum extent necessary to make it enforceable. If the provision
|
||||||
|
cannot be reformed, it shall be severed from this Public License
|
||||||
|
without affecting the enforceability of the remaining terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no
|
||||||
|
failure to comply consented to unless expressly agreed to by the
|
||||||
|
Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted
|
||||||
|
as a limitation upon, or waiver of, any privileges and immunities
|
||||||
|
that apply to the Licensor or You, including from the legal
|
||||||
|
processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public
|
||||||
|
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||||
|
its public licenses to material it publishes and in those instances
|
||||||
|
will be considered the “Licensor.” The text of the Creative Commons
|
||||||
|
public licenses is dedicated to the public domain under the CC0 Public
|
||||||
|
Domain Dedication. Except for the limited purpose of indicating that
|
||||||
|
material is shared under a Creative Commons public license or as
|
||||||
|
otherwise permitted by the Creative Commons policies published at
|
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the
|
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo
|
||||||
|
of Creative Commons without its prior written consent including,
|
||||||
|
without limitation, in connection with any unauthorized modifications
|
||||||
|
to any of its public licenses or any other arrangements,
|
||||||
|
understandings, or agreements concerning use of licensed material. For
|
||||||
|
the avoidance of doubt, this paragraph does not form part of the
|
||||||
|
public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
||||||
26
LICENSE-MIT
Normal file
26
LICENSE-MIT
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
Copyright (c) 2018 Michael Droogleever
|
||||||
|
Copyright (c) 2016 Jorge Aparicio
|
||||||
|
|
||||||
|
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.
|
||||||
26
README.md
Normal file
26
README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# MicroRust
|
||||||
|
|
||||||
|
> Learn embedded software in Rust on the micro:bit
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The documentation is licensed under
|
||||||
|
|
||||||
|
- Creative Commons Attribution 4.0 License ([LICENSE-CC-BY](LICENSE-CC-BY)
|
||||||
|
or https://creativecommons.org/licenses/by/4.0/legalcode)
|
||||||
|
|
||||||
|
And the source code is licensed under either of
|
||||||
|
|
||||||
|
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
||||||
|
- MIT License ([LICENSE-MIT](LICENSE-MIT) or
|
||||||
|
https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
at your option.
|
||||||
|
|
||||||
|
### Contribution
|
||||||
|
|
||||||
|
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
|
||||||
|
licensed as above, without any additional terms or conditions.
|
||||||
19
ci/after-success.sh
Normal file
19
ci/after-success.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
main() {
|
||||||
|
mdbook build
|
||||||
|
|
||||||
|
mkdir ghp-import
|
||||||
|
|
||||||
|
curl -Ls https://github.com/davisp/ghp-import/archive/master.tar.gz |
|
||||||
|
tar --strip-components 1 -C ghp-import -xz
|
||||||
|
|
||||||
|
./ghp-import/ghp_import.py book
|
||||||
|
|
||||||
|
set +x
|
||||||
|
git push -fq https://$GH_TOKEN@github.com/$TRAVIS_REPO_SLUG.git gh-pages && echo OK
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $TRAVIS_BRANCH = master ]; then
|
||||||
|
main
|
||||||
|
fi
|
||||||
19
ci/install.sh
Normal file
19
ci/install.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
main() {
|
||||||
|
curl -LSfs https://japaric.github.io/trust/install.sh | \
|
||||||
|
sh -s -- \
|
||||||
|
--force \
|
||||||
|
--git rust-lang-nursery/mdBook \
|
||||||
|
--tag v0.1.5 \
|
||||||
|
--target x86_64-unknown-linux-musl
|
||||||
|
|
||||||
|
rustup target add thumbv6m-none-eabi
|
||||||
|
|
||||||
|
pip install linkchecker --user
|
||||||
|
|
||||||
|
# sanity check that a linker is present
|
||||||
|
which arm-none-eabi-ld
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
35
ci/script.sh
Normal file
35
ci/script.sh
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# test that building the book works
|
||||||
|
mdbook build
|
||||||
|
|
||||||
|
linkchecker book
|
||||||
|
|
||||||
|
# first (fast) pass: check that examples compile
|
||||||
|
for chapter in $(echo src/*); do
|
||||||
|
if [ ! -f $chapter/Cargo.toml ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd $chapter
|
||||||
|
cargo check
|
||||||
|
popd
|
||||||
|
done
|
||||||
|
|
||||||
|
# second (slow) pass: check that examples link
|
||||||
|
for chapter in $(echo src/*); do
|
||||||
|
if [ ! -f $chapter/Cargo.toml ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd $chapter
|
||||||
|
cargo build
|
||||||
|
cargo build --release
|
||||||
|
popd
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $TRAVIS_BRANCH != master ]; then
|
||||||
|
main
|
||||||
|
fi
|
||||||
65
src/README.md
Normal file
65
src/README.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# MicroRust
|
||||||
|
|
||||||
|
> Discover the world of microcontrollers through [Rust] on the [BBC micro:bit][microbit]!
|
||||||
|
|
||||||
|
[Rust]: https://www.rust-lang.org/
|
||||||
|
[microbit]: https://microbit.org/
|
||||||
|
|
||||||
|
This book is an introductory course on microcontroller-based embedded systems that uses Rust as the
|
||||||
|
teaching language (rather than the usual C/C++), and the micro:bit as target system.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
The following topics will be covered:
|
||||||
|
|
||||||
|
- How to write, build, flash and debug an embedded program.
|
||||||
|
|
||||||
|
- Functionality ("peripherals") commonly found in microcontrollers:
|
||||||
|
- Digital input and output, using buttons and LEDs
|
||||||
|
|
||||||
|
<!-- - Functionality ("peripherals") commonly found in microcontrollers: Digital input and output, Pulse
|
||||||
|
Width Modulation (PWM), Analog to Digital Converters (ADC), common communication protocols like
|
||||||
|
Serial, I2C and SPI, etc. -->
|
||||||
|
|
||||||
|
<!-- - Multitasking concepts: cooperative vs preemptive multitasking, interrupts, schedulers, etc. -->
|
||||||
|
|
||||||
|
<!-- - Control systems concepts: sensors, calibration, digital filters, actuators, open loop control,
|
||||||
|
closed loop control, etc. -->
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
- Beginner friendly.
|
||||||
|
No previous experience with microcontrollers or embedded systems is required.
|
||||||
|
|
||||||
|
- Hands on.
|
||||||
|
*You* will be doing most of the work here.
|
||||||
|
When possible, pages will end on a problem for you to solve, with the solution on the next page.
|
||||||
|
Plenty of exercises to put the theory into practice.
|
||||||
|
|
||||||
|
- Standard. We'll make plenty use of standard tooling and processes to ease development.
|
||||||
|
Fixing compiler errors, debugging with GDB, and logging will be introduced early on.
|
||||||
|
Using LEDs as a debugging mechanism has no place here.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
What's out of scope for this book:
|
||||||
|
|
||||||
|
- Teaching Rust.
|
||||||
|
There's plenty of material on that topic already.
|
||||||
|
We'll focus on microcontrollers and embedded systems.
|
||||||
|
|
||||||
|
- Teaching electric circuit theory or electronics.
|
||||||
|
We'll cover the minimum required to understand how some devices work along the way.
|
||||||
|
|
||||||
|
- Covering Rustic, low level details.
|
||||||
|
We won't be talking about linker scripts, the boot process,
|
||||||
|
or how to glue those two into a minimally working Rust program.
|
||||||
|
|
||||||
|
## Reporting problems
|
||||||
|
|
||||||
|
The source of this book is in [this repository].
|
||||||
|
If you encounter any typo or problem with the code report it on the [issue tracker],
|
||||||
|
or even submit a pull request.
|
||||||
|
|
||||||
|
[this repository]: https://github.com/droogmic/microrust
|
||||||
|
[issue tracker]: https://github.com/droogmic/microrust/issues
|
||||||
34
src/SUMMARY.md
Normal file
34
src/SUMMARY.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
[Introduction](README.md)
|
||||||
|
|
||||||
|
[Background](background/README.md)
|
||||||
|
|
||||||
|
[Requirements](requirements/README.md)
|
||||||
|
|
||||||
|
- [Meet your hardware](hardware/README.md)
|
||||||
|
|
||||||
|
- [Development environment setup](setup/README.md)
|
||||||
|
- [Linux](setup/LINUX.md)
|
||||||
|
- [Windows](setup/WINDOWS.md)
|
||||||
|
- [macOS](setup/MACOS.md)
|
||||||
|
- [Verify the installation](setup/VERIFY.md)
|
||||||
|
|
||||||
|
- [Getting started](getting-started/00.00.README.md)
|
||||||
|
- [Building](getting-started/01.00.PROJECT.md)
|
||||||
|
- [Flashing](getting-started/02.00.FLASH.md)
|
||||||
|
- [LED](getting-started/03.00.LED.md)
|
||||||
|
- [Debugging](getting-started/04.00.DEBUGGING.md)
|
||||||
|
|
||||||
|
[Explore](appendix/explore.md)
|
||||||
|
|
||||||
|
[General troubleshooting](appendix/troubleshooting.md)
|
||||||
|
|
||||||
|
<!-- - [LED roulette](05-led-roulette/README.md)
|
||||||
|
- [Build it](05-led-roulette/build-it.md)
|
||||||
|
- [Flash it](05-led-roulette/flash-it.md)
|
||||||
|
- [Debug it](05-led-roulette/debug-it.md)
|
||||||
|
- [The `led` and `delay` abstractions](05-led-roulette/the-led-and-delay-abstractions.md)
|
||||||
|
- [The challenge](05-led-roulette/the-challenge.md)
|
||||||
|
- [My solution](05-led-roulette/my-solution.md) -->
|
||||||
|
|
||||||
|
<!-- - [Hello, world!](06-hello-world/README.md)
|
||||||
|
- [`panic!`](06-hello-world/panic.md) -->
|
||||||
162
src/appendix/explore.md
Normal file
162
src/appendix/explore.md
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
# What's left for you to explore
|
||||||
|
|
||||||
|
We have barely scratched the surface! There's lots of stuff left for you to explore:
|
||||||
|
|
||||||
|
## Multitasking
|
||||||
|
|
||||||
|
All our programs executed a single task. How could we achieve multitasking in a system with no OS,
|
||||||
|
and thus no threads. There are two main approaches to multitasking: preemptive multitasking and
|
||||||
|
cooperative multitasking.
|
||||||
|
|
||||||
|
In preemptive multitasking a task that's currently being executed can, at any point in time, be
|
||||||
|
*preempted* (interrupted) by another task. On preemption, the first task will be suspended and the
|
||||||
|
processor will instead execute the second task. At some point the first task will be resumed.
|
||||||
|
Microcontrollers provide hardware support for preemption in the form of *interrupts*.
|
||||||
|
|
||||||
|
In cooperative multitasking a task that's being executed will run until it reaches a *suspension
|
||||||
|
point*. When the processor reaches that suspension point it will stop executing the current task and
|
||||||
|
instead go and execute a different task. At some point the first task will be resumed. The main
|
||||||
|
difference between these two approaches to multitasking is that in cooperative multitasking *yields*
|
||||||
|
execution control at *known* suspension points instead of being forcefully preempted at any point of
|
||||||
|
its execution.
|
||||||
|
|
||||||
|
## Direct Memory Access (DMA).
|
||||||
|
|
||||||
|
This peripheral is a kind of *asynchronous* `memcpy`. So far our programs have
|
||||||
|
been pumping data, byte by byte, into peripherals like UART and I2C. This DMA
|
||||||
|
peripheral can be used to perform bulk transfers of data. Either from RAM to
|
||||||
|
RAM, from a peripheral, like a UART, to RAM or from RAM to a peripheral. You can
|
||||||
|
schedule a DMA transfer, like read 256 bytes from USART1 into this buffer, leave
|
||||||
|
it running in the background and then poll some register to see if it has
|
||||||
|
completed so you can do other stuff while the transfer is ongoing.
|
||||||
|
|
||||||
|
## Sleeping
|
||||||
|
|
||||||
|
All our programs have been continuously polling peripherals to see if there's
|
||||||
|
anything that needs to be done. However, some times there's nothing to be done!
|
||||||
|
At those times, the microcontroller should "sleep".
|
||||||
|
|
||||||
|
When the processor sleeps, it stops executing instructions and this saves power.
|
||||||
|
It's almost always a good idea to save power so your microcontroller should be
|
||||||
|
sleeping as much as possible. But, how does it know when it has to wake up to
|
||||||
|
perform some action? "Interrupts" are one of the events that wake up the
|
||||||
|
microcontroller but there are others and the `wfi` and `wfe` are the
|
||||||
|
instructions that make the processor "sleep".
|
||||||
|
|
||||||
|
## Pulse Width Modulation (PWM)
|
||||||
|
|
||||||
|
In a nutshell, PWM is turning on something and then turning it off periodically
|
||||||
|
while keeping some proportion ("duty cycle") between the "on time" and the "off
|
||||||
|
time". When used on a LED with a sufficiently high frequency, this can be used
|
||||||
|
to dim the LED. A low duty cycle, say 10% on time and 90% off time, will make
|
||||||
|
the LED very dim wheres a high duty cycle, say 90% on time and 10% off time,
|
||||||
|
will make the LED much brighter (almost as if it were fully powered).
|
||||||
|
|
||||||
|
In general, PWM can be used to control how much *power* is given to some
|
||||||
|
electric device. With proper (power) electronics between a microcontroller and
|
||||||
|
an electrical motor, PWM can be used to control how much power is given to the
|
||||||
|
motor thus it can be used to control its torque and speed. Then you can add an
|
||||||
|
angular position sensor and you got yourself a closed loop controller that can
|
||||||
|
control the position of the motor at different loads.
|
||||||
|
|
||||||
|
## Digital input
|
||||||
|
|
||||||
|
We have used the microcontroller pins as digital outputs, to drive LEDs. But
|
||||||
|
these pins can also be configured as digital inputs. As digital inputs, these
|
||||||
|
pins can read the binary state of switches (on/off) or buttons (pressed/not
|
||||||
|
pressed).
|
||||||
|
|
||||||
|
(*spoilers* reading the binary state of switches / buttons is not as
|
||||||
|
straightforward as it sounds ;-)
|
||||||
|
|
||||||
|
## Sensor fusion
|
||||||
|
|
||||||
|
The STM32F3DISCOVERY contains three motion sensors: an accelerometer, a
|
||||||
|
gyroscope and a magnetometer. On their own these measure: (proper) acceleration,
|
||||||
|
angular speed and (the Earth's) magnetic field. But these magnitudes can be
|
||||||
|
"fused" into something more useful: a "robust" measurement of the orientation of
|
||||||
|
the board. Where robust means with less measurement error than a single sensor
|
||||||
|
would be capable of.
|
||||||
|
|
||||||
|
This idea of deriving more reliable data from different sources is known as
|
||||||
|
sensor fusion.
|
||||||
|
|
||||||
|
## Analog-to-Digital Converters (ADC)
|
||||||
|
|
||||||
|
There are a lots of digital sensors out there. You can use a protocol like I2C
|
||||||
|
and SPI to read them. But analog sensors also exist! These sensors just output a
|
||||||
|
voltage level that's proportional to the magnitude they are sensing.
|
||||||
|
|
||||||
|
The ADC peripheral can be use to convert that "analog" voltage level, say `1.25`
|
||||||
|
Volts,into a "digital" number, say in the `[0, 65535]` range, that the processor
|
||||||
|
can use in its calculations.
|
||||||
|
|
||||||
|
## Digital-to-Analog Converters (DAC)
|
||||||
|
|
||||||
|
As you might expect a DAC is exactly the opposite of ADC. You can write some
|
||||||
|
digital value into a register to produce a voltage in the `[0, 3.3V]` range
|
||||||
|
(assuming a `3.3V` power supply) on some "analog" pin. When this analog pin is
|
||||||
|
connected to some appropriate electronics and the register is written to at some
|
||||||
|
constant, fast rate (frequency) with the right values you can produce sounds or
|
||||||
|
even music!
|
||||||
|
|
||||||
|
## Real Time Clock (RTC)
|
||||||
|
|
||||||
|
This peripheral can be used to track time in "human format". Seconds, minutes,
|
||||||
|
hours, days, months and years. This peripheral handles the translation from
|
||||||
|
"ticks" to these human friendly units of time. It even handles leap years and
|
||||||
|
Daylight Save Time for you!
|
||||||
|
|
||||||
|
## Other communication protocols
|
||||||
|
|
||||||
|
SPI, I2S, SMBUS, CAN, IrDA, Ethernet, USB, Bluetooth, etc.
|
||||||
|
|
||||||
|
Different applications use different communication protocols. User facing
|
||||||
|
applications usually have an USB connector because USB is an ubiquitous
|
||||||
|
protocol in PCs and smartphones. Whereas inside cars you'll find plenty of CAN
|
||||||
|
"buses". Some digital sensors use SPI, others use I2C and others, SMBUS.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
So where to next? There are several options:
|
||||||
|
|
||||||
|
- You could check out the examples in the [`microbit`] board support crate repository. All those examples work for
|
||||||
|
the micro:bit board you have.
|
||||||
|
|
||||||
|
[`f3`]: https://docs.rs/f3
|
||||||
|
|
||||||
|
- You could try out [this motion sensors demo][madgwick]. Details about the implementation and
|
||||||
|
source code are available in [this blog post][wd-1-2].
|
||||||
|
|
||||||
|
[madgwick]: https://mobile.twitter.com/japaricious/status/962770003325005824
|
||||||
|
[wd-1-2]: http://blog.japaric.io/wd-1-2-l3gd20-lsm303dlhc-madgwick/
|
||||||
|
|
||||||
|
- You could check out [Real Time for The Masses]. A very efficient preemptive multitasking framework
|
||||||
|
that supports task prioritization and dead lock free execution.
|
||||||
|
|
||||||
|
[Real Time for The Masses]: https://docs.rs/cortex-m-rtfm
|
||||||
|
|
||||||
|
- You could try running Rust on a different development board. The easiest way to get started is to
|
||||||
|
use the [`cortex-m-quickstart`] Cargo project template.
|
||||||
|
|
||||||
|
[`cortex-m-quickstart`]: https://docs.rs/cortex-m-quickstart/0.2.4/cortex_m_quickstart
|
||||||
|
|
||||||
|
- You could check out [this blog post][brave-new-io] which describes how Rust type system can
|
||||||
|
prevent bugs in I/O configuration.
|
||||||
|
|
||||||
|
[brave-new-io]: http://blog.japaric.io/brave-new-io/
|
||||||
|
|
||||||
|
- You could check out my [blog] for miscellaneous topics about embedded development with Rust.
|
||||||
|
|
||||||
|
[blog]: http://blog.japaric.io
|
||||||
|
|
||||||
|
- You could check out the [`embedded-hal`] project which aims to build abstractions (traits) for all
|
||||||
|
the embedded I/O functionality commonly found on microcontrollers.
|
||||||
|
|
||||||
|
[`embedded-hal`]: https://github.com/japaric/embedded-hal
|
||||||
|
|
||||||
|
- You could join the [Weekly driver initiative] and help us write generic drivers on top of the
|
||||||
|
`embedded-hal` traits and that work for all sorts of platforms (ARM Cortex-M, AVR, MSP430, RISCV,
|
||||||
|
etc.)
|
||||||
|
|
||||||
|
[Weekly driver initiative]: https://github.com/rust-lang-nursery/embedded-wg/issues/39
|
||||||
170
src/appendix/troubleshooting.md
Normal file
170
src/appendix/troubleshooting.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
# General troubleshooting
|
||||||
|
|
||||||
|
## OpenOCD problems
|
||||||
|
|
||||||
|
### can't connect to OpenOCD - "Error: open failed"
|
||||||
|
|
||||||
|
#### Symptoms
|
||||||
|
|
||||||
|
Upon trying to establish a *new connection* with the device you get an error
|
||||||
|
that looks like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ openocd -f (..)
|
||||||
|
(..)
|
||||||
|
Error: open failed
|
||||||
|
in procedure 'init'
|
||||||
|
in procedure 'ocd_bouncer'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cause + Fix
|
||||||
|
|
||||||
|
- All: The device is not (properly) connected. Check the USB connection using
|
||||||
|
`lsusb` or the Device Manager.
|
||||||
|
- Linux: You may not have enough permission to open the device. Try again with
|
||||||
|
`sudo`. If that works, you can use [these instructions] to make OpenOCD work
|
||||||
|
without root privilege.
|
||||||
|
- Windows: You are probably missing the ST-LINK USB driver. Installation
|
||||||
|
instructions [here].
|
||||||
|
|
||||||
|
[these instructions]: 03-setup/linux.html#udev%20rules
|
||||||
|
[here]: 03-setup/windows.html#ST-LINK%20USB%20driver
|
||||||
|
|
||||||
|
### can't connect to OpenOCD - "Polling again in X00ms"
|
||||||
|
|
||||||
|
#### Symptoms
|
||||||
|
|
||||||
|
Upon trying to establish a *new connection* with the device you get an error
|
||||||
|
that looks like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ openocd -f (..)
|
||||||
|
(..)
|
||||||
|
Error: jtag status contains invalid mode value - communication failure
|
||||||
|
Polling target stm32f3x.cpu failed, trying to reexamine
|
||||||
|
Examination failed, GDB will be halted. Polling again in 100ms
|
||||||
|
Info : Previous state query failed, trying to reconnect
|
||||||
|
Error: jtag status contains invalid mode value - communication failure
|
||||||
|
Polling target stm32f3x.cpu failed, trying to reexamine
|
||||||
|
Examination failed, GDB will be halted. Polling again in 300ms
|
||||||
|
Info : Previous state query failed, trying to reconnect
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cause
|
||||||
|
|
||||||
|
The microcontroller may have get stuck in some tight infinite loop or it may be
|
||||||
|
continuously raising an exception, e.g. the exception handler is raising an
|
||||||
|
exception.
|
||||||
|
|
||||||
|
#### Fix
|
||||||
|
|
||||||
|
- Close OpenOCD, if running
|
||||||
|
- Press and hold the reset (black) button
|
||||||
|
- Launch the OpenOCD command
|
||||||
|
- Now, release the reset button
|
||||||
|
|
||||||
|
|
||||||
|
### OpenOCD connection lost - "Polling again in X00ms"
|
||||||
|
|
||||||
|
#### Symptoms
|
||||||
|
|
||||||
|
A *running* OpenOCD session suddenly errors with:
|
||||||
|
|
||||||
|
```
|
||||||
|
# openocd -f (..)
|
||||||
|
Error: jtag status contains invalid mode value - communication failure
|
||||||
|
Polling target stm32f3x.cpu failed, trying to reexamine
|
||||||
|
Examination failed, GDB will be halted. Polling again in 100ms
|
||||||
|
Info : Previous state query failed, trying to reconnect
|
||||||
|
Error: jtag status contains invalid mode value - communication failure
|
||||||
|
Polling target stm32f3x.cpu failed, trying to reexamine
|
||||||
|
Examination failed, GDB will be halted. Polling again in 300ms
|
||||||
|
Info : Previous state query failed, trying to reconnect
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cause
|
||||||
|
|
||||||
|
The USB connection was lost.
|
||||||
|
|
||||||
|
#### Fix
|
||||||
|
|
||||||
|
- Close OpenOCD
|
||||||
|
- Disconnect and re-connect the USB cable.
|
||||||
|
- Re-launch OpenOCD
|
||||||
|
|
||||||
|
### Can't flash the device - "Ignoring packet error, continuing..."
|
||||||
|
|
||||||
|
#### Symptoms
|
||||||
|
|
||||||
|
While flashing the device, you get:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ arm-none-eabi-gdb $file
|
||||||
|
Start address 0x8000194, load size 31588
|
||||||
|
Transfer rate: 22 KB/sec, 5264 bytes/write.
|
||||||
|
Ignoring packet error, continuing...
|
||||||
|
Ignoring packet error, continuing...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cause
|
||||||
|
|
||||||
|
Closed `itmdump` while a program that "printed" to the ITM was running. The
|
||||||
|
current GDB session will appear to work normally, just without ITM output but
|
||||||
|
the next GDB session will error with the message that was shown in the previous
|
||||||
|
section.
|
||||||
|
|
||||||
|
Or, `itmdump` was called **after** the `monitor tpiu` was issued thus making
|
||||||
|
`itmdump` delete the file / named-pipe that OpenOCD was writing to.
|
||||||
|
|
||||||
|
#### Fix
|
||||||
|
|
||||||
|
- Close/kill GDB, OpenOCD and `itmdump`
|
||||||
|
- Remove the file / named-pipe that `itmdump` was using (for example,
|
||||||
|
`itm.txt`).
|
||||||
|
- Launch OpenOCD
|
||||||
|
- Then, launch `itmdump`
|
||||||
|
- Then, launch the GDB session that executes the `monitor tpiu` command.
|
||||||
|
|
||||||
|
## Cargo problems
|
||||||
|
|
||||||
|
### "can't find crate for `core`"
|
||||||
|
|
||||||
|
#### Symptoms
|
||||||
|
|
||||||
|
```
|
||||||
|
Compiling volatile-register v0.1.2
|
||||||
|
Compiling rlibc v1.0.0
|
||||||
|
Compiling r0 v0.1.0
|
||||||
|
error[E0463]: can't find crate for `core`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
error[E0463]: can't find crate for `core`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
error[E0463]: can't find crate for `core`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Build failed, waiting for other jobs to finish...
|
||||||
|
Build failed, waiting for other jobs to finish...
|
||||||
|
error: Could not compile `r0`.
|
||||||
|
|
||||||
|
To learn more, run the command again with --verbose.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cause
|
||||||
|
|
||||||
|
You are using a toolchain older than `nightly-2018-04-08` and forgot to call `rustup target add
|
||||||
|
thumbv7m-none-eabi`.
|
||||||
|
|
||||||
|
#### Fix
|
||||||
|
|
||||||
|
Update your nightly and install the `thumbv7em-none-eabihf` target.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ rustup update nightly
|
||||||
|
|
||||||
|
$ rustup target add thumbv7em-none-eabihf
|
||||||
|
```
|
||||||
78
src/background/README.md
Normal file
78
src/background/README.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Background
|
||||||
|
|
||||||
|
## What is a microcontroller?
|
||||||
|
|
||||||
|
A microcontroller is a *system* on a chip. Whereas your laptop is made up of several discrete
|
||||||
|
components: a processor, RAM sticks, a hard drive, an ethernet port, etc.; a microcontroller has all
|
||||||
|
those components built into a single "chip" or package. This makes it possible to build systems with
|
||||||
|
minimal part count.
|
||||||
|
|
||||||
|
## What can you do with a microcontroller?
|
||||||
|
|
||||||
|
Lots of things! Microcontrollers are the central part of systems known as *embedded* systems. These
|
||||||
|
systems are everywhere but you don't usually notice them. These systems control the brakes of your
|
||||||
|
car, wash your clothes, print your documents, keep you warm, keep you cool, optimize the fuel
|
||||||
|
consumption of your car, etc.
|
||||||
|
|
||||||
|
The main trait of these systems is that they operate without user intervention even if they expose a
|
||||||
|
user interface like a washing machine does; most of their operation is done on their own.
|
||||||
|
|
||||||
|
The other common trait of these systems is that they *control* a process. And for that these systems
|
||||||
|
usually have one or more sensors and one or more actuators. For example, an HVAC system has several
|
||||||
|
sensors, thermometers and humidy sensors spread across some area, and several actuators as well,
|
||||||
|
heating elements and fans connected to ducts.
|
||||||
|
|
||||||
|
## When should I use a microcontroller?
|
||||||
|
|
||||||
|
All these application I've mentioned, you can probably implement with a Raspberry Pi, a computer
|
||||||
|
that runs Linux. Why should I bother with a microcontroller that operates without an OS? Sounds like
|
||||||
|
it would be harder to develop a program.
|
||||||
|
|
||||||
|
One main reason is cost. A microcontroller is much cheaper than a general purpose computer. Not only
|
||||||
|
the microcontroller is cheaper; it also requires much less external electrical components to
|
||||||
|
operate. This makes Printed Circuit Boards (PCB) smaller and cheaper to design and manufacture.
|
||||||
|
|
||||||
|
Another big reason is power consumption. A microcontroller consumes orders of magnitude less power
|
||||||
|
than a full blown processor. If your application will run on batteries that makes a huge difference.
|
||||||
|
|
||||||
|
And last but not least: (hard) *real time* constraints. Some processes require their controllers to
|
||||||
|
respond to some events within some time interval (e.g. a quadcopter/drone hit by a wind gust). If
|
||||||
|
this *deadline* is not met, the process could end in catastrophic failure (e.g. the drone crashes to
|
||||||
|
the ground). A general purpose computer running a general purpose OS has many services running in
|
||||||
|
the background. This makes it hard to guarantee execution of a program within tight time constraints.
|
||||||
|
|
||||||
|
## When should I *not* use a microcontroller?
|
||||||
|
|
||||||
|
Where heavy computations are involved. To keep their power consumption low, microcontrollers have
|
||||||
|
very limited computational resources available to them. For example, some microcontrollers don't
|
||||||
|
even have hardware support for floating point operations. On those devices, performing a simple
|
||||||
|
addition of single precision numbers can take hundreds of CPU cycles.
|
||||||
|
|
||||||
|
## Development on the micro:bit
|
||||||
|
|
||||||
|
The [micro:bit website](https://microbit.org/code/) offers several very simple ways of programming a
|
||||||
|
microbit, aimed at teaching school children how to program. This is a very good introduction to the
|
||||||
|
world of microcontollers **and** programming, but falls short of teaching true embedded development.
|
||||||
|
From there you would usually move to C to develop skills useful in industry, developing performant
|
||||||
|
embedded software.
|
||||||
|
|
||||||
|
## Why use Rust and not C?
|
||||||
|
|
||||||
|
Hopefully I don't need to convince you here as you are probably familiar with the language
|
||||||
|
differences between Rust and C. One point I do want to bring up is package management. C lacks an
|
||||||
|
official, widely accepted package management solution whereas Rust has Cargo. This makes development
|
||||||
|
*much* easier. And, IMO, easy package management encourages code reuse because libraries can be
|
||||||
|
easily integrated into an application which is also a good thing as libraries get more "battle
|
||||||
|
testing".
|
||||||
|
|
||||||
|
## Why should I not use Rust?
|
||||||
|
|
||||||
|
Or why should I prefer C over Rust?
|
||||||
|
|
||||||
|
The C ecosystem is way more mature. Off the shelf solution for several problems already exist. If
|
||||||
|
you need to control a time sensitive process, you can grab one of the existing commercial Real Time
|
||||||
|
Operating Systems (RTOS) out there and solve your problem. There are no commercial, production-grade
|
||||||
|
RTOSes in Rust yet so you would have to either create one yourself or try one of the ones that are
|
||||||
|
in development. If you are looking to develop your skills to find a job, it is currently unlikely
|
||||||
|
that a company doing embedded software development will be using Rust, and so your time would be
|
||||||
|
better spent learning normal embedded development using C.
|
||||||
9
src/getting-started/.cargo/config
Normal file
9
src/getting-started/.cargo/config
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[target.thumbv6m-none-eabi]
|
||||||
|
runner = "arm-none-eabi-gdb"
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=-Wl,-Tlink.x",
|
||||||
|
"-C", "link-arg=-nostartfiles",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
target = "thumbv6m-none-eabi"
|
||||||
4
src/getting-started/.gdbinit
Normal file
4
src/getting-started/.gdbinit
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
target remote :3333
|
||||||
|
load
|
||||||
|
break main
|
||||||
|
continue
|
||||||
13
src/getting-started/00.00.README.md
Normal file
13
src/getting-started/00.00.README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Getting started
|
||||||
|
|
||||||
|
Alright, let's start as you usually would with Rust.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ rustup update
|
||||||
|
```
|
||||||
|
|
||||||
|
It is always good to keep your toolchain up to date.
|
||||||
|
|
||||||
|
Now let's make a new binary project.
|
||||||
|
You might not do this often, so it is understandeable to forget.
|
||||||
|
If you run `$ cargo`, you will be given a hint.
|
||||||
388
src/getting-started/01.00.PROJECT.md
Normal file
388
src/getting-started/01.00.PROJECT.md
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
# New Project
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cargo new rustled
|
||||||
|
Created binary (application) `rustled` project
|
||||||
|
$ cd rustled
|
||||||
|
Cargo.toml src
|
||||||
|
```
|
||||||
|
|
||||||
|
This has created a binary crate.
|
||||||
|
|
||||||
|
Now we could `$ cargo build` this, and even `$ cargo run` it,
|
||||||
|
but everything is being compiled for, and run on, your computer.
|
||||||
|
|
||||||
|
## Targets
|
||||||
|
|
||||||
|
The micro:bit has a different architecture than your computer,
|
||||||
|
so the first step will be to cross compile for the micro:bit's architecture.
|
||||||
|
If you were to do an internet search, you would find a [platform support list for Rust][platforms].
|
||||||
|
Looking into this page, you will find the micro:bit's nRF51822 Cortex-M0 microprocessor:
|
||||||
|
|
||||||
|
> `thumbv6m-none-eabi [*] [ ] [ ] Bare Cortex-M0, M0+, M1`
|
||||||
|
|
||||||
|
"thumbv6m-none-eabi" is known a a target triple. Note what the star represents:
|
||||||
|
|
||||||
|
> These are bare-metal microcontroller targets that only have access to the core library, not std.
|
||||||
|
|
||||||
|
To install this target:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ rustup target add thumbv6m-none-eabi
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build 1
|
||||||
|
|
||||||
|
Now how should we use this? Well, if you were to take a look at `$ cargo build -h`, you would try:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cargo build --target thumbv6m-none-eabi
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
error[E0463]: can't find crate for `std`
|
||||||
|
|
|
||||||
|
= note: the `thumbv6m-none-eabi` target may not be installed
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0463`.
|
||||||
|
error: Could not compile `rustled`.
|
||||||
|
|
||||||
|
To learn more, run the command again with --verbose.
|
||||||
|
```
|
||||||
|
|
||||||
|
The help note is rather unhelpful because we just installed that target.
|
||||||
|
We also just noted that the thumbv6m-none-eabi target does not include std,
|
||||||
|
only the core crate, which is has a platform independent subset of the std features.
|
||||||
|
Why is it still looking for the std crate when we build?
|
||||||
|
|
||||||
|
### `no_std`
|
||||||
|
|
||||||
|
It turns out, rust will always look for the std crate unless explicitly disabled,
|
||||||
|
so we will add the no_std attribute
|
||||||
|
|
||||||
|
`src/main.rs`
|
||||||
|
``` rust
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build 2
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cargo build --target thumbv6m-none-eabi
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
error: cannot find macro `println!` in this scope
|
||||||
|
--> src/main.rs:4:5
|
||||||
|
|
|
||||||
|
4 | println!("Hello, world!");
|
||||||
|
| ^^^^^^^
|
||||||
|
```
|
||||||
|
|
||||||
|
`println` is a macro found in the std crate.
|
||||||
|
We don't need it at the moment, so we can remove it and try to compile again:
|
||||||
|
|
||||||
|
```
|
||||||
|
error: language item required, but not found: `panic_impl`
|
||||||
|
```
|
||||||
|
|
||||||
|
This error, is because the panic macro is unimplemented,
|
||||||
|
when rustc needs it to have an implementation.
|
||||||
|
|
||||||
|
### `panic_impl`
|
||||||
|
|
||||||
|
We could try and implement the panic macro ourselves,
|
||||||
|
but it's easier and more portable to use a crate that does it for us.
|
||||||
|
|
||||||
|
If we look on [crates.io for the panic-impl keyword][panic] we will find some examples.
|
||||||
|
Let us pic the simplest one, and add it to our Cargo.toml.
|
||||||
|
If you have forgotten how to do this, try looking at [the cargo book][cargo].
|
||||||
|
|
||||||
|
[platforms]: https://forge.rust-lang.org/platform-support.html
|
||||||
|
[panic]: https://crates.io/keywords/panic-impl
|
||||||
|
[cargo]: https://doc.rust-lang.org/stable/cargo/
|
||||||
|
|
||||||
|
`Cargo.toml`
|
||||||
|
```
|
||||||
|
[dependencies]
|
||||||
|
panic-abort = "~0.2"
|
||||||
|
```
|
||||||
|
|
||||||
|
`src/main.rs`
|
||||||
|
```
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build 3
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cargo build --target thumbv6m-none-eabi
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
error: requires `start` lang_item
|
||||||
|
```
|
||||||
|
|
||||||
|
### `no_main`
|
||||||
|
|
||||||
|
In the normal command line rust binaries you would be used to making,
|
||||||
|
executing the binary usually has the operating system start by executing the C runtime library (crt0).
|
||||||
|
This in turn invokes the Rust runtime, as marked by the `start` language item,
|
||||||
|
which in turn invokes the main function.
|
||||||
|
|
||||||
|
Having enabled `no_std`, as we are targeting on a microcontroller,
|
||||||
|
neither the crt0 nor the rust runtime are available,
|
||||||
|
so even implementing `start` would not help us.
|
||||||
|
We need to replace the operating system entry point.
|
||||||
|
|
||||||
|
You could for example name a function after the default entry point, which for linux is `_main`,
|
||||||
|
and start that way. Note, you would also need to disable [name mangling][nm]:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn _start() -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[nm]: https://en.wikipedia.org/wiki/Name_mangling
|
||||||
|
|
||||||
|
This is the end of the road for trying to get this to work on our own.
|
||||||
|
At this point we need the help of a board specific crate and a few cargo tweaks to get this working.
|
||||||
|
|
||||||
|
## microbit crate
|
||||||
|
|
||||||
|
Let us add a dependency on the board crate for the micro:bit.
|
||||||
|
|
||||||
|
```
|
||||||
|
[dependencies]
|
||||||
|
panic-abort = "~0.2"
|
||||||
|
microbit="~0.5"
|
||||||
|
```
|
||||||
|
|
||||||
|
The microbit crate has 2 notable dependencies:
|
||||||
|
|
||||||
|
### `embedded-hal`
|
||||||
|
|
||||||
|
This crate is a HAL implementation crate, where HAL stands for *hardware abstraction layer*.
|
||||||
|
As rust becomes more and more popular in embedded development,
|
||||||
|
it is desireable to have as little hardware specific implementation as possible.
|
||||||
|
|
||||||
|
For this reason, the `embedded-hal` crate contains a range of hardware abstraction traits which can
|
||||||
|
be implemented by board specific crates.
|
||||||
|
|
||||||
|
### `cortex-m-rt`
|
||||||
|
|
||||||
|
This crate implements the minimal startup / runtime for Cortex-M microcontrollers.
|
||||||
|
Among other things this crate provides:
|
||||||
|
- the `entry!` macro, to define the entry point of the program.
|
||||||
|
- the `exception!` macro, to set or override a processor core exception handler.
|
||||||
|
|
||||||
|
This crate requires:
|
||||||
|
- a definition of the specific microcontroller's memory layout as a memory.x file.
|
||||||
|
- a definition of the hard fault handler
|
||||||
|
- a definition of the default exception handler
|
||||||
|
|
||||||
|
For more detailed information,
|
||||||
|
you can use the helpful [cortex-m-quickstart crate][qs] and [its documentation][doc].
|
||||||
|
|
||||||
|
[qs]: https://docs.rs/crate/cortex-m-quickstart
|
||||||
|
[doc]: https://docs.rs/cortex-m-quickstart
|
||||||
|
|
||||||
|
## cargo config
|
||||||
|
|
||||||
|
Before we go any further,
|
||||||
|
we are going to tweak the cargo's configuration by editing `rustled/.cargo/config`.
|
||||||
|
For more information, you can read [the documentation here][cargoconfig].
|
||||||
|
|
||||||
|
[cargoconfig]: https://doc.rust-lang.org/cargo/reference/config.html
|
||||||
|
|
||||||
|
``` toml
|
||||||
|
# Configure builds for our target
|
||||||
|
[target.thumbv6m-none-eabi]
|
||||||
|
# Execute binary using gdb
|
||||||
|
runner = "arm-none-eabi-gdb"
|
||||||
|
# Tweak to the linking process required by the cortex-m-rt crate
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
"-C", "link-arg=-nostartfiles",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Automatically select this target when running cargo for this project
|
||||||
|
[build]
|
||||||
|
target = "thumbv6m-none-eabi"
|
||||||
|
```
|
||||||
|
|
||||||
|
### arm-none-eabi-gdb
|
||||||
|
|
||||||
|
This is a version of gdb (the GNU debugger) for the ARM EABI (embedded application binary interface).
|
||||||
|
It will allow us to debug the code running on our micro:bit, from your computer.
|
||||||
|
|
||||||
|
### Build target
|
||||||
|
|
||||||
|
Now, all you need to do is run `$ cargo build`,
|
||||||
|
and cargo will automatically add `--target thumbv6m-none-eabi`.
|
||||||
|
|
||||||
|
## Build 4
|
||||||
|
|
||||||
|
`Cargo.toml`
|
||||||
|
```
|
||||||
|
[dependencies]
|
||||||
|
panic-abort = "~0.2"
|
||||||
|
microbit="~0.5"
|
||||||
|
```
|
||||||
|
|
||||||
|
`src/main.rs`
|
||||||
|
```
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
``` console
|
||||||
|
cargo build
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> src/main.rs:9:1
|
||||||
|
|
|
||||||
|
8 | entry!(main);
|
||||||
|
| ^^^^^^^^^^^^^ expected !, found ()
|
||||||
|
|
|
||||||
|
= note: expected type `fn() -> !`
|
||||||
|
found type `fn() {main}`
|
||||||
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
```
|
||||||
|
|
||||||
|
## `!` return type
|
||||||
|
|
||||||
|
A little known rust feature, so I will forgive you if you do not know what this means.
|
||||||
|
A return type of `!` means that the function cannot return
|
||||||
|
An easy way to implement this, is by using an infinite loop.
|
||||||
|
|
||||||
|
`src/main.rs`
|
||||||
|
```
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
|
||||||
|
#[macro_use(entry)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build 5
|
||||||
|
|
||||||
|
```
|
||||||
|
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
|
||||||
|
|
|
||||||
|
= note: "arm-none-eabi-gcc" "-L" "/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib" "/home/xxx/rust/rustled/target/thumbv6m-none-eabi/debug/deps/rustled-e6053d34b0422141.2yhvr0tmp69gb94x.rcgu.o" "-o"
|
||||||
|
# SNIP
|
||||||
|
"/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcore-fb37a4ea1db1e473.rlib" "-Wl,--end-group" "/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcompiler_builtins-f2357c0397dd7e0d.rlib" "-Wl,-Tlink.x" "-nostartfiles" "-Wl,-Bdynamic"
|
||||||
|
= note: /usr/lib/gcc/arm-none-eabi/8.1.0/../../../../arm-none-eabi/bin/ld: cannot open linker script file memory.x: No such file or directory
|
||||||
|
collect2: error: ld returned 1 exit status
|
||||||
|
```
|
||||||
|
|
||||||
|
A scary error, but if you look closely you will see `cannot open linker script file memory.x: No such file or directory`.
|
||||||
|
We mentioned something a little earlier about memory.x file.
|
||||||
|
To save you the hassle of scouring the internet for one or creating your own, you can copy it over into your project:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
cp ../getting-started/memory.x
|
||||||
|
```
|
||||||
|
|
||||||
|
> Often a board support crate will already include this, so this step will not be necessary.
|
||||||
|
|
||||||
|
## Build 6
|
||||||
|
|
||||||
|
```
|
||||||
|
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
|
||||||
|
|
|
||||||
|
= note: "arm-none-eabi-gcc" "-L" "/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib" "/home/xxx/rust/rustled/target/thumbv6m-none-eabi/debug/deps/rustled-e6053d34b0422141.2yhvr0tmp69gb94x.rcgu.o" "-o"
|
||||||
|
# SNIP
|
||||||
|
"/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcompiler_builtins-f2357c0397dd7e0d.rlib" "-Wl,-Tlink.x" "-nostartfiles" "-Wl,-Bdynamic"
|
||||||
|
= note: device.x:1: undefined symbol `DefaultHandler' referenced in expression
|
||||||
|
collect2: error: ld returned 1 exit status
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice `undefined symbol 'DefaultHandler' referenced in expression`.
|
||||||
|
We said earlier, as with the memory,
|
||||||
|
that the hard fault handler and default exception handler both need defining.
|
||||||
|
|
||||||
|
`Cargo.toml`
|
||||||
|
```
|
||||||
|
[dependencies]
|
||||||
|
panic-abort = "~0.2"
|
||||||
|
cortex-m-rt="~0.5"
|
||||||
|
microbit="~0.5"
|
||||||
|
```
|
||||||
|
|
||||||
|
`src/main.rs`
|
||||||
|
```
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hard_fault);
|
||||||
|
|
||||||
|
fn hard_fault(ef: &ExceptionFrame) -> ! {
|
||||||
|
panic!("{:#?}", ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(*, default_handler);
|
||||||
|
|
||||||
|
fn default_handler(irqn: i16) {
|
||||||
|
panic!("Unhandled exception (IRQn = {})", irqn);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It is all a bit ugly, but fortunately it only needs to be done once.
|
||||||
|
If you try building now, you should finally be greeted with `Finished`!
|
||||||
|
|
||||||
|
## Build Complete
|
||||||
|
|
||||||
|
As a sanity check, let's verify that the produced executable is actually an ARM binary:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ file target/thumbv6m-none-eabi/debug/rustled
|
||||||
|
target/thumbv6m-none-eabi/debug/rustled: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
|
||||||
|
^^^ ^^^^
|
||||||
|
```
|
||||||
192
src/getting-started/02.00.FLASH.md
Normal file
192
src/getting-started/02.00.FLASH.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# Flashing
|
||||||
|
|
||||||
|
Flashing is the process of moving our program into the microcontroller's (persistent) memory. Once flashed, the microcontroller will execute the flashed program every time it is powered on.
|
||||||
|
|
||||||
|
In this case, our `rustled` program will be the only program in the microcontroller memory. By this I mean that there's nothing else running on the microcontroller: no OS, no "daemon", nothing. `rustled` has full control over the device. This is what is meant by *bare-metal* programming.
|
||||||
|
|
||||||
|
Onto the actual flashing. First thing we need is to do is launch OpenOCD. We did that in the previous section but this time we'll run the command inside a temporary directory (/tmp on *nix; %TEMP% on Windows).
|
||||||
|
|
||||||
|
Connect the mirco:bit to your computer and run the following commands on a new terminal.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ # *nix
|
||||||
|
$ cd /tmp
|
||||||
|
|
||||||
|
$ # Windows
|
||||||
|
$ cd %TEMP%
|
||||||
|
```
|
||||||
|
|
||||||
|
We need to give OCD the name of the interfaces we are using:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ # All
|
||||||
|
$ # Windows: remember that you need an extra `-s %PATH_TO_OPENOCD%\share\scripts`
|
||||||
|
$ openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
The program will block; leave that terminal open.
|
||||||
|
|
||||||
|
Now it's a good time to explain what this command is actually doing.
|
||||||
|
|
||||||
|
I mentioned that the micro:bit actually has two microcontrollers.
|
||||||
|
One of them is used as a USB interface and programmer/debugger.
|
||||||
|
This microcontroller is connected to the target microcontroller using a Serial Wire Debug (SWD) interface
|
||||||
|
(this interface is an ARM standard so you'll run into it when dealing with other Cortex-M based microcontrollers).
|
||||||
|
This SWD interface can be used to flash and debug a microcontroller.
|
||||||
|
It uses the CMSIS-DAP protocol for host debugging of application programs.
|
||||||
|
It will appear as a USB device when you connect the micro:bit to your laptop.
|
||||||
|
|
||||||
|
As for OpenOCD, it's software that provides some services like a *GDB server* on top of USB
|
||||||
|
devices that expose a debugging protocol like SWD or JTAG.
|
||||||
|
|
||||||
|
Onto the actual command: those `.cfg` files we are using instruct OpenOCD to look for
|
||||||
|
- a CMSIS-DAP USB interface device (`interface/cmsis-dap.cfg`)
|
||||||
|
- a nRF51XXX microcontroller target (`target/nrf51.cfg`) to be connected to the USB interface.
|
||||||
|
|
||||||
|
The OpenOCD output looks like this:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
Open On-Chip Debugger 0.9.0 (2016-04-27-23:18)
|
||||||
|
Licensed under GNU GPL v2
|
||||||
|
For bug reports, read
|
||||||
|
http://openocd.org/doc/doxygen/bugs.html
|
||||||
|
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
|
||||||
|
adapter speed: 1000 kHz
|
||||||
|
adapter_nsrst_delay: 100
|
||||||
|
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
|
||||||
|
none separate
|
||||||
|
Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
Info : clock speed 950 kHz
|
||||||
|
Info : STLINK v2 JTAG v27 API v2 SWIM v15 VID 0x0483 PID 0x374B
|
||||||
|
Info : using stlink api v2
|
||||||
|
Info : Target voltage: 2.919073
|
||||||
|
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
|
||||||
|
```
|
||||||
|
|
||||||
|
The "6 breakpoints, 4 watchpoints" part indicates the debugging features the processor has
|
||||||
|
available.
|
||||||
|
|
||||||
|
I mentioned that OpenOCD provides a GDB server so let's connect to that right now:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ arm-none-eabi-gdb -q target/thumbv7em-none-eabihf/debug/led-roulette
|
||||||
|
Reading symbols from target/thumbv7em-none-eabihf/debug/led-roulette...done.
|
||||||
|
(gdb)
|
||||||
|
```
|
||||||
|
|
||||||
|
This only opens a GDB shell. To actually connect to the OpenOCD GDB server, use the following
|
||||||
|
command within the GDB shell:
|
||||||
|
|
||||||
|
```
|
||||||
|
(gdb) target remote :3333
|
||||||
|
Remote debugging using :3333
|
||||||
|
0x00000000 in ?? ()
|
||||||
|
```
|
||||||
|
|
||||||
|
By default OpenOCD's GDB server listens on TCP port 3333 (localhost). This command is connecting to
|
||||||
|
that port.
|
||||||
|
|
||||||
|
After entering this command, you'll see new output in the OpenOCD terminal:
|
||||||
|
|
||||||
|
``` diff
|
||||||
|
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
|
||||||
|
+Info : accepting 'gdb' connection on tcp/3333
|
||||||
|
+Info : device id = 0x10036422
|
||||||
|
+Info : flash size = 256kbytes
|
||||||
|
```
|
||||||
|
|
||||||
|
Almost there. To flash the device, we'll use the `load` command inside the GDB shell:
|
||||||
|
|
||||||
|
```
|
||||||
|
(gdb) load
|
||||||
|
Loading section .vector_table, size 0x188 lma 0x8000000
|
||||||
|
Loading section .text, size 0x38a lma 0x8000188
|
||||||
|
Loading section .rodata, size 0x8 lma 0x8000514
|
||||||
|
Start address 0x8000188, load size 1306
|
||||||
|
Transfer rate: 6 KB/sec, 435 bytes/write.
|
||||||
|
```
|
||||||
|
|
||||||
|
And that's it. You'll also see new output in the OpenOCD terminal.
|
||||||
|
|
||||||
|
``` diff
|
||||||
|
Info : flash size = 256kbytes
|
||||||
|
+Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
+Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
+adapter speed: 950 kHz
|
||||||
|
+target state: halted
|
||||||
|
+target halted due to debug-request, current mode: Thread
|
||||||
|
+xPSR: 0x01000000 pc: 0x08000194 msp: 0x2000a000
|
||||||
|
+Info : Unable to match requested speed 8000 kHz, using 4000 kHz
|
||||||
|
+Info : Unable to match requested speed 8000 kHz, using 4000 kHz
|
||||||
|
+adapter speed: 4000 kHz
|
||||||
|
+target state: halted
|
||||||
|
+target halted due to breakpoint, current mode: Thread
|
||||||
|
+xPSR: 0x61000000 pc: 0x2000003a msp: 0x2000a000
|
||||||
|
+Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
+Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
+adapter speed: 950 kHz
|
||||||
|
+target state: halted
|
||||||
|
+target halted due to debug-request, current mode: Thread
|
||||||
|
+xPSR: 0x01000000 pc: 0x08000194 msp: 0x2000a000
|
||||||
|
```
|
||||||
|
|
||||||
|
Our program is loaded, we can now run it!
|
||||||
|
|
||||||
|
```
|
||||||
|
(gdb) continue
|
||||||
|
Continuing.
|
||||||
|
```
|
||||||
|
|
||||||
|
Continue runs the program until the next breakpoint.
|
||||||
|
This time it blocks, nothing happens.
|
||||||
|
This is because all we have in our code is a loop!
|
||||||
|
|
||||||
|
## `.gdbinit`
|
||||||
|
|
||||||
|
Before we move on though, we are going to add one more file to our project.
|
||||||
|
This will automate the last few steps so we don't need to repeatedly do the same actions in gdb:
|
||||||
|
|
||||||
|
`.gdbinit`
|
||||||
|
```
|
||||||
|
target remote :3333
|
||||||
|
load
|
||||||
|
```
|
||||||
|
|
||||||
|
## LED
|
||||||
|
|
||||||
|
Let us now turn on an LED! But how?
|
||||||
|
|
||||||
|
Well, first we should look at the documentation of our crate,
|
||||||
|
and you should be able to figure out how to get access to the gpio,
|
||||||
|
and set individual pins high and low:
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
let mut pin1 = gpio.pin1.into_push_pull_output();
|
||||||
|
pin1.set_high();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Next we need to see how these pins are hooked up,
|
||||||
|
for that we need [the micro:bit schematics][schematics] linked to at the bottom of [the hardware overview][hw].
|
||||||
|
On the first sheet you should find a diagram with a grid of numbered LEDs.
|
||||||
|
|
||||||
|
> If you do not know much about electronics:
|
||||||
|
> Each row and column (labelled ROW and COL) represent a GPIO output pin.
|
||||||
|
> The components labelled LED are light emitting diodes;
|
||||||
|
> LEDs only let current flow one way, and only emit light when current is flowing.
|
||||||
|
> If a row is set high, high voltage, and a column is set low, low voltage,
|
||||||
|
> the LED at the point that they cross will have a potential difference across it,
|
||||||
|
> so current will flow and it will light up.
|
||||||
|
|
||||||
|
It is worth noting that the 5x5 array of LEDs is wired up as a 9x3 array, with 2 missing.
|
||||||
|
This is usually done to make the circuit design easier.
|
||||||
|
|
||||||
|
The fifth sheet shows how each row and column correspond to each GPIO pin.
|
||||||
|
|
||||||
|
[hw]: http://tech.microbit.org/hardware/
|
||||||
|
[schematics]: https://github.com/bbcmicrobit/hardware/blob/master/SCH_BBC-Microbit_V1.3B.pdf
|
||||||
|
|
||||||
|
You should now have enough information to try and turn on an LED.
|
||||||
41
src/getting-started/03.00.LED.md
Normal file
41
src/getting-started/03.00.LED.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# LED
|
||||||
|
|
||||||
|
This is my solution:
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_abort;
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
|
||||||
|
#[macro_use(entry, exception)]
|
||||||
|
extern crate microbit;
|
||||||
|
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
use microbit::hal::prelude::*;
|
||||||
|
|
||||||
|
entry!(main);
|
||||||
|
fn main() -> ! {
|
||||||
|
if let Some(p) = microbit::Peripherals::take() {
|
||||||
|
let mut gpio = p.GPIO.split();
|
||||||
|
let mut led = gpio.pin13.into_push_pull_output();
|
||||||
|
let _ = gpio.pin4.into_push_pull_output();
|
||||||
|
led.set_high();
|
||||||
|
}
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hard_fault);
|
||||||
|
|
||||||
|
fn hard_fault(ef: &ExceptionFrame) -> ! {
|
||||||
|
panic!("{:#?}", ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(*, default_handler);
|
||||||
|
|
||||||
|
fn default_handler(irqn: i16) {
|
||||||
|
panic!("Unhandled exception (IRQn = {})", irqn);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
It is worth noting that pin4 starts low, so does not need to be explicitly set low.
|
||||||
1
src/getting-started/04.00.DEBUGGING.md
Normal file
1
src/getting-started/04.00.DEBUGGING.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Debugging
|
||||||
8
src/getting-started/Cargo.toml
Normal file
8
src/getting-started/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "rustled"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
panic-abort = "~0.2"
|
||||||
|
cortex-m-rt="~0.5"
|
||||||
|
microbit="~0.5"
|
||||||
11
src/getting-started/memory.x
Normal file
11
src/getting-started/memory.x
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* NOTE K = KiBi = 1024 bytes */
|
||||||
|
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 16K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is where the call stack will be allocated. */
|
||||||
|
/* The stack is of the full descending type. */
|
||||||
|
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
|
||||||
|
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
29
src/getting-started/src/main.rs
Normal file
29
src/getting-started/src/main.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#![deny(unsafe_code)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate aux5;
|
||||||
|
|
||||||
|
use aux5::prelude::*;
|
||||||
|
use aux5::{Delay, Leds};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (mut delay, mut leds): (Delay, Leds) = aux5::init();
|
||||||
|
|
||||||
|
let period = 50_u16;
|
||||||
|
let mut step: usize = 0;
|
||||||
|
loop {
|
||||||
|
match step % 2 {
|
||||||
|
0 => leds[step/2].on(),
|
||||||
|
1 => {
|
||||||
|
let wrap_step = ((step + 16 - 3) / 2) % 8;
|
||||||
|
leds[wrap_step].off();
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
delay.delay_ms(period);
|
||||||
|
match step {
|
||||||
|
15 => step = 0,
|
||||||
|
_ => step += 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/hardware/README.md
Normal file
58
src/hardware/README.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Meet your hardware
|
||||||
|
|
||||||
|
Let's get familiar with the hardware we'll be working with.
|
||||||
|
|
||||||
|
## BBC micro:bit (the "microbit")
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img title="microbit" src="http://tech.microbit.org/docs/hardware/assets/microbit-overview.png">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
What does this board contain? For full details see the [microbit hardware page][microbit].
|
||||||
|
|
||||||
|
[microbit]: http://tech.microbit.org/hardware
|
||||||
|
|
||||||
|
- A Nordic nRF51822 microcontroller. This microcontroller has
|
||||||
|
|
||||||
|
- A single core ARM Cortex-M0 processor with a maximum clock frequency of 16 MHz.
|
||||||
|
|
||||||
|
- 256 KB of flash memory. (1 KB = 10**24** bytes)
|
||||||
|
|
||||||
|
- 16 KB of static RAM.
|
||||||
|
|
||||||
|
- many "peripherals": timers, GPIO, I2C, SPI, UART, etc.
|
||||||
|
|
||||||
|
- This microcontroller operates at (around) 3.3V.
|
||||||
|
|
||||||
|
- 2 user buttons on the front and 1 reset button on the back.
|
||||||
|
|
||||||
|
- A 5x5 array of user LEDs.
|
||||||
|
|
||||||
|
- A configureable 23-pin edge connector
|
||||||
|
|
||||||
|
- A 2.4GHz radio transciever with support for [bluetooth low energy][ble] (BLE).
|
||||||
|
|
||||||
|
[ble]: https://en.wikipedia.org/wiki/Bluetooth_Low_Energy
|
||||||
|
|
||||||
|
- An on-core nRF51 temperature sensor.
|
||||||
|
|
||||||
|
- An NXP/Freescale MMA8652 3-axis [accelerometer].
|
||||||
|
|
||||||
|
[accelerometer]: https://en.wikipedia.org/wiki/Accelerometer
|
||||||
|
|
||||||
|
- An NXP/Freescale MAG3110 3-axis [magnetometer].
|
||||||
|
|
||||||
|
[magnetometer]: https://en.wikipedia.org/wiki/Magnetometer
|
||||||
|
|
||||||
|
- A second microcontroller: NXP/Freescale KL26Z. This microcontroller handles the USB interface,
|
||||||
|
communication between your computer and the main microcontroller,
|
||||||
|
and changing the USB's input voltage from 5V to 3.3V.
|
||||||
|
|
||||||
|
## Micro-USB Cable
|
||||||
|
|
||||||
|
This can be any generic cable, and is used to connect the microbit to your computer.
|
||||||
|
|
||||||
|
## External battery pack
|
||||||
|
|
||||||
|
The external battery pack that comes with the microbit will not be used explicitly as part of this guide,
|
||||||
|
but feel free to use it to test your software without being tethered to a computer.
|
||||||
52
src/requirements/README.md
Normal file
52
src/requirements/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
## Knowledge
|
||||||
|
|
||||||
|
The only knowledge requirement to read this book is to know *some* Rust. It's hard to
|
||||||
|
quantify *some* but a good benchmark is having read and understood the first 14 chapters of [the Rust book][thebook].
|
||||||
|
|
||||||
|
[thebook]: https://doc.rust-lang.org/nightly/book/
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
To follow this material you'll only need a [micro:bit].
|
||||||
|
|
||||||
|
[micro:bit]: http://tech.microbit.org/hardware/
|
||||||
|
|
||||||
|
You can purchase the BBC micro:bit from [a large list of international resellers][resellers].
|
||||||
|
|
||||||
|
[resellers]: https://microbit.org/resellers/
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img title="microbit" src="https://microbit.org/images/microbit-front.png" width="45%">
|
||||||
|
<img title="microbit" src="https://microbit.org/images/microbit-back.png" width="45%">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
> **FAQ**: Wait, why do I need this specific device?
|
||||||
|
|
||||||
|
It makes my life and yours much easier.
|
||||||
|
|
||||||
|
The material is much, much more approachable if we don't have to worry about hardware differences.
|
||||||
|
Trust me on this one.
|
||||||
|
|
||||||
|
> **FAQ**: Can I follow this material with a different development board?
|
||||||
|
|
||||||
|
Maybe? It depends mainly on two things: your previous experience with microcontrollers and/or
|
||||||
|
whether there already exists a high level crate. A list of boards with high level crates available can be found [here][bsc].
|
||||||
|
|
||||||
|
[bsc]: https://github.com/rust-embedded/awesome-embedded-rust#board-support-crates
|
||||||
|
|
||||||
|
With other development boards, this text would lose most if not all its beginner friendliness
|
||||||
|
and "easy to follow"-ness, IMO.
|
||||||
|
|
||||||
|
There are other similar guides for different hardware. For a full list see [this list][books].
|
||||||
|
[books]: https://github.com/rust-embedded/awesome-embedded-rust/#books-blogs-and-training-materials
|
||||||
|
The following are worth a special mention:
|
||||||
|
- [Discovery](https://japaric.github.io/discovery/) by @japaric: The genesis guide which this is based on. Uses the STM32F3DISCOVERY.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
If you have a different cortex-m development board and you don't consider yourself a total beginner, you are
|
||||||
|
better off starting with the [cortex-m-quickstart] project template.
|
||||||
|
|
||||||
|
[cortex-m-quickstart]: https://docs.rs/crate/cortex-m-quickstart
|
||||||
158
src/setup/LINUX.md
Normal file
158
src/setup/LINUX.md
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# Linux
|
||||||
|
|
||||||
|
Here are the installation commands for a few Linux distributions.
|
||||||
|
|
||||||
|
## REQUIRED packages
|
||||||
|
|
||||||
|
- Ubuntu 16.04 or newer / Debian Jessie or newer
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo apt-get install \
|
||||||
|
gcc-arm-none-eabi \
|
||||||
|
gdb-arm-none-eabi \
|
||||||
|
minicom \
|
||||||
|
openocd
|
||||||
|
```
|
||||||
|
|
||||||
|
- Fedora 23 or newer
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo dnf install \
|
||||||
|
arm-none-eabi-gcc-cs \
|
||||||
|
arm-none-eabi-gdb \
|
||||||
|
minicom \
|
||||||
|
openocd
|
||||||
|
```
|
||||||
|
|
||||||
|
- Arch Linux
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo pacman -S \
|
||||||
|
arm-none-eabi-gcc \
|
||||||
|
arm-none-eabi-gdb \
|
||||||
|
minicom \
|
||||||
|
openocd
|
||||||
|
```
|
||||||
|
|
||||||
|
- Other distros
|
||||||
|
|
||||||
|
For distros that don't have packages for [ARM's pre-built toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads), download the "Linux 64-bit" file and put its `bin` directory on your path. Here's one way to do it:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ mkdir -p ~/local && cd ~/local
|
||||||
|
$ tar xjf /path/to/downloaded/file/gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2.tbz
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, use your editor of choice to append to your `PATH` in the appropriate shell init file (e.g. `~/.zshrc` or `~/.bashrc`):
|
||||||
|
|
||||||
|
```
|
||||||
|
PATH=$PATH:$HOME/local/gcc-arm-none-eabi-7-2017-q4-major/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Optional packages
|
||||||
|
|
||||||
|
- Ubuntu / Debian
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo apt-get install \
|
||||||
|
bluez \
|
||||||
|
rfkill
|
||||||
|
```
|
||||||
|
|
||||||
|
- Fedora
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo dnf install \
|
||||||
|
bluez \
|
||||||
|
rfkill
|
||||||
|
```
|
||||||
|
|
||||||
|
- Arch Linux
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo pacman -S \
|
||||||
|
bluez \
|
||||||
|
bluez-utils \
|
||||||
|
rfkill
|
||||||
|
```
|
||||||
|
|
||||||
|
## udev rules
|
||||||
|
|
||||||
|
These rules let you use USB devices like the F3 and the Serial module without root privilege, i.e.
|
||||||
|
`sudo`.
|
||||||
|
|
||||||
|
Create these two files in `/etc/udev/rules.d` with the contents shown below.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cat /etc/udev/rules.d/99-ftdi.rules
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
# FT232 - USB <-> Serial Converter
|
||||||
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="uucp"
|
||||||
|
```
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cat /etc/udev/rules.d/99-openocd.rules
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
# STM32F3DISCOVERY rev A/B - ST-LINK/V2
|
||||||
|
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", GROUP="uucp"
|
||||||
|
|
||||||
|
# STM32F3DISCOVERY rev C+ - ST-LINK/V2-1
|
||||||
|
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", GROUP="uucp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then reload the udev rules with:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo udevadm control --reload-rules
|
||||||
|
```
|
||||||
|
|
||||||
|
If you had any board plugged to your laptop, unplug them and then plug them in again.
|
||||||
|
|
||||||
|
Finally, check if you are in the `uucp` group.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ groups $(id -nu)
|
||||||
|
(..) uucp (..)
|
||||||
|
$ # ^^^^
|
||||||
|
```
|
||||||
|
|
||||||
|
(`$(id -nu)` returns your user name. In my case it's `japaric`.)
|
||||||
|
|
||||||
|
If `uucp` appears in the output. You are all set! Go to the [next section]. Otherwise, keep reading:
|
||||||
|
|
||||||
|
[next section]: 03-setup/verify.html
|
||||||
|
|
||||||
|
- Add yourself to the `uucp` group.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo usermod -a -G uucp $(id -u -n)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Check again the output of `groups`. `uucp` should be there this time!
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ groups $(id -nu)
|
||||||
|
(..) uucp (..)
|
||||||
|
$ # ^^^^
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll have to re-log for these changes to take effect. You have two options:
|
||||||
|
|
||||||
|
You can reboot or log out from your current session and then log in; this will close all the
|
||||||
|
programs you have open right now.
|
||||||
|
|
||||||
|
The other option is to use the command below:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ su - $(id -nu)
|
||||||
|
```
|
||||||
|
|
||||||
|
to re-log *only in the current shell* and get access to `uucp` devices *only on that shell*. Other
|
||||||
|
shells *won't* have access to `uucp` devices unless you manually re-log on them with the same `su`
|
||||||
|
command.
|
||||||
|
|
||||||
|
Now, go to the [next section].
|
||||||
17
src/setup/MACOS.md
Normal file
17
src/setup/MACOS.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# macOS
|
||||||
|
|
||||||
|
All the tools can be install using [Homebrew]:
|
||||||
|
|
||||||
|
[Homebrew]: http://brew.sh/
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ brew cask install gcc-arm-embedded
|
||||||
|
$ brew install minicom openocd
|
||||||
|
```
|
||||||
|
|
||||||
|
If the `brew cask` command doesn't work (`Error: Unknown command: cask`), then run `brew tap
|
||||||
|
Caskroom/tap` first and try again.
|
||||||
|
|
||||||
|
That's all! Go to the [next section].
|
||||||
|
|
||||||
|
[next section]: 03-setup/verify.html
|
||||||
66
src/setup/README.md
Normal file
66
src/setup/README.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# Development environment setup
|
||||||
|
|
||||||
|
Dealing with microcontrollers involves several tools as we'll be dealing with an architecture
|
||||||
|
different than your laptop's and we'll have to run and debug programs on a "remote" device.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Without documentation it is pretty much impossible to work with microcontrollers.
|
||||||
|
|
||||||
|
We'll be referring to the [micro:bit hardware page][microbit] and the links found within.
|
||||||
|
|
||||||
|
[microbit]: http://tech.microbit.org/hardware
|
||||||
|
|
||||||
|
*HEADS UP* Some of the links point to large PDF files several MBs in size.
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
We'll use all the tools listed below. Where a minimum version is not specified, any recent version
|
||||||
|
should work but we have listed the version we have tested.
|
||||||
|
|
||||||
|
- Cargo & `rustc`.
|
||||||
|
|
||||||
|
- OpenOCD. version >=0.8
|
||||||
|
|
||||||
|
- `arm-none-eabi` toolchain. Tested version: gcc 8.1.0, binutils 2.30.
|
||||||
|
|
||||||
|
- `arm-none-eabi-gdb`.
|
||||||
|
|
||||||
|
- `minicom` on Linux and macOS. Tested version: 2.7.
|
||||||
|
Readers report that `picocom` also works but we'll use `minicom` in this book.
|
||||||
|
|
||||||
|
- `PuTTY` on Windows.
|
||||||
|
|
||||||
|
Next, follow OS-agnostic installation instructions for a few of the tools:
|
||||||
|
|
||||||
|
### `rustc` & Cargo
|
||||||
|
|
||||||
|
Install rustup by following the instructions at [https://rustup.rs](https://rustup.rs).
|
||||||
|
|
||||||
|
Then, install or switch to the nightly channel.
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ rustup default nightly
|
||||||
|
```
|
||||||
|
|
||||||
|
**NOTE** Make sure you have a nightly newer than `nightly-2018-06-22`.
|
||||||
|
`rustc -V` should return a date newer than the one shown below:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ rustc -V
|
||||||
|
rustc 1.28.0-nightly (056f589fb 2018-06-22)
|
||||||
|
```
|
||||||
|
|
||||||
|
### `itmdump`
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ cargo install itm
|
||||||
|
```
|
||||||
|
|
||||||
|
### OS specific instructions
|
||||||
|
|
||||||
|
Now follow the instructions specific to the OS you are using:
|
||||||
|
|
||||||
|
- [Linux](setup/linux.html)
|
||||||
|
- [Windows](setup/windows.html)
|
||||||
|
- [macOS](setup/macos.html)
|
||||||
114
src/setup/VERIFY.md
Normal file
114
src/setup/VERIFY.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# Verify the installation
|
||||||
|
|
||||||
|
Let's verify that all the tools were installed correctly.
|
||||||
|
|
||||||
|
## Linux only
|
||||||
|
|
||||||
|
### Verify permissions
|
||||||
|
|
||||||
|
Connect the F3 to your laptop using an USB cable. Be sure to connect the cable to the "USB ST-LINK"
|
||||||
|
port, the USB port in the center of the edge of the board.
|
||||||
|
|
||||||
|
The F3 should now appear as a USB device (file) in `/dev/bus/usb`. Let's find out how it got
|
||||||
|
enumerated:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ lsusb | grep -i stm
|
||||||
|
Bus 003 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2.1
|
||||||
|
$ # ^^^ ^^^
|
||||||
|
```
|
||||||
|
|
||||||
|
In my case, the F3 got connected to the bus #3 and got enumerated as the device #4. This means the
|
||||||
|
file `/dev/bus/usb/003/004` *is* the F3. Let's check its permissions:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ ls -l /dev/bus/usb/003/004
|
||||||
|
crw-rw-r-- 1 root uucp 189, 262 Oct 27 00:00 /dev/bus/usb/003/004
|
||||||
|
```
|
||||||
|
|
||||||
|
The group should be `uucp`. If it's not ... then check your [udev rules] and try re-loading them
|
||||||
|
with:
|
||||||
|
|
||||||
|
[udev rules]: 03-setup/linux.html#udev%20rules
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ sudo udevadm control --reload-rules
|
||||||
|
```
|
||||||
|
|
||||||
|
Now let's repeat the procedure for the Serial module.
|
||||||
|
|
||||||
|
Unplug the F3 and plug the Serial module. Now, figure out what's its associated file:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ lsusb | grep -i ft232
|
||||||
|
Bus 003 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
|
||||||
|
```
|
||||||
|
|
||||||
|
In my case, it's the `/dev/bus/usb/003/005`. Now, check its permissions:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ ls -l /dev/bus/usb/003/005
|
||||||
|
crw-rw-r--+ 1 root uucp 189, 261 Oct 27 00:00 /dev/bus/usb/003/005
|
||||||
|
```
|
||||||
|
|
||||||
|
As before, the group should be `uucp`.
|
||||||
|
|
||||||
|
## All
|
||||||
|
|
||||||
|
### First OpenOCD connection
|
||||||
|
|
||||||
|
First, connect the F3 to your laptop using an USB cable. Connect the cable to the USB port in the
|
||||||
|
center of edge of the board, the one that's labeled "USB ST-LINK".
|
||||||
|
|
||||||
|
Two *red* LEDs should turn on right after connecting the USB cable to the board.
|
||||||
|
|
||||||
|
Next, run this command:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ # *nix
|
||||||
|
$ openocd -f interface/stlink-v2-1.cfg -f target/stm32f3x.cfg
|
||||||
|
|
||||||
|
$ # Windows
|
||||||
|
$ # NOTE cygwin users have reported problems with the -s flag. If you run into
|
||||||
|
$ # that you can call openocd from the `C:\OpenOCD\share\scripts` directory
|
||||||
|
$ openocd -s C:\OpenOCD\share\scripts -f interface/stlink-v2-1.cfg -f target/stm32f3x.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
> **NOTE** Windows users: `C:\OpenOCD` is the directory where you installed OpenOCD to.
|
||||||
|
|
||||||
|
> **IMPORTANT** There is more than one hardware revision of the STM32F3DISCOVERY board. For older
|
||||||
|
> revisions, you'll need to change the "interface" argument to `-f interface/stlink-v2.cfg` (note:
|
||||||
|
> no `-1` at the end). Alternatively, older revisions can use `-f board/stm32f3discovery.cfg`
|
||||||
|
> instead of `-f interface/stlink-v2-1.cfg -f target/stm32f3x.cfg`.
|
||||||
|
|
||||||
|
You should see output like this:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
Open On-Chip Debugger 0.10.0
|
||||||
|
Licensed under GNU GPL v2
|
||||||
|
For bug reports, read
|
||||||
|
http://openocd.org/doc/doxygen/bugs.html
|
||||||
|
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
|
||||||
|
adapter speed: 1000 kHz
|
||||||
|
adapter_nsrst_delay: 100
|
||||||
|
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
|
||||||
|
none separate
|
||||||
|
Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||||||
|
Info : clock speed 950 kHz
|
||||||
|
Info : STLINK v2 JTAG v27 API v2 SWIM v15 VID 0x0483 PID 0x374B
|
||||||
|
Info : using stlink api v2
|
||||||
|
Info : Target voltage: 2.915608
|
||||||
|
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
|
||||||
|
```
|
||||||
|
|
||||||
|
(If you don't ... then check the [general troubleshooting] instructions.)
|
||||||
|
|
||||||
|
[general troubleshooting]: appendix/1-general-troubleshooting/README.html
|
||||||
|
|
||||||
|
`openocd` will block the terminal. That's fine.
|
||||||
|
|
||||||
|
Also, one of the red LEDs, the one closest to the USB port, should start oscillating between red
|
||||||
|
light and green light.
|
||||||
|
|
||||||
|
That's it! It works. You can now close/kill `openocd`.
|
||||||
50
src/setup/WINDOWS.md
Normal file
50
src/setup/WINDOWS.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Windows
|
||||||
|
|
||||||
|
## `arm-none-eabi-*`
|
||||||
|
|
||||||
|
ARM provides `.exe` installers for Windows. Grab one from [here][gcc], and follow the instructions.
|
||||||
|
Just before the installation process finishes tick/select the "Add path to environment variable"
|
||||||
|
option. Then verify that the tools are in your `%PATH%`:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ arm-none-eabi-gcc -v
|
||||||
|
(..)
|
||||||
|
gcc version 5.4.1 20160919 (release) (..)
|
||||||
|
```
|
||||||
|
|
||||||
|
[gcc]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
|
||||||
|
|
||||||
|
## OpenOCD
|
||||||
|
|
||||||
|
There's no official binary release of OpenOCD for Windows but there are unofficial releases
|
||||||
|
available [here][openocd]. Grab the 0.10.x zipfile and extract it somewhere in your drive (I
|
||||||
|
recommend `C:\OpenOCD` but with the drive letter that makes sense to you) then update your `%PATH%`
|
||||||
|
environment variable to include the following path: `C:\OpenOCD\bin` (or the path that you used
|
||||||
|
before).
|
||||||
|
|
||||||
|
[openocd]: https://github.com/gnu-mcu-eclipse/openocd/releases
|
||||||
|
|
||||||
|
Verify that OpenOCD is in yout `%PATH%` with:
|
||||||
|
|
||||||
|
``` console
|
||||||
|
$ openocd -v
|
||||||
|
Open On-Chip Debugger 0.10.0
|
||||||
|
(..)
|
||||||
|
```
|
||||||
|
|
||||||
|
## PuTTY
|
||||||
|
|
||||||
|
Download the latest `putty.exe` from [this site] and place it somewhere in your `%PATH%`.
|
||||||
|
|
||||||
|
[this site]: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
|
||||||
|
|
||||||
|
## ST-LINK USB driver
|
||||||
|
|
||||||
|
You'll also need to install [this USB driver] or OpenOCD won't work. Follow the installer
|
||||||
|
instructions and make sure you install the right (32-bit or 64-bit) version of the driver.
|
||||||
|
|
||||||
|
[this USB driver]: http://www.st.com/en/embedded-software/stsw-link009.html
|
||||||
|
|
||||||
|
That's all! Go to the [next section].
|
||||||
|
|
||||||
|
[next section]: 03-setup/verify.html
|
||||||
Reference in New Issue
Block a user