Skip to content

Commit fd9a24f

Browse files
committed
Automate the build system with a build.rs
This replaces the AoT processing we did to generate the Rust modules locally. It generates them on the fly at build-time, and only for the selected MCU. The process is mostly the same, just automated. Some things became unnecessary though, such as the `modrs.patch`. `form` is no longer run, in order to minimize the number of files and directories, but rustfmt is, so that the user can read the source from generated documentation pages. The patches were updated to not have the `_svd` key, since that's now handled by the build script. Those that ended up empty were removed.
1 parent 9a99870 commit fd9a24f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+372
-264
lines changed

.gitignore

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
11
/target/
2-
/macros/target/
32
**/*.rs.bk
43
Cargo.lock
5-
6-
svd/
7-
.deps/
8-
src/devices/*/*
9-
src/generic.rs
10-
__pycache__/

Cargo.toml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ keywords = ["avr", "arduino"]
1212
categories = ["no-std", "embedded", "hardware-support"]
1313

1414
include = [
15-
"/src/**/*.rs",
1615
"/LICENSE-*",
1716
"/README.md",
1817
"/build.rs",
18+
"/patch/**/*.yaml",
19+
"/src/**/*.rs",
20+
"/vendor/*.atdf",
21+
"/vendor/LICENSE",
1922
]
2023

2124
[package.metadata.docs.rs]
@@ -64,8 +67,9 @@ attiny88 = ["device-selected"]
6467
attiny1614 = ["device-selected"]
6568
avr64du32 = ["device-selected"]
6669
avr64du28 = ["device-selected"]
67-
rt = ["avr-device-macros"]
70+
rt = ["avr-device-macros", "critical-section"]
6871

72+
critical-section = ["critical-section-impl"]
6973
critical-section-impl = ["critical-section/restore-state-u8"]
7074

7175
# Unfortunately, we can only build documentation for a single MCU.
@@ -83,10 +87,19 @@ path = "macros/"
8387
version = "=0.5.4"
8488
optional = true
8589

90+
[build-dependencies]
91+
svd2rust = "0.33.2"
92+
svdtools = "0.3.14"
93+
atdf2svd = "0.4.0"
94+
8695
[dev-dependencies]
8796
nb = "0.1.2"
8897
embedded-hal = "0.2.3"
8998

99+
[lib]
100+
test = false
101+
bench = false
102+
90103
[[example]]
91104
name = "atmega328p"
92105
path = "examples/atmega328p/src/main.rs"

Makefile

Lines changed: 0 additions & 73 deletions
This file was deleted.

README.md

Lines changed: 70 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ Add the following to `Cargo.toml`:
77
```toml
88
[dependencies.avr-device]
99
version = "0.5.4"
10-
features = ["atmega32u4"]
10+
features = ["atmega32u4", "rt"]
1111
```
1212

13-
Via the feature you can select which chip you want the register specifications for. The following list is what is currently supported:
13+
Via the features you can select which chip you want the register specifications
14+
for. The following list is what is currently supported:
1415

1516
| ATmega | ATmega USB | ATmega 0,1 Series | AT90 | ATtiny |
1617
| :-------------: | :----------: | :---------------: | :-----------: | :-----------: |
@@ -32,63 +33,80 @@ Via the feature you can select which chip you want the register specifications f
3233
| `atmega2560` | | | | `attiny2313` |
3334
| `atmega164pa` | | | | `attiny2313a` |
3435

35-
## Build Instructions
36-
The version on `crates.io` is pre-built. The following is only necessary when trying to build this crate from source.
37-
38-
You need to have [atdf2svd][] (= 0.4.0), [svd2rust][] (= 0.28), [form][] (>= 0.8), [rustfmt][](for the *nightly* toolchain) and [svdtools][] (>= 0.1.9) installed:
39-
```bash
40-
cargo install atdf2svd --version 0.4.0
41-
cargo install svd2rust --version 0.28.0
42-
cargo install form
43-
rustup component add --toolchain nightly rustfmt
44-
pip3 install --user svdtools
45-
46-
# check svdtools
47-
svd --version
48-
# if a "command not found" error is printed instead of a version,
49-
# either svdtools is installed incorrectly, or its installation path is missing from the PATH variable.
50-
# Temporary solution to PATH variable issue is to manually add the path. Like so:
51-
export PATH=$PATH:~/.local/bin
52-
```
53-
54-
[atdf2svd]: https://github.com/Rahix/atdf2svd
55-
[svd2rust]: https://github.com/rust-embedded/svd2rust
56-
[form]: https://github.com/djmcgill/form
57-
[rustfmt]: https://github.com/rust-lang/rustfmt
58-
[svdtools]: https://github.com/rust-embedded/svdtools
59-
60-
Next, clone this repo and build the device definitions:
61-
```bash
62-
git clone https://github.com/Rahix/avr-device
63-
cd avr-device
64-
make
65-
# You can build for just one specific chip using
66-
# make atmega32u4
67-
# I suggest building documentation as well
68-
cargo +nightly doc --features <chip> --open
69-
```
36+
The `rt` feature, while optional, provides some minimal
37+
startup/interrupt-handling code most projects will benefit from. It also enables
38+
the `critical-section` feature, without which all peripheral access is
39+
considered `unsafe` and the API becomes more limited.
7040

71-
## Internals
72-
*avr-device* is generated using [`atdf2svd`](https://github.com/Rahix/atdf2svd) and [`svd2rust`](https://github.com/rust-embedded/svd2rust). The vendor-provided *atdf* files can be found in `vendor/`. The intermediate svd files are patched by `svdpatch.py` (Adapted from [`svdpatch.py`](https://github.com/stm32-rs/stm32-rs/blob/master/scripts/svdpatch.py) in [stm32-rs](https://github.com/stm32-rs/stm32-rs)) with device-dependent patches in `patch/`, mainly to improve undescriptive names and missing descriptions.
41+
## Build Instructions
42+
The PACs (Peripheral Access Crates, or really modules, in our case) **are not**
43+
checked into git. Rather, we generate them at build time, via an automated
44+
process implemented in [`build.rs`](./build.rs). It takes the ATDF files
45+
Microchip (former Atmel) provides plus some patches of our own making as inputs,
46+
and outputs a module generated from those device descriptions. These inputs
47+
**are** checked-in. The process is similar to what the `*bindgen` crates
48+
provide, just has more steps. So, in short, building should be a matter of
49+
selecting the features and running cargo.
7350

7451
### Adding a new Chip
75-
To add a new chip, download the *atdf* from <http://packs.download.atmel.com/> (or [avr-mcu/packs/](https://github.com/avr-rust/avr-mcu/tree/master/packs)) and place it in `vendor/`. Be sure to name it like the Rust module that should be generated. Next, you need to integrate it into the base crate and build system. Follow what was done in commit [290613454fbd ("Add basic support for ATmega64")](https://github.com/Rahix/avr-device/commit/290613454fbdc5e4ac98e53deccaf74dafc88963). Please adhere to the alphabetical sorting that is present so far.
76-
77-
Next, you **must** create a `<chipname>.yaml` in `patch/` which has at least the following content:
78-
```yaml
79-
_svd: ../svd/<chipname>.svd
80-
```
81-
82-
If more patches need to be applied (most likely!), they should be added into this file as well. The patching format is documented in the [`svdtools` README](https://github.com/stm32-rs/svdtools#device-and-peripheral-yaml-format). Ideally, try to reuse the exisiting patches in `patch/common/` or `patch/timer/`.
83-
84-
Finally, try building the crate for your MCU with `make <chipname>`.
52+
To add a new chip:
53+
54+
1. Download the ATDF from <http://packs.download.atmel.com/> and place it in
55+
`vendor/`. Be sure to name it like the Rust module that should be generated.
56+
2. Add a feature of the same name to `Cargo.toml` (it should enable
57+
`device-selected`);
58+
3. Add any needed patches to a yaml file with the same name under the `patch`
59+
directory, ideally by including some of the snippets present in
60+
`patch/common` and `patch/timer`; The format is decribed
61+
[here](https://github.com/rust-embedded/svdtools#device-and-peripheral-yaml-format),
62+
but it should not include the top-level `_svd` key, as that's handled by the
63+
build system; If patching is unneeded (most likely it is!), the file can be
64+
ommited.
65+
4. Include the module into the tree, in [`devices.rs`](./src/devices.rs),
66+
following the format used by other modules in that file;
67+
5. Finally, try building the crate for your MCU with
68+
`cargo build --features <mcu>,rt`.
69+
6. Also check the built documentation for inconsistencies, via
70+
`cargo doc --features <mcu>,rt --open` (it will pop up in your browser).
71+
72+
## Internals
73+
Since the vendor does not provide SVDs we can pass to [`svd2rust`][], we
74+
generate one via [`atdf2svd`][]. The sequence is as follows:
75+
76+
1. Check which MCUs are known to the crate
77+
([build.rs:get_available_mcus](./build.rs#L21-L40));
78+
2. Select which to build for by checking enabled features
79+
([build.rs:select_mcu](./build.rs#L42-L62));
80+
3. Generate the Rust module ([build.rs:build_mcu_module](./build.rs#L64-L148));
81+
82+
Substeps are:
83+
1. Register inputs with cargo;
84+
2. Get a temporary directory;
85+
3. Apply `atdf2svd`;
86+
4. If a yaml patch exists, use it via [`svdtools`][] and read the new content
87+
/ else, read the content of the unpatched file to continue;
88+
5. Get the output directory;
89+
6. Apply `svd2rust`;
90+
7. Run [`rustfmt`][] on the module to make it readable in [`docs.rs`][];
91+
4. It will be included from `$OUT_DIR/pac/<mcu>.rs` into the path
92+
`avr_device::devices::<mcu>` (private), and re-exported as
93+
`avr_device::<mcu>` (public).
94+
95+
[`atdf2svd`]: https://github.com/Rahix/atdf2svd
96+
[`svd2rust`]: https://github.com/rust-embedded/svd2rust
97+
[`svdtools`]: https://github.com/rust-embedded/svdtools
98+
[`rustfmt`]: https://github.com/rust-lang/rustfmt
99+
[`docs.rs`]: https://docs.rs/avr-device/latest/avr_device
85100

86101
## License
87102
*avr-device* is licensed under either of
88103

89-
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
90-
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
104+
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
105+
http://www.apache.org/licenses/LICENSE-2.0)
106+
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
107+
http://opensource.org/licenses/MIT)
91108

92109
at your option.
93110

94-
The vendored *atdf* files are licensed under the Apache License, Version 2.0 ([LICENSE-VENDOR](vendor/LICENSE)).
111+
The vendored *atdf* files are licensed under the Apache License, Version 2.0
112+
([LICENSE-VENDOR](vendor/LICENSE)).

0 commit comments

Comments
 (0)