#unit-testing #embedded-devices

regmock-rs

Register mocking library to allow host unittests of embedded software, build on svd2pac

1 unstable release

0.1.0 Oct 14, 2024

#865 in Testing

Download history 143/week @ 2024-10-09 41/week @ 2024-10-16 2/week @ 2024-10-23

112 downloads per month

MIT license

61KB
877 lines

regmock-rs

A small library for mocking registers of embedded targets on host machines in Rust 🦀. It allows you to do a wide range of tests for embedded code on your host machine- mocking, faking or modelling the hardwares behavior.

⚠️ WARNING ⚠️ This crate is WIP and all APIs are subject to change.

Made for PACs generated with svd2pac.

Features ⚙️

As of now regmock-rs provides the following features:

  • 📼 recording of register accesses (type, register, values before and after the access)
  • 🤡 mocking of registers on host machines
  • 🔁 register arbitrary callbacks for register accesses
  • 🤫 non-recorded register access

How it works

regmock-rs provides the read_fn/write_fn (and ldmst_fn) functions that can be registered with PACs generated by svd2pac to trace register accesses.

When generating PACs using svd2pac and --features=tracing, the generated PAC provides interfaces to register functions that get called on register access operations (i.e. read/write and ldmst for the Aurix platform). This gives developers the ability to attach arbitrary behavior to the register accesses that get performed through the PAC, either by implementing these functions themselves or by using a library that provide an implementation of these functions.

regmock-rs is such a library. The provided read/write/ldmst functions together provide a more advanced implementation of functions that can be registered with svd2pac PACs. The Regmock struct provides a way of mocking registers of embedded devices on non-embedded host computers. This enables the execution unit tests of embedded code on developer machines as well as CI pipelines.

Event Logging 📜

This allows regmock-rs to record:

  • the order of register accesses
  • the access type (normally read/write - but special accesses such as LDMST on Aurix chips can easily be supported using feature flags)
  • on which register these accesses happen

In addition to the plain logging of register accesses, regmock-rs also allows to fully mock the actual registers that get accessed. With this, the log is able to record the value before and after the register access.

Non-Recorded Register Access

The silent<T>(f: impl FnOnce()->T)->T can be used to turn off logging and execution of possible callbacks during the execution of the passed function.

    unsafe {
        let _ =  regmock_rs::silent(|| { pac::REGISTER.bitfield().read() });
        let _ = unsafe { pac::REGISTER.bitfield().read() };
        let logs = regmock_rs::get_logs();
        assert_eq!(logs.len(), 1);
    }

Depending on regmock-rs

To integrate regmock-rs into your build you need a PAC crate and regmock-rs. You want to enable the tracing feature for test builds and keep it disabled for embedded builds.

[dependencies]
# you can for sure depend on released crates, but often you'll encounter "just a repo"
# here we enable all peripherals to be available
my-cpus-pac = { git = "<clone url>", rev = "<tag/revision to use>", features = ["all"] }

[dev-dependencies]
regmock-rs = { git = "https://github.com/Infineon/regmock-rs.git", rev = "<tag/revision to use>" }

[dev-dependencies]
# overwrite PAC cate features for test, we sadly need to restate url & revision
git = "<clone url from above>"
rev = "<rev from above>"
features = ["all", "tracing"] # tracing is not part of all

Assertions

As of now there are no assertions built into this library. This means developers are free to choose whatever assertion library they please. See the test-project test cases for an example how to write test and perform assertions.

Documentation

For an up-to-date documentation of the crate, its usage and different components please refer to the cargo generated documentation by running

cargo doc --open

A range of example with different complexity can be found in the examples.

Dependencies

~1.8–2.8MB
~57K SLoC