├── .cargo └── config.toml ├── .dockerignore ├── .github └── workflows │ └── docker-image.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Dockerfile.ci ├── LICENSE ├── README.md ├── avr-atmega328p.json ├── rust-toolchain.toml └── src └── main.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "avr-atmega328p.json" 3 | 4 | [unstable] 5 | build-std = ["core"] 6 | 7 | # Cargo versions before 2021-02-23 won't recognize this: https://github.com/rust-lang/cargo/pull/9175 8 | [env] 9 | AVR_CPU_FREQUENCY_HZ = "16_000_000" 10 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Dockerfile 3 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Test suite 2 | 3 | 4 | on: 5 | push: 6 | branches: [ master ] 7 | pull_request: 8 | branches: [ master ] 9 | schedule: 10 | - cron: "0 2 * * 1-5" 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Prepare the AVR Rust build environment 19 | run: 20 | docker build . --file Dockerfile.ci --tag avr-rust/blink.ci:$GITHUB_RUN_NUMBER 21 | 22 | - name: Compile the crate 23 | run: 24 | docker run avr-rust/blink.ci:$GITHUB_RUN_NUMBER 25 | 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "avr-config" 7 | version = "2.0.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "abb2276df19ea0f25741658d218861b8a24d78eaf926127eb2384f0927f9ab9f" 10 | dependencies = [ 11 | "const_env--value", 12 | ] 13 | 14 | [[package]] 15 | name = "avr-mcu" 16 | version = "0.3.5" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "029b6df2c7d547a07eca1e2302ef423a0e1be7a61cae020c91eadf06ca354a7a" 19 | dependencies = [ 20 | "json", 21 | "lazy_static", 22 | "target-cpu-fetch", 23 | "xmltree", 24 | ] 25 | 26 | [[package]] 27 | name = "avr-std-stub" 28 | version = "1.0.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "839920177137ff472f3c35abf5b8166f331c6cf7f2dfa7ffd69f9aa7dc70b526" 31 | 32 | [[package]] 33 | name = "avr_delay" 34 | version = "0.4.0" 35 | source = "git+https://github.com/avr-rust/delay#cfe9848f82b3c3e479cb5dc7a30e24152468030a" 36 | dependencies = [ 37 | "avr-config", 38 | ] 39 | 40 | [[package]] 41 | name = "blink" 42 | version = "0.1.0" 43 | dependencies = [ 44 | "ruduino", 45 | ] 46 | 47 | [[package]] 48 | name = "const_env--value" 49 | version = "0.1.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "1ade503a5095050a5bf3feb8ae71842fb49dfc4af01dd613beb4f00bb7144645" 52 | dependencies = [ 53 | "const_env_impl--value", 54 | ] 55 | 56 | [[package]] 57 | name = "const_env_impl--value" 58 | version = "0.1.2" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "a046e06596453266c54d3eb790813fd047494fc1d04d5077fba628bf84e1b83a" 61 | dependencies = [ 62 | "proc-macro2", 63 | "quote", 64 | "syn", 65 | ] 66 | 67 | [[package]] 68 | name = "json" 69 | version = "0.12.4" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" 72 | 73 | [[package]] 74 | name = "lazy_static" 75 | version = "1.4.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 78 | 79 | [[package]] 80 | name = "proc-macro2" 81 | version = "1.0.39" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" 84 | dependencies = [ 85 | "unicode-ident", 86 | ] 87 | 88 | [[package]] 89 | name = "quote" 90 | version = "1.0.18" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 93 | dependencies = [ 94 | "proc-macro2", 95 | ] 96 | 97 | [[package]] 98 | name = "ruduino" 99 | version = "0.4.0" 100 | source = "git+https://github.com/avr-rust/ruduino?branch=master#a33d38a7554f2c362fcfb54044d204c19fd9ac1a" 101 | dependencies = [ 102 | "avr-config", 103 | "avr-mcu", 104 | "avr-std-stub", 105 | "avr_delay", 106 | "const_env--value", 107 | "target-cpu-macro", 108 | ] 109 | 110 | [[package]] 111 | name = "syn" 112 | version = "1.0.96" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" 115 | dependencies = [ 116 | "proc-macro2", 117 | "quote", 118 | "unicode-ident", 119 | ] 120 | 121 | [[package]] 122 | name = "target-cpu-fetch" 123 | version = "0.1.3" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "c620c949188981ea1071b1a280e1cfd7e4ca1394083a4a5b878714a351231031" 126 | dependencies = [ 127 | "json", 128 | ] 129 | 130 | [[package]] 131 | name = "target-cpu-macro" 132 | version = "0.1.3" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "d6a3fb73cc55bfda6bf277c6c84b03993c41f5068e0d53b74116a9aa9697760b" 135 | dependencies = [ 136 | "json", 137 | "target-cpu-fetch", 138 | ] 139 | 140 | [[package]] 141 | name = "unicode-ident" 142 | version = "1.0.0" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" 145 | 146 | [[package]] 147 | name = "xml-rs" 148 | version = "0.8.4" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" 151 | 152 | [[package]] 153 | name = "xmltree" 154 | version = "0.10.3" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" 157 | dependencies = [ 158 | "xml-rs", 159 | ] 160 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink" 3 | version = "0.1.0" 4 | authors = ["Dylan McKay "] 5 | edition = '2018' 6 | 7 | [dependencies] 8 | ruduino = { git = "https://github.com/avr-rust/ruduino", branch = "master" } 9 | 10 | [profile.release] 11 | opt-level = 'z' 12 | lto = true 13 | strip = true 14 | -------------------------------------------------------------------------------- /Dockerfile.ci: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN useradd -m avr-rust 4 | 5 | # Install dependencies 6 | RUN apt-get update -y && apt-get install -y wget gcc binutils gcc-avr avr-libc 7 | 8 | RUN mkdir -p /code && chown avr-rust:avr-rust /code 9 | 10 | USER avr-rust 11 | 12 | # Install Rustup along with nightly 13 | RUN wget -q https://sh.rustup.rs -O /tmp/rustup.sh && sh /tmp/rustup.sh -y --profile minimal --default-toolchain nightly -c rust-src --quiet 14 | ENV PATH=/home/avr-rust/.cargo/bin:$PATH 15 | 16 | COPY --chown=avr-rust:avr-rust . /code/blink 17 | 18 | WORKDIR /code/blink 19 | ENV AVR_CPU_FREQUENCY_HZ=16000000 20 | 21 | CMD ["cargo", "build", "-Z", "build-std=core", "--target", "avr-atmega328p.json", "--release"] 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2017 AVR-Rust contributors 3 | 4 | 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: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | 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. 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blink 2 | 3 | A small Hello World Rust application for the AVR. 4 | 5 | The program itself toggles a LED on PORTB periodically. 6 | 7 | Designed for the ATmega328p. 8 | 9 | [The AVR-Rust Book](https://book.avr-rust.org/) 10 | 11 | ## Prerequisites 12 | 13 | * A recent version of the nightly Rust compiler. Anything including or 14 | greater than `rustc 1.63.0-nightly (fee3a459d 2022-06-05)` can be used. 15 | * A recent version of Cargo. At least 1.52.0 or greater. 16 | * The rust-src rustup component - `$ rustup component add rust-src` 17 | * AVR-GCC on the system for linking 18 | * AVR-Libc on the system for support libraries 19 | 20 | ## Usage 21 | 22 | 23 | Now to build, run: 24 | 25 | ```bash 26 | # Ensure time delays are consistent with a 16MHz microcontroller. 27 | export AVR_CPU_FREQUENCY_HZ=16000000 28 | 29 | # Compile the crate to an ELF executable. 30 | cargo build --release 31 | ``` 32 | There should now be an ELF file at `target/avr-atmega328p/release/blink.elf`. It 33 | can be flashed directly to an AVR microcontroller or ran inside a simulator. 34 | 35 | 36 | ## Resources 37 | 38 | * The [AVR-Rust book](https://book.avr-rust.org) 39 | 40 | -------------------------------------------------------------------------------- /avr-atmega328p.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "avr", 3 | "cpu": "atmega328p", 4 | "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8", 5 | "env": "", 6 | "executables": true, 7 | "linker": "avr-gcc", 8 | "linker-flavor": "gcc", 9 | "linker-is-gnu": true, 10 | "llvm-target": "avr-unknown-unknown", 11 | "os": "unknown", 12 | "position-independent-executables": false, 13 | "exe-suffix": ".elf", 14 | "eh-frame-header": false, 15 | "pre-link-args": { 16 | "gcc": ["-mmcu=atmega328p"] 17 | }, 18 | "late-link-args": { 19 | "gcc": ["-lgcc", "-lc"] 20 | }, 21 | "target-c-int-width": "16", 22 | "target-endian": "little", 23 | "target-pointer-width": "16", 24 | "vendor": "unknown" 25 | } 26 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" 3 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | use ruduino::Pin; 5 | use ruduino::cores::current::{port}; 6 | 7 | #[no_mangle] 8 | pub extern fn main() { 9 | port::B5::set_output(); 10 | 11 | loop { 12 | port::B5::set_high(); 13 | 14 | ruduino::delay::delay_ms(1000); 15 | 16 | port::B5::set_low(); 17 | 18 | ruduino::delay::delay_ms(1000); 19 | } 20 | } 21 | --------------------------------------------------------------------------------