defmt tests #35

Merged
muellerr merged 1 commits from defmt-tests into main 2026-01-20 22:06:01 +01:00
11 changed files with 196 additions and 24 deletions
+8 -12
View File
@@ -11,9 +11,8 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
targets: "armv7a-none-eabihf"
- run: just check zynq
- run: just check tools
- run: just check zynq7000-boot-image
- run: just check firmware
- run: just check host
build:
name: Check build
@@ -25,9 +24,8 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
targets: "armv7a-none-eabihf"
- run: just build zynq
- run: just build tools
- run: just build zynq7000-boot-image
- run: just check firmware
- run: just check host
fmt:
name: Check formatting
@@ -39,9 +37,8 @@ jobs:
with:
components: rustfmt
targets: "armv7a-none-eabihf"
- run: just fmt zynq
- run: just fmt tools
- run: just fmt zynq7000-boot-image
- run: just check-fmt firmware
- run: just check-fmt host
docs:
name: Check Documentation Build
@@ -65,10 +62,9 @@ jobs:
with:
components: clippy, rust-src
targets: "armv7a-none-eabihf"
- run: just clippy zynq
- run: just clippy firmware
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- run: just clippy tools
- run: just clippy zynq7000-boot-image
- run: just clippy host
+12 -12
View File
@@ -8,35 +8,35 @@ family of SoCs.
This project contains the following crates:
## [Zynq Workspace](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq)
## [Firmware Workspace](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware)
This workspace contains libraries and application which can only be run on the target system.
- The [`zynq7000-rt`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-rt)
- The [`zynq7000-rt`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zynq7000-rt)
run-time crate containing basic low-level startup code necessary to boot a Rust app on the
Zynq7000.
- The [`zynq7000`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000) PAC
- The [`zynq7000`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zynq7000) PAC
crate containing basic low-level register definitions.
- The [`zynq7000-mmu`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-hal)
- The [`zynq7000-mmu`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zynq7000-hal)
crate containing common MMU abstractions used by both the HAL and the run-time crate.
- The [`zynq7000-hal`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-hal)
- The [`zynq7000-hal`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zynq7000-hal)
HAL crate containing higher-level abstractions on top of the PAC register crate.
- The [`zynq7000-embassy`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zynq7000-embassy)
- The [`zynq7000-embassy`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zynq7000-embassy)
crate containing support for running the embassy-rs asynchronous run-time.
This project was developed using a Zedboard, so there are several crates available targeted towards
this board:
- The [`zedboard-bsp`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zedboard-bsp)
- The [`zedboard-bsp`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zedboard-bsp)
crate containing board specific components for the Zedboard.
- The [`zedboard-fsbl`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zedboard-fsbl)
- The [`zedboard-fsbl`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zedboard-fsbl)
contains a simple first-stage bootloader application for the Zedboard.
- The [`zedboard-qspi-flasher`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/zedboard-qspi-flasher)
- The [`zedboard-qspi-flasher`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/zedboard-qspi-flasher)
contains an application which is able to flash a boot binary from DDR to the QSPI.
It also contains the following helper crates:
- The [`examples`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq/examples)
- The [`examples`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/firmware/examples)
folder contains various example applications crates using the HAL and the PAC.
This folder also contains dedicated example applications using the
[`embassy`](https://github.com/embassy-rs/embassy) native Rust RTOS.
@@ -46,10 +46,10 @@ It also contains the following helper crates:
- The [`zedboard-fpga-design`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zedboard-fpga-design)
folder contains a sample FPGA design and block design which was used in some of the provided software examples. The project was created with Vivado version 2024.1.
The folder contains a README with all the steps required to load this project from a TCL script.
- The [`zynq7000-boot-image`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/zynq7000-boot-image)
- The [`zynq7000-boot-image`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/host/zynq7000-boot-image)
library contains generic helpers to interface with the AMD
[boot binary](https://docs.amd.com/r/en-US/ug1283-bootgen-user-guide).
- The [`tools/zynq7000-ps7init-extract`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract)
- The [`tools/zynq7000-ps7init-extract`](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/host/zynq7000-ps7init-extract)
tool allows extracting configuration from the AMD generated `ps7init.tcl` file which contains
static configuration parameters for DDR initialization.
+5
View File
@@ -6,6 +6,8 @@ rustflags = [
"-Ctarget-feature=+vfp3",
"-Ctarget-feature=+neon",
"-Clink-arg=-Tlink.x",
# Breaks builds not using/including defmt..
# "-Clink-arg=-Tdefmt.x",
# If this is not enabled, debugging / stepping can become problematic.
"-Cforce-frame-pointers=yes",
# Can be useful for debugging.
@@ -14,3 +16,6 @@ rustflags = [
[build]
target = "armv7a-none-eabihf"
[env]
DEFMT_LOG = "info"
+1
View File
@@ -10,6 +10,7 @@ members = [
"examples/simple",
"examples/embassy",
"examples/zedboard",
"examples/defmt",
"zedboard-bsp",
"zedboard-qspi-flasher",
+21
View File
@@ -0,0 +1,21 @@
[package]
name = "defmt"
version = "0.1.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2024"
description = "DEFMT test app"
homepage = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs"
repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs"
license = "MIT OR Apache-2.0"
[dependencies]
aarch32-cpu = { version = "0.1" }
zynq7000-rt = { path = "../../zynq7000-rt" }
zynq7000 = { path = "../../zynq7000" }
zynq7000-hal = { path = "../../zynq7000-hal", features = ["defmt"] }
defmt = "1"
defmt-rtt = "1"
embedded-io = "0.7"
embedded-hal = "1"
fugit = "0.3"
log = "0.4"
+32
View File
@@ -0,0 +1,32 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
// Put `memory.x` in our output directory and ensure it's
// on the linker search path.
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rustc-link-arg=-Tdefmt.x");
// By default, Cargo will re-run a build script whenever
// any file in the project changes. By specifying `memory.x`
// here, we ensure the build script is only re-run when
// `memory.x` is changed.
println!("cargo:rerun-if-changed=memory.x");
}
+24
View File
@@ -0,0 +1,24 @@
MEMORY
{
/* Zedboard: 512 MB DDR3. Only use 63 MB for now, should be plenty for a bare-metal app.
Leave 1 MB of memory which will be configured as uncached device memory by the MMU. This is
recommended for something like DMA descriptors. */
/*CODE(rx) : ORIGIN = 0x00100000, LENGTH = 63M*/
CODE(rx) : ORIGIN = 0x00000000, LENGTH = 192K
UNCACHED(rx): ORIGIN = 0x4000000, LENGTH = 1M
}
REGION_ALIAS("VECTORS", CODE);
REGION_ALIAS("DATA", CODE);
SECTIONS
{
/* Uncached memory */
.uncached (NOLOAD) : ALIGN(4) {
. = ALIGN(4);
_sbss_uncached = .;
*(.uncached .uncached.*);
. = ALIGN(4);
_ebss_uncached = .;
} > UNCACHED
}
+83
View File
@@ -0,0 +1,83 @@
//! Simple blinky app, showing a PAC variant and a HAL variant.
#![no_std]
#![no_main]
use aarch32_cpu::asm::nop;
use core::panic::PanicInfo;
use defmt_rtt as _;
use embedded_hal::{delay::DelayNs, digital::StatefulOutputPin};
use zynq7000_hal::{
InteruptConfig,
clocks::Clocks,
gpio::{Output, PinState, mio},
priv_tim::CpuPrivateTimer,
time::Hertz,
};
pub const LIB: Lib = Lib::Hal;
// Define the clock frequency as a constant.
//
// Not required for the PAC mode, is required for clean delays in HAL mode.
const PS_CLOCK_FREQUENCY: Hertz = Hertz::from_raw(33_333_333);
#[derive(Debug)]
pub enum Lib {
Pac,
Hal,
}
#[zynq7000_rt::entry]
fn main() -> ! {
let dp = zynq7000_hal::init(zynq7000_hal::Config {
init_l2_cache: true,
level_shifter_config: Some(zynq7000_hal::LevelShifterConfig::EnableAll),
interrupt_config: Some(InteruptConfig::AllInterruptsToCpu0),
})
.expect("Failed to initialize Zynq7000");
defmt::println!("-- Zynq7000 defmt test application --");
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
defmt::info!("clocks {:?}", clocks);
// Unwrap okay, we only call this once on core 0 here.
let mut cpu_tim = CpuPrivateTimer::take(clocks.arm_clocks()).unwrap();
let mio_pins = mio::Pins::new(dp.gpio);
let mut led = Output::new_for_mio(mio_pins.mio7, PinState::High);
loop {
defmt::info!("toggling LED!");
led.toggle().unwrap();
cpu_tim.delay_ms(1000);
}
}
#[zynq7000_rt::irq]
fn irq_handler() {}
#[zynq7000_rt::exception(DataAbort)]
fn data_abort_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[zynq7000_rt::exception(Undefined)]
fn undefined_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
#[zynq7000_rt::exception(PrefetchAbort)]
fn prefetch_handler(_faulting_addr: usize) -> ! {
loop {
nop();
}
}
/// Panic handler
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {
nop();
}
}
+2
View File
@@ -42,10 +42,12 @@ vcell = "0.1"
raw-slicee = "0.1"
embedded-io-async = "0.7"
serde = { version = "1", optional = true, features = ["derive"] }
defmt = { version = "1", optional = true }
[features]
std = ["thiserror/std", "alloc"]
alloc = []
defmt = ["dep:defmt", "fugit/defmt"]
# These devices have a lower pin count.
7z010-7z007s-clg225 = []
+4
View File
@@ -14,6 +14,7 @@ use zynq7000::slcr::{
use super::time::Hertz;
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ArmClocks {
ref_clk: Hertz,
cpu_1x_clk: Hertz,
@@ -46,6 +47,7 @@ impl ArmClocks {
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DdrClocks {
/// DDR reference clock generated by the DDR PLL.
ref_clk: Hertz,
@@ -114,6 +116,7 @@ impl DdrClocks {
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct IoClocks {
/// Reference clock provided by IO PLL which is used to calculate all other clock frequencies.
ref_clk: Hertz,
@@ -195,6 +198,7 @@ impl IoClocks {
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Clocks {
ps_clk: Hertz,
arm_pll_out: Hertz,
+4
View File
@@ -4,6 +4,7 @@ check-all: (check "firmware") (check "host")
clean-all: (clean "firmware") (clean "host")
build-all: build-zynq (build "host")
fmt-all: (fmt "firmware") (fmt "host")
check-fmt-all: (check-fmt "firmware") (check-fmt "host")
clippy-all: (clippy "firmware") (clippy "host")
check target:
@@ -18,6 +19,9 @@ build-zynq: (build "firmware")
clean target:
cd {{target}} && cargo clean
check-fmt target:
cd {{target}} && cargo +stable fmt --all -- --check
fmt target:
cd {{target}} && cargo +stable fmt