Crate adacore_zynqmp

Source
Expand description

Support for the AMD Zynq UltraScale+ MPSoC.

§Usage

The crate expects a file called memory.x, which defines the memory map for a specific board, in the package root of your Cargo project. Here is a sample memory map for the ZCU102 board:

MEMORY
{
  DDR (rwx) : ORIGIN = 0, LENGTH = 2048M
  OCM (rwx) : ORIGIN = 0xFFFC0000, LENGTH = 256K
}

REGION_ALIAS("CODE", DDR)
REGION_ALIAS("DATA", DDR)

Cargo will generate a linker script called link.x when the adacore_zynqmp crate is built. You must ensure that this linker script is used by adding the following flag to your .cargo/config.toml:

[target.aarch64-unknown-none]
rustflags = [
    "-C", "link-arg=-Tlink.x"
]

Alternatively, this flag can be defined in a build script or the RUSTFLAGS environment variable.

The std feature enables limited support for std. The adacore_zynqmp crate must be referenced in a use import to ensure that the crate is linked into the binary:

use adacore_zynqmp as _;

fn main() {
    println!("Hello, world!");
}

In a no_std project the entry point must be defined using the entry macro.

§Interrupt Handling

You can define custom interrupt handling by implementing the following functions:

#[unsafe(no_mangle)]
extern "C" fn _sync_handler() {
    // ...
}

#[unsafe(no_mangle)]
extern "C" fn _irq_handler() {
    // ...
}

#[unsafe(no_mangle)]
extern "C" fn _fiq_handler() {
    // ...
}

#[unsafe(no_mangle)]
extern "C" fn _serror_handler() {
    // ...
}

By default, an interrupt leads to a spin loop.

§Exit Handling

By default, a soft reset will be performed if an exit point is reached. You can change this behavior by defining a custom exit handler:

#[unsafe(no_mangle)]
extern "C" fn _exit_handler() {
    // ...
}

§Optional Features

§std

Provides limited support for std based on Newlib, including support for cargo test:

use adacore_zynqmp as _;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

§Limitations

Panics on this target call abort() rather than unwinding the stack, which has two consequences:

  • #[should_panic] cannot confirm an expected panic: when a #[should_panic] test actually panics, the abort terminates the whole test binary and the harness never observes the panic. A #[should_panic] test that does not panic is still reported as a failure correctly, since the harness only needs to observe a normal return.
  • An unexpected panic in any test aborts the entire test binary; results for subsequent tests are lost. On QEMU, abort() triggers a soft reset which QEMU may not handle, causing the process to hang until the runner kills it. Enable the semihosting feature to make QEMU exit cleanly instead.

Requires GNAT Pro for Rust 26 or newer, since stable Rust does not ship std support for aarch64-unknown-none. GNAT Pro for Rust 27 or newer is needed for correct timing values: the newlib PAL timing implementation in 27 reports durations with microsecond precision, while earlier versions compile but produce coarse or incorrect timing in Instant-based measurements such as libtest’s per-test durations.

§semihosting

Enables clean QEMU termination via semihosting, which is useful for cargo test where a hanging process would otherwise require a timeout to recover from. Specifically:

  • _exit terminates via a semihosting SYS_EXIT call rather than a soft reset.
  • The default exception handler calls _exit(-1) rather than spinning, so that QEMU exits cleanly when a panicking test triggers an abort exception.

Enable this feature when running under QEMU. Do not enable it for production builds targeting real hardware, where semihosting is not available.

Implies the std feature.

§Minimum Supported Rust Version (MSRV)

This crate is guaranteed to compile on stable Rust 1.85.0 and up. It might compile with older versions but that may change in any new patch release.

Modules§

Macros§

  • Defines the entry point of the binary.

Functions§