Problems testing in a no_std environment (Arduino)

Hey all, I'm new here (and to rust)

I recently got an Arduino robot that I'm trying to program. I want to use rust to test my code on my own computer, not just run it on the Arduino. However, I've been having quite the time running tests.

I generated the project based off of Rahix's template, and when I run cargo test I get a bunch of errors like:

error[E0277]: the size for values of type `core::cmp::Ordering` cannot be known at compilation time
   --> /Users/tws/.cargo/registry/src/github.com-1ecc6299db9ec823/nb-1.0.0/src/lib.rs:198:38
    |
198 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
    |                                      ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `core::cmp::Ordering`
note: required by a bound in `Option`
   --> /Users/tws/.rustup/toolchains/nightly-2022-06-13-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:518:17
    |
518 | pub enum Option<T> {
    |                 ^ required by this bound in `Option`
    = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)

I am running a nightly version of rust, as that seems to be required. I've tried defining the tests in a module in the same lib.rs file, in a separate file, and in a separate workspace, but I always get error like the one above.

I am able to run the code fine on the arduino, but I can't run tests. My code is at this repo, if that helps give some more context.

Edit:
The tests I am trying to run are as simple as

#[cfg(test)]
mod testing {
    #[test]
    fn foo() {
        assert_eq!(1 + 1, 2);
    }
}

Independent of the error you're getting, do the Arduino crates you're using have support for running tests on a PC? Or even building for a PC?

When building for the target, code has to be generated that interacts with the AVR peripherals (I/O machine instructions specific to that processor). If an alternative is not written for a PC you could actually end up with what is essentially a corrupt executable.

I've done a bit of searching through the repo, and haven't found any mentions of tests. The tests I'm trying to write don't depend on any I/O, or anything from the crate directly, so I would expect that with the right settings they could run. How can I set up my tests to target my PC, while my builds still target the avr/adruino?

Step 1: Pick one thing you want to unit test. What is that one thing?

Thanks for helping!
So far, it's a custom sine function that operates on i8 and returns i8, instead of floats. There is nothing in there that should tie it to any particular OS/platform, so that should be a good place to start.

Yup. That definitely should be portable.

Were I in your shoes step 2 would be: Move the code of interest (sin) to a new crate. This new crate will contain things that are portable and, more importantly, unit testable.

Step 3 would be to reference the new crate from the old crate. That's really easy to do if the two crates are peers (side-by-side in the directory structure), together in a workspace, have a parent-child relationship in the directory structure, or one of them is published on crates.io. I prefer peers in a workspace when a project is young. Though, for this situation, a workspace may make things more difficult. And, you can always introduce the workspace later. So, peers.

I do wonder if the Libc sin is a better choice. That's an awful lot of 32 bit integer multiplies. For floats (f32) on AVR processors multiply and divide are actually faster (24 bits vs 32 bits).

Thanks for all the help! After following some of your steps, I get:

error: ran out of registers during register allocation

error: could not compile `core` due to previous error

So I think I've got some other errors to work through. I ended up finding this blog post, so I'm going to try and follow this, and see where I get. It looks like it's trying to solve the exact problems I have.

1 Like

Bummer.

Did you get the error when building for the AVR processor?