Skip to content

Commit 2c7e145

Browse files
Merge pull request #276 from rust-embedded/tests-build
Add tests for new build methods in `riscv-rt`
2 parents b5832b6 + 3d3ea5a commit 2c7e145

38 files changed

+246
-6
lines changed

.github/workflows/tests.yaml

+54-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ on:
44
pull_request:
55
merge_group:
66

7-
name: Run macro tests (tests)
7+
name: Run tests (build and trybuild)
88

99
jobs:
10-
run-tests:
10+
run-trybuild:
1111
strategy:
1212
matrix:
1313
os: [ macos-latest, ubuntu-latest ] # windows shows weird linking errors
@@ -16,12 +16,62 @@ jobs:
1616
- uses: actions/checkout@v4
1717
- uses: dtolnay/rust-toolchain@stable
1818
- name: Run tests
19-
run: cargo test --package tests
19+
run: cargo test --package tests-trybuild
20+
run-build:
21+
strategy:
22+
matrix:
23+
# All generated code should be running on stable now, MRSV is 1.61.0
24+
toolchain: [ stable, nightly, 1.61.0 ]
25+
target:
26+
- riscv32i-unknown-none-elf
27+
- riscv32im-unknown-none-elf
28+
- riscv32imc-unknown-none-elf
29+
- riscv32imac-unknown-none-elf
30+
- riscv32imafc-unknown-none-elf
31+
- riscv64imac-unknown-none-elf
32+
- riscv64gc-unknown-none-elf
33+
example:
34+
- empty
35+
include:
36+
# Nightly is only for reference and allowed to fail
37+
- toolchain: nightly
38+
experimental: true
39+
exclude:
40+
- toolchain: 1.61.0
41+
target: riscv32im-unknown-none-elf
42+
- toolchain: 1.61.0
43+
target: riscv32imafc-unknown-none-elf
44+
runs-on: ubuntu-latest
45+
continue-on-error: ${{ matrix.experimental || false }}
46+
steps:
47+
- uses: actions/checkout@v4
48+
- uses: dtolnay/rust-toolchain@master
49+
with:
50+
toolchain: ${{ matrix.toolchain }}
51+
targets: ${{ matrix.target }}
52+
- name: Build (no features)
53+
run: RUSTFLAGS="-C link-arg=-Tdevice.x -C link-arg=-Tmemory.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }}
54+
- name: Build (include device.x)
55+
run: RUSTFLAGS="-C link-arg=-Tmemory.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features device
56+
- name: Build (include memory.x)
57+
run: RUSTFLAGS="-C link-arg=-Tdevice.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features memory
58+
- name: Build (include device.x and memory.x)
59+
run: RUSTFLAGS="-C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features device,memory
60+
61+
- name: Build (custom interrupts and exceptions)
62+
run: RUSTFLAGS="-C link-arg=-Tdevice.x -C link-arg=-Tmemory.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features no-interrupts,no-exceptions
63+
- name: Build (custom interrupts and exceptions, include device.x)
64+
run: RUSTFLAGS="-C link-arg=-Tmemory.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features no-interrupts,no-exceptions,device
65+
- name: Build (custom interrupts and exceptions, include memory.x)
66+
run: RUSTFLAGS="-C link-arg=-Tdevice.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features no-interrupts,no-exceptions,memory
67+
- name: Build (custom interrupts and exceptions, include device.x and memory.x)
68+
run: RUSTFLAGS="-C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features no-interrupts,no-exceptions,device,memory
2069

2170
# Job to check that all the builds succeeded
2271
tests-check:
2372
needs:
24-
- run-tests
73+
- run-trybuild
74+
- run-build
2575
runs-on: ubuntu-latest
2676
if: always()
2777
steps:

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ members = [
77
"riscv-rt",
88
"riscv-semihosting",
99
"riscv-target-parser",
10-
"tests",
10+
"tests-build",
11+
"tests-trybuild",
1112
]

tests-build/Cargo.toml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "tests-build"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
panic-halt = "1.0"
8+
riscv = { path = "../riscv", version = "0.13.0" }
9+
riscv-rt = { path = "../riscv-rt", version = "0.14.0" }
10+
11+
[features]
12+
single-hart = ["riscv-rt/single-hart"]
13+
v-trap = ["riscv-rt/v-trap"]
14+
device = ["riscv-rt/device"]
15+
memory = ["riscv-rt/memory"]
16+
no-exceptions = ["riscv-rt/no-exceptions"]
17+
no-interrupts = ["riscv-rt/no-interrupts"]

tests-build/build.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::{env, fs::File, io::Write, path::PathBuf};
2+
3+
fn main() {
4+
// Put device.x somewhere the linker can find it
5+
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
6+
File::create(out.join("device.x"))
7+
.unwrap()
8+
.write_all(include_bytes!("device.x"))
9+
.unwrap();
10+
println!("cargo:rustc-link-search={}", out.display());
11+
println!("cargo:rerun-if-changed=device.x");
12+
13+
// Put memory.x somewhere the linker can find it
14+
File::create(out.join("memory.x"))
15+
.unwrap()
16+
.write_all(include_bytes!("memory.x"))
17+
.unwrap();
18+
println!("cargo:rustc-link-search={}", out.display());
19+
println!("cargo:rerun-if-changed=memory.x");
20+
21+
println!("cargo:rerun-if-changed=build.rs");
22+
}

tests-build/device.x

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* Core interrupt sources and trap handlers */
2+
PROVIDE(MachineSoft = DefaultHandler);
3+
PROVIDE(MachineTimer = DefaultHandler);
4+
PROVIDE(MachineExternal = DefaultHandler);
5+
PROVIDE(_start_MachineSoft_trap = _start_DefaultHandler_trap);
6+
PROVIDE(_start_MachineTimer_trap = _start_DefaultHandler_trap);
7+
PROVIDE(_start_MachineExternal_trap = _start_DefaultHandler_trap);
8+
9+
/* External interrupt sources */
10+
PROVIDE(Gpio = DefaultHandler);
11+
PROVIDE(Uart = DefaultHandler);
12+
PROVIDE(I2c = DefaultHandler);
13+
14+
/* Exception sources */
15+
PROVIDE(InstructionMisaligned = ExceptionHandler);
16+
PROVIDE(InstructionFault = ExceptionHandler);
17+
PROVIDE(IllegalInstruction = ExceptionHandler);
18+
PROVIDE(Breakpoint = ExceptionHandler);
19+
PROVIDE(LoadMisaligned = ExceptionHandler);
20+
PROVIDE(LoadFault = ExceptionHandler);
21+
PROVIDE(StoreMisaligned = ExceptionHandler);
22+
PROVIDE(StoreFault = ExceptionHandler);
23+
PROVIDE(MachineEnvCall = ExceptionHandler);
24+
PROVIDE(InstructionPageFault = ExceptionHandler);
25+
PROVIDE(LoadPageFault = ExceptionHandler);
26+
PROVIDE(StorePageFault = ExceptionHandler);

tests-build/examples/empty.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
extern crate panic_halt;
5+
6+
use riscv_rt::{core_interrupt, entry, exception, external_interrupt};
7+
use tests_build::{CoreInterrupt, Exception, ExternalInterrupt};
8+
9+
/* EXAMPLES OF USING THE core_interrupt MACRO FOR CORE INTERRUPT HANDLERS.
10+
IF v-trap ENABLED, THE MACRO ALSO DEFINES _start_COREINTERRUPT_trap routines */
11+
12+
/// Handler with the simplest signature.
13+
#[core_interrupt(CoreInterrupt::MachineSoft)]
14+
fn supervisor_soft() {
15+
// do something here
16+
loop {}
17+
}
18+
19+
/// Handler with the most complete signature.
20+
#[core_interrupt(CoreInterrupt::MachineTimer)]
21+
unsafe fn supervisor_timer() -> ! {
22+
// do something here
23+
loop {}
24+
}
25+
26+
/* EXAMPLES OF USING THE external_interrupt MACRO FOR EXTERNAL INTERRUPT HANDLERS. */
27+
28+
/// Handler with the simplest signature.
29+
#[external_interrupt(ExternalInterrupt::Gpio)]
30+
fn external_gpio() {
31+
// do something here
32+
loop {}
33+
}
34+
35+
/// Handler with the most complete signature.
36+
#[external_interrupt(ExternalInterrupt::Uart)]
37+
unsafe fn external_uart() -> ! {
38+
// do something here
39+
loop {}
40+
}
41+
42+
/* EXAMPLES OF USING THE exception MACRO FOR EXCEPTION HANDLERS. */
43+
44+
/// Handler with the simplest signature.
45+
#[exception(Exception::InstructionMisaligned)]
46+
fn instruction_misaligned() {
47+
// do something here
48+
loop {}
49+
}
50+
51+
/// Handler with the most complete signature.
52+
#[exception(Exception::IllegalInstruction)]
53+
unsafe fn illegal_instruction(_trap: &riscv_rt::TrapFrame) -> ! {
54+
// do something here
55+
loop {}
56+
}
57+
58+
// The reference to TrapFrame can be mutable if the handler needs to modify it.
59+
#[exception(Exception::Breakpoint)]
60+
unsafe fn breakpoint(_trap: &mut riscv_rt::TrapFrame) -> ! {
61+
// do something here
62+
loop {}
63+
}
64+
65+
#[entry]
66+
fn main() -> ! {
67+
// do something here
68+
loop {}
69+
}

tests-build/memory.x

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
MEMORY
2+
{
3+
RAM : ORIGIN = 0x80000000, LENGTH = 16K
4+
FLASH : ORIGIN = 0x20000000, LENGTH = 4M
5+
}
6+
7+
REGION_ALIAS("REGION_TEXT", FLASH);
8+
REGION_ALIAS("REGION_RODATA", FLASH);
9+
REGION_ALIAS("REGION_DATA", RAM);
10+
REGION_ALIAS("REGION_BSS", RAM);
11+
REGION_ALIAS("REGION_HEAP", RAM);
12+
REGION_ALIAS("REGION_STACK", RAM);

tests-build/src/lib.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
5+
#[riscv::pac_enum(unsafe ExternalInterruptNumber)]
6+
pub enum ExternalInterrupt {
7+
Gpio = 0,
8+
Uart = 1,
9+
I2c = 2,
10+
}
11+
12+
#[cfg(not(feature = "no-interrupts"))]
13+
pub use riscv::interrupt::Interrupt as CoreInterrupt;
14+
15+
#[cfg(feature = "no-interrupts")]
16+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
17+
#[riscv::pac_enum(unsafe CoreInterruptNumber)]
18+
pub enum CoreInterrupt {
19+
MachineSoft = 3,
20+
MachineTimer = 7,
21+
MachineExternal = 11,
22+
}
23+
24+
#[cfg(not(feature = "no-exceptions"))]
25+
pub use riscv::interrupt::Exception;
26+
27+
#[cfg(feature = "no-exceptions")]
28+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
29+
#[riscv::pac_enum(unsafe ExceptionNumber)]
30+
pub enum Exception {
31+
InstructionMisaligned = 0,
32+
InstructionFault = 1,
33+
IllegalInstruction = 2,
34+
Breakpoint = 3,
35+
LoadMisaligned = 4,
36+
LoadFault = 5,
37+
StoreMisaligned = 6,
38+
StoreFault = 7,
39+
MachineEnvCall = 11,
40+
InstructionPageFault = 12,
41+
LoadPageFault = 13,
42+
StorePageFault = 15,
43+
}

tests/Cargo.toml renamed to tests-trybuild/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "tests"
2+
name = "tests-trybuild"
33
version = "0.1.0"
44
edition = "2021"
55

File renamed without changes.

0 commit comments

Comments
 (0)