#run-time #arm #no-std #cortex-r

no-std cortex-r-rt

Run-time support for Arm Cortex-R

1 unstable release

0.1.0 Feb 25, 2025

#2056 in Embedded development

MIT/Apache

315KB
8K SLoC

Arm Cortex-R Run-Time

Minimum Supported Rust Version (MSRV)

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

Licence

Copyright (c) Ferrous Systems, 2025

Licensed under either MIT or Apache-2.0 at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be licensed as above, without any additional terms or conditions.


lib.rs:

Run-time support for Arm Cortex-R

This library implements a simple Arm vector table, suitable for getting into a Rust application running in System Mode.

Transferring from System Mode to User Mode (i.e. implementing an RTOS) is not handled here.

If your processor starts in Hyp mode, this runtime will be transfer it to System mode. If you wish to write a hypervisor, you will need to replace this library with something more advanced.

We assume the following global symbols exist:

  • __start - a Reset handler. Our linker script PROVIDEs a default function at _default_start but you can override it.
  • _stack_top - the address of the top of some region of RAM that we can use as stack space, with eight-byte alignment. Our linker script PROVIDEs a default pointing at the top of RAM.
  • _fiq_stack_size - the number of bytes to be reserved for stack space when in FIQ mode; must be a multiple of 8.
  • _irq_stack_size - the number of bytes to be reserved for stack space when in FIQ mode; must be a multiple of 8.
  • _svc_stack_size - the number of bytes to be reserved for stack space when in SVC mode; must be a multiple of 8.F
  • _svc_handler - an extern "C" function to call when an SVC Exception occurs. Our linker script PROVIDEs a default function at _default_handler but you can override it.
  • _irq_handler - an extern "C" function to call when an Interrupt occurs. Our linker script PROVIDEs a default function at _default_handler but you can override it.
  • _asm_fiq_handler - a naked function to call when a Fast Interrupt Request (FIQ) occurs. Our linker script PROVIDEs a default function at _asm_default_fiq_handler but you can override it.
  • _asm_undefined_handler - a naked function to call when an Undefined Exception occurs. Our linker script PROVIDEs a default function at _asm_default_handler but you can override it.
  • _asm_prefetch_handler - a naked function to call when an Prefetch Exception occurs. Our linker script PROVIDEs a default function at _asm_default_handler but you can override it.
  • _asm_abort_handler - a naked function to call when an Abort Exception occurs. Our linker script PROVIDEs a default function at _asm_default_handler but you can override it.
  • kmain - the extern "C" entry point to your application.
  • __sdata - the start of initialised data in RAM. Must be 4-byte aligned.
  • __edata - the end of initialised data in RAM. Must be 4-byte aligned.
  • __sidata - the start of the initialisation values for data, in read-only memory. Must be 4-byte aligned.
  • __sbss - the start of zero-initialised data in RAM. Must be 4-byte aligned.
  • __ebss - the end of zero-initialised data in RAM. Must be 4-byte aligned.

On start-up, the memory between __sbss and __ebss is zeroed, and the memory between __sdata and __edata is initialised with the data found at __sidata.

This library produces global symbols called:

  • _vector_table - the start of the interrupt vector table
  • _default_start - the default Reset handler, that sets up some stacks and calls an extern "C" function called kmain.
  • _asm_default_fiq_handler - an FIQ handler that just spins
  • _asm_default_handler - an exception handler that just spins
  • _asm_svc_handler - assembly language trampoline for SVC Exceptions that calls _svc_handler
  • _asm_irq_handler - assembly language trampoline for Interrupts that calls _irq_handler

The assembly language trampolines are required because Armv7-R (and Armv8-R) processors do not save a great deal of state on entry to an exception handler, unlike Armv7-M (and other M-Profile) processors. We must therefore save this state to the stack using assembly language, before transferring to an extern "C" function. We do not change modes before entering that extern "C" function - that's for the handler to deal with as it wishes. We supply a default handler that prints an error message to Semihosting so you know if you hit an unexpected exception. Because FIQ is often performance-sensitive, we don't supply an FIQ trampoline; if you want to use FIQ, you have to write your own assembly routine, allowing you to preserve only whatever state is important to you.

If our start-up routine doesn't work for you (e.g. if you have to initialise your memory controller before you touch RAM), supply your own _start function (but feel free to call our _default_start as part of it).

Dependencies

~0.5–0.9MB
~20K SLoC