Skip to content

Commit f39bfba

Browse files
authored
Merge pull request #109 from us-irs/update-examples
update examples
2 parents 9f13866 + de38e9e commit f39bfba

File tree

8 files changed

+141
-47
lines changed

8 files changed

+141
-47
lines changed

.cargo/config.toml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,25 @@
1-
[target.thumbv7m-none-eabi]
1+
[build]
2+
# Common embedded build targets
3+
target = "thumbv7em-none-eabihf"
4+
# target = "thumbv6m-none-eabi"
5+
6+
[target.thumbv7em-none-eabihf]
27
# used to run the qemu_test.rs example with QEMU
3-
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
4-
rustflags = ["-C", "link-arg=-Tlink.x"]
8+
runner = "./qemu-runner.sh --target thumbv7em-none-eabihf"
9+
rustflags = [
10+
"-Clink-arg=-Tlink.x",
11+
"-Clink-arg=-Tdefmt.x",
12+
# Can be useful for debugging and to inspect where the heap memory is placed/linked.
13+
# "-Clink-args=-Map=app.map"
14+
]
15+
16+
[target.thumbv6m-none-eabi]
17+
# used to run the qemu_test.rs example with QEMU
18+
runner = "./qemu-runner.sh --target thumbv6m-none-eabi"
19+
rustflags = [
20+
"-Clink-arg=-Tlink.x",
21+
"-Clink-arg=-Tdefmt.x",
22+
]
23+
24+
[env]
25+
DEFMT_LOG="info"

.github/workflows/ci.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
matrix:
1717
target:
1818
- thumbv6m-none-eabi
19-
- thumbv7m-none-eabi
19+
- thumbv7em-none-eabihf
2020
toolchain:
2121
- stable
2222
- nightly
@@ -49,15 +49,15 @@ jobs:
4949
- uses: actions/checkout@v4
5050
- uses: dtolnay/rust-toolchain@master
5151
with:
52-
targets: thumbv7m-none-eabi
52+
targets: thumbv7em-none-eabihf
5353
toolchain: nightly
5454
- name: Install QEMU
5555
run: |
5656
sudo apt update
5757
sudo apt install qemu-system-arm
5858
- run: qemu-system-arm --version
59-
- run: cargo run --target thumbv7m-none-eabi --example llff_integration_test --all-features
60-
- run: cargo run --target thumbv7m-none-eabi --example tlsf_integration_test --all-features
59+
- run: cargo +nightly run --target thumbv7em-none-eabihf --example llff_integration_test --all-features
60+
- run: cargo +nightly run --target thumbv7em-none-eabihf --example tlsf_integration_test --all-features
6161

6262
clippy:
6363
name: Clippy
@@ -88,5 +88,8 @@ jobs:
8888
steps:
8989
- uses: actions/checkout@v4
9090
- uses: dtolnay/rust-toolchain@nightly
91+
with:
92+
targets: thumbv7em-none-eabihf
93+
toolchain: nightly
9194
- name: rustdoc
92-
run: cargo rustdoc --all-features
95+
run: cargo +nightly rustdoc --all-features

Cargo.toml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,17 @@ const-default = { version = "1.0.0", default-features = false, optional = true }
4141
[dev-dependencies]
4242
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
4343
cortex-m-rt = "0.7"
44-
cortex-m-semihosting = "0.5"
45-
panic-semihosting = { version = "0.6", features = ["exit"] }
44+
defmt = "1.0"
45+
defmt-semihosting = "0.3.0"
46+
semihosting = { version = "0.1.20", features = ["stdio"] }
47+
48+
# thumbv6m-none-eabi only
49+
[target.thumbv6m-none-eabi.dev-dependencies]
50+
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"] }
51+
52+
# every other target gets the crate without the feature
53+
[target.'cfg(not(target = "thumbv6m-none-eabi"))'.dev-dependencies]
54+
portable-atomic = { version = "1" }
4655

4756
[[example]]
4857
name = "allocator_api"

examples/allocator_api.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
//! This examples requires nightly for the allocator API.
12
#![feature(allocator_api)]
23
#![no_std]
34
#![no_main]
45

56
extern crate alloc;
67

7-
use alloc::vec::Vec;
8-
use core::mem::MaybeUninit;
9-
use core::panic::PanicInfo;
8+
use core::{mem::MaybeUninit, panic::PanicInfo};
9+
use cortex_m as _;
1010
use cortex_m_rt::entry;
11+
use defmt_semihosting as _;
1112
use embedded_alloc::LlffHeap as Heap;
1213

1314
// This is not used, but as of 2023-10-29 allocator_api cannot be used without
@@ -22,14 +23,16 @@ fn main() -> ! {
2223
let heap: Heap = Heap::empty();
2324
unsafe { heap.init(&raw mut HEAP_MEM as usize, HEAP_SIZE) }
2425

25-
let mut xs = Vec::new_in(heap);
26-
xs.push(1);
26+
let mut vec = alloc::vec::Vec::new_in(heap);
27+
vec.push(1);
2728

28-
#[allow(clippy::empty_loop)]
29-
loop { /* .. */ }
29+
defmt::info!("Allocated vector: {:?}", vec.as_slice());
30+
31+
semihosting::process::exit(0);
3032
}
3133

3234
#[panic_handler]
33-
fn panic(_: &PanicInfo) -> ! {
34-
loop {}
35+
fn panic(info: &PanicInfo) -> ! {
36+
defmt::error!("{}", info);
37+
semihosting::process::exit(0);
3538
}

examples/global_alloc.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
extern crate alloc;
55

6-
use alloc::vec::Vec;
7-
use core::panic::PanicInfo;
6+
use cortex_m as _;
87
use cortex_m_rt::entry;
8+
use defmt_semihosting as _;
9+
10+
use core::panic::PanicInfo;
911
// Linked-List First Fit Heap allocator (feature = "llff")
1012
use embedded_alloc::LlffHeap as Heap;
1113
// Two-Level Segregated Fit Heap allocator (feature = "tlsf")
@@ -21,14 +23,19 @@ fn main() -> ! {
2123
embedded_alloc::init!(HEAP, 1024);
2224
}
2325

24-
let mut xs = Vec::new();
25-
xs.push(1);
26+
let vec = alloc::vec![1];
27+
28+
defmt::info!("Allocated vector: {:?}", vec.as_slice());
29+
30+
let string = alloc::string::String::from("Hello, world!");
31+
32+
defmt::info!("Allocated string: {:?}", string.as_str());
2633

27-
#[allow(clippy::empty_loop)]
28-
loop { /* .. */ }
34+
semihosting::process::exit(0);
2935
}
3036

3137
#[panic_handler]
32-
fn panic(_: &PanicInfo) -> ! {
33-
loop {}
38+
fn panic(info: &PanicInfo) -> ! {
39+
defmt::error!("{}", info);
40+
semihosting::process::exit(0);
3441
}

examples/llff_integration_test.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717
#![no_std]
1818

1919
extern crate alloc;
20-
extern crate panic_semihosting;
2120

2221
use alloc::vec::Vec;
23-
use core::mem::{size_of, MaybeUninit};
22+
use core::{
23+
mem::{size_of, MaybeUninit},
24+
panic::PanicInfo,
25+
};
26+
use cortex_m as _;
2427
use cortex_m_rt::entry;
25-
use cortex_m_semihosting::{debug, hprintln};
28+
use defmt_semihosting as _;
2629
use embedded_alloc::LlffHeap as Heap;
2730

2831
#[global_allocator]
@@ -61,26 +64,31 @@ fn test_allocator_api() {
6164
assert_eq!(v.as_slice(), &[0xCAFE, 0xDEAD, 0xFEED]);
6265
}
6366

67+
pub type TestTable<'a> = &'a [(fn() -> (), &'static str)];
68+
6469
#[entry]
6570
fn main() -> ! {
6671
unsafe {
6772
embedded_alloc::init!(HEAP, 1024);
6873
}
6974

70-
#[allow(clippy::type_complexity)]
71-
let tests: &[(fn() -> (), &'static str)] = &[
75+
let tests: TestTable = &[
7276
(test_global_heap, "test_global_heap"),
7377
(test_allocator_api, "test_allocator_api"),
7478
];
7579

7680
for (test_fn, test_name) in tests {
77-
hprintln!("{}: start", test_name);
81+
defmt::info!("{}: start", test_name);
7882
test_fn();
79-
hprintln!("{}: pass", test_name);
83+
defmt::info!("{}: pass", test_name);
8084
}
8185

8286
// exit QEMU with a success status
83-
debug::exit(debug::EXIT_SUCCESS);
84-
#[allow(clippy::empty_loop)]
85-
loop {}
87+
semihosting::process::exit(0);
88+
}
89+
90+
#[panic_handler]
91+
fn panic(info: &PanicInfo) -> ! {
92+
defmt::error!("{}", info);
93+
semihosting::process::exit(-1);
8694
}

examples/tlsf_integration_test.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,20 @@
1717
#![no_std]
1818

1919
extern crate alloc;
20-
extern crate panic_semihosting;
20+
use defmt_semihosting as _;
2121

2222
use alloc::collections::LinkedList;
23-
use core::mem::MaybeUninit;
23+
use core::{mem::MaybeUninit, panic::PanicInfo};
24+
use cortex_m as _;
2425
use cortex_m_rt::entry;
25-
use cortex_m_semihosting::{debug, hprintln};
2626
use embedded_alloc::TlsfHeap as Heap;
2727

2828
#[global_allocator]
2929
static HEAP: Heap = Heap::empty();
3030
const HEAP_SIZE: usize = 30 * 1024;
3131

32+
pub type TestTable<'a> = &'a [(fn() -> (), &'static str)];
33+
3234
fn test_global_heap() {
3335
const ELEMS: usize = 250;
3436

@@ -85,20 +87,23 @@ fn main() -> ! {
8587
embedded_alloc::init!(HEAP, HEAP_SIZE);
8688
}
8789

88-
#[allow(clippy::type_complexity)]
89-
let tests: &[(fn() -> (), &'static str)] = &[
90+
let tests: TestTable = &[
9091
(test_global_heap, "test_global_heap"),
9192
(test_allocator_api, "test_allocator_api"),
9293
];
9394

9495
for (test_fn, test_name) in tests {
95-
hprintln!("{}: start", test_name);
96+
defmt::info!("{}: start", test_name);
9697
test_fn();
97-
hprintln!("{}: pass", test_name);
98+
defmt::info!("{}: pass", test_name);
9899
}
99100

100101
// exit QEMU with a success status
101-
debug::exit(debug::EXIT_SUCCESS);
102-
#[allow(clippy::empty_loop)]
103-
loop {}
102+
semihosting::process::exit(0);
103+
}
104+
105+
#[panic_handler]
106+
fn panic(info: &PanicInfo) -> ! {
107+
defmt::error!("{}", info);
108+
semihosting::process::exit(-1);
104109
}

qemu-runner.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
# This requires you to previously run `cargo install defmt-print`
4+
5+
# See https://ferroussystems.hackmd.io/@jonathanpallant/ryA1S6QDJx for a description of all the relevant QEMU machines
6+
TARGET=""
7+
ELF_BINARY=""
8+
9+
# very small argument parser
10+
while [[ $# -gt 0 ]]; do
11+
case "$1" in
12+
--target) TARGET="$2"; shift 2 ;;
13+
*) ELF_BINARY="$1"; shift ;;
14+
esac
15+
done
16+
17+
# default to the target cargo is currently building for
18+
TARGET="${TARGET:-thumbv7em-none-eabihf}"
19+
20+
case "$TARGET" in
21+
thumbv6m-none-eabi)
22+
MACHINE="-cpu cortex-m3 -machine mps2-an385" ;;
23+
thumbv7em-none-eabihf)
24+
# All suitable for thumbv7em-none-eabihf
25+
MACHINE="-cpu cortex-m4 -machine mps2-an386" ;;
26+
# MACHINE="-cpu cortex-m7 -machine mps2-387" ;;
27+
# MACHINE="-cpu cortex-m7 -machine mps2-500"
28+
*)
29+
echo "Unsupported target: $TARGET" >&2
30+
exit 1 ;;
31+
esac
32+
33+
LOG_FORMAT='{[{L}]%bold} {s} {({ff}:{l:1})%dimmed}'
34+
35+
echo "Running on '$MACHINE'..."
36+
echo "------------------------------------------------------------------------"
37+
qemu-system-arm $MACHINE -semihosting-config enable=on,target=native -nographic -kernel $ELF_BINARY | defmt-print -e $ELF_BINARY --log-format="$LOG_FORMAT"
38+
echo "------------------------------------------------------------------------"

0 commit comments

Comments
 (0)