├── .github ├── Dockerfile.ci └── workflows │ └── docker-image.yml ├── .gitignore ├── Cargo.toml ├── README.md ├── avr-atmega328p.json └── src └── main.rs /.github/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 17 | 18 | WORKDIR /code 19 | 20 | ENV AVR_CPU_FREQUENCY_HZ=16000000 21 | 22 | ENTRYPOINT ["cargo"] 23 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Test suite 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | schedule: 9 | - cron: "0 2 * * 1-5" 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Prepare the Rust build environment 18 | run: 19 | docker build . --file .github/Dockerfile.ci --tag rust-avr-ci:$GITHUB_RUN_NUMBER 20 | 21 | - name: Compile the crate for the AVR atmega328p 22 | run: 23 | docker run rust-avr-ci:$GITHUB_RUN_NUMBER build -Z build-std=core --target avr-atmega328p.json --release --all --bins --examples 24 | 25 | - name: Compile the crate for the host machine and and run tests 26 | run: 27 | docker run rust-avr-ci:$GITHUB_RUN_NUMBER test --all 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "template-bin" 3 | version = "0.1.0" 4 | authors = ["Your Name "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | avr-std-stub = "1.0" 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust AVR executable template 2 | 3 | A template for Rust based AVR executables. 4 | 5 | **NOTE**: This software template repository is offered in the public domain. It is free to use, adapt, modify, distribute, with no restrictions and no crediting required. 6 | 7 | Provides: 8 | 9 | * A Rust target specification JSON for ATmega328P - [`avr-atmega328p.json`](./avr-atmega328p.json) 10 | * A GitHub-action based CI test pipeline 11 | 12 | ## Build instructions 13 | 14 | Install Rust nightly. 15 | 16 | Then run: 17 | 18 | ``` 19 | cargo build --target avr-atmega328p.json -Z build-std=core --release 20 | ``` 21 | 22 | The final ELF executable file will then be available at `target/avr-atmega328p/release/template-bin.elf`. 23 | 24 | -------------------------------------------------------------------------------- /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 | "no-compiler-rt": true, 12 | "os": "unknown", 13 | "position-independent-executables": false, 14 | "exe-suffix": ".elf", 15 | "eh-frame-header": false, 16 | "pre-link-args": { 17 | "gcc": [ 18 | "-Os", 19 | "-mmcu=atmega328p" 20 | ] 21 | }, 22 | "late-link-args": { 23 | "gcc": [ 24 | "-lc", 25 | "-lgcc" 26 | ] 27 | }, 28 | "target-c-int-width": "16", 29 | "target-endian": "little", 30 | "target-pointer-width": "16", 31 | "vendor": "unknown" 32 | } 33 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![cfg_attr(not(test), no_main)] // #![no_main] interfers with 'cargo test' when targeting the host machine. 3 | 4 | extern crate avr_std_stub; 5 | 6 | #[no_mangle] 7 | #[cfg(not(test))] // The main function interfers with 'cargo test' when targeting the host machine. 8 | fn main() { 9 | } 10 | 11 | #[cfg(test)] 12 | mod test { 13 | #[test] 14 | fn test_foo() { 15 | assert_eq!(1, 1); 16 | } 17 | } 18 | --------------------------------------------------------------------------------