diff --git a/.gitignore b/.gitignore index 8a6e74d6c0..97da0fa07e 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ ubuntu*.log # EEPROM image file (created by SITL) eeprom.bin + +src/rustemu/include/* +src/rustemu/target/* diff --git a/Makefile b/Makefile index 3df70b2dab..7b36379904 100644 --- a/Makefile +++ b/Makefile @@ -203,6 +203,18 @@ INCLUDE_DIRS := $(INCLUDE_DIRS) \ INCLUDE_DIRS := $(INCLUDE_DIRS) \ $(TARGET_DIR) +RUSTEMU_DIR := $(ROOT)/src/rustemu +RUSTEMU_INCLUDE_DIR := $(RUSTEMU_DIR)/include/ +RUSTEMU_TARGET_DIR := $(RUSTEMU_DIR)/target/thumbv7em-none-eabihf/release +RUSTEMU_HEADER := $(RUSTEMU_INCLUDE_DIR)/rustemu.h +RUSTEMU_LIBRARY := $(RUSTEMU_TARGET_DIR)/librustemu.a +RUSTEMU_SRC := $(shell find $(RUSTEMU_DIR)/src -name '*.rs') + +INCLUDE_DIRS := $(INCLUDE_DIRS) \ + $(RUSTEMU_INCLUDE_DIR) + +EXTRA_LD_FLAGS := $(EXTRA_LD_FLAGS) -L$(RUSTEMU_TARGET_DIR) -lrustemu + VPATH := $(VPATH):$(TARGET_DIR) include $(ROOT)/make/source.mk @@ -327,6 +339,12 @@ CLEAN_ARTIFACTS += $(TARGET_DFU) # Make sure build date and revision is updated on every incremental build $(OBJECT_DIR)/$(TARGET)/build/version.o : $(SRC) +$(RUSTEMU_LIBRARY): $(RUSTEMU_SRC) + cd src/rustemu && cargo build --release --target thumbv7em-none-eabihf + +$(RUSTEMU_HEADER): $(RUSTEMU_LIBRARY) + cd src/rustemu && cbindgen --lang c -o $(PWD)/$(RUSTEMU_HEADER) + # List of buildable ELF files and their object dependencies. # It would be nice to compute these lists, but that seems to be just beyond make. @@ -390,7 +408,7 @@ $(TARGET_HEX): $(TARGET_BIN) endif -$(TARGET_ELF): $(TARGET_OBJS) $(LD_SCRIPT) +$(TARGET_ELF): $(RUSTEMU_HEADER) $(RUSTEMU_LIBRARY) $(TARGET_OBJS) $(LD_SCRIPT) @echo "Linking $(TARGET)" "$(STDOUT)" $(V1) $(CROSS_CC) -o $@ $(filter-out %.ld,$^) $(LD_FLAGS) $(V1) $(SIZE) $(TARGET_ELF) @@ -683,7 +701,6 @@ test_versions: test_%: $(V0) cd src/test && $(MAKE) $@ - # rebuild everything when makefile changes $(TARGET_OBJS): Makefile $(TARGET_DIR)/target.mk $(wildcard make/*) diff --git a/src/main/blackbox/blackbox.c b/src/main/blackbox/blackbox.c index 5ea25df7a9..1deda8ec3e 100644 --- a/src/main/blackbox/blackbox.c +++ b/src/main/blackbox/blackbox.c @@ -36,8 +36,9 @@ #include "build/debug.h" #include "build/version.h" +#include + #include "common/axis.h" -#include "common/encoding.h" #include "common/maths.h" #include "common/time.h" #include "common/utils.h" diff --git a/src/main/blackbox/blackbox_encoding.c b/src/main/blackbox/blackbox_encoding.c index 1fe94c2608..581b6237cd 100644 --- a/src/main/blackbox/blackbox_encoding.c +++ b/src/main/blackbox/blackbox_encoding.c @@ -31,9 +31,9 @@ #include "blackbox_encoding.h" #include "blackbox_io.h" -#include "common/encoding.h" #include "common/printf.h" +#include static void _putc(void *p, char c) { diff --git a/src/main/common/encoding.c b/src/main/common/encoding.c deleted file mode 100644 index de4d8719e9..0000000000 --- a/src/main/common/encoding.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Cleanflight and Betaflight and EmuFlight. - * - * Cleanflight and Betaflight and EmuFlight are free software. You can redistribute - * this software and/or modify this software under the terms of the - * GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * Cleanflight and Betaflight and EmuFlight are distributed in the hope that they - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software. - * - * If not, see . - */ - -#include "platform.h" - -#include "encoding.h" - -/** - * Cast the in-memory representation of the given float directly to an int. - * - * This is useful for printing the hex representation of a float number (which is considerably cheaper - * than a full decimal float formatter, in both code size and output length). - */ -uint32_t castFloatBytesToInt(float f) -{ - union floatConvert_t { - float f; - uint32_t u; - } floatConvert; - - floatConvert.f = f; - - return floatConvert.u; -} - -/** - * ZigZag encoding maps all values of a signed integer into those of an unsigned integer in such - * a way that numbers of small absolute value correspond to small integers in the result. - * - * (Compared to just casting a signed to an unsigned which creates huge resulting numbers for - * small negative integers). - */ -uint32_t zigzagEncode(int32_t value) -{ - return (uint32_t)((value << 1) ^ (value >> 31)); -} diff --git a/src/main/common/encoding.h b/src/main/common/encoding.h deleted file mode 100644 index 758a175f84..0000000000 --- a/src/main/common/encoding.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Cleanflight and Betaflight and EmuFlight. - * - * Cleanflight and Betaflight and EmuFlight are free software. You can redistribute - * this software and/or modify this software under the terms of the - * GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * Cleanflight and Betaflight and EmuFlight are distributed in the hope that they - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software. - * - * If not, see . - */ - -#pragma once - -#include - -uint32_t castFloatBytesToInt(float f); -uint32_t zigzagEncode(int32_t value); diff --git a/src/rustemu/Cargo.lock b/src/rustemu/Cargo.lock new file mode 100644 index 0000000000..1c172ecf41 --- /dev/null +++ b/src/rustemu/Cargo.lock @@ -0,0 +1,337 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cbindgen" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e3973b165dc0f435831a9e426de67e894de532754ff7a3f307c03ee5dec7dc" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "libc" +version = "0.2.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "panic-abort" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e20e6499bbbc412f280b04a42346b356c6fa0753d5fd22b7bd752ff34c778ee" + +[[package]] +name = "panic-halt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rustemu" +version = "0.1.0" +dependencies = [ + "cbindgen", + "panic-abort", + "panic-halt", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "serde" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/src/rustemu/Cargo.toml b/src/rustemu/Cargo.toml new file mode 100644 index 0000000000..52063f09ce --- /dev/null +++ b/src/rustemu/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "rustemu" +version = "0.1.0" +edition = "2021" +publish = false + +[profile.release] +opt-level = 'z' # turn on maximum optimizations. We only have 64kB +lto = true # Link-time-optimizations for further size reduction + +[lib] +crate-type = ["staticlib"] + +[build-dependencies] +cbindgen = "0.20.0" + +[dependencies] +panic-abort = "0.3.2" +panic-halt = "0.2.0" diff --git a/src/rustemu/src/lib.rs b/src/rustemu/src/lib.rs new file mode 100644 index 0000000000..229deed32f --- /dev/null +++ b/src/rustemu/src/lib.rs @@ -0,0 +1,42 @@ +#![no_std] + +// dev profile: easier to debug panics; can put a breakpoint on `rust_begin_unwind` +#[cfg(all(debug_assertions, not(test)))] +use panic_halt as _; + +// release profile: minimize the binary size of the application +#[cfg(all(not(debug_assertions), not(test)))] +use panic_abort as _; + + +#[no_mangle] pub extern fn zigzagEncode(value: i32) -> u32 { + ((value << 1) ^ (value >> 31)) as u32 +} + +#[no_mangle] pub extern fn castFloatBytesToInt(value: f32) -> u32 { + u32::from_ne_bytes(value.to_ne_bytes()) +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn zigzagEncode_test() { + assert_eq!(zigzagEncode(0), 0); + assert_eq!(zigzagEncode(-1), 1); + assert_eq!(zigzagEncode(1), 2); + assert_eq!(zigzagEncode(2147483646), 4294967292); + assert_eq!(zigzagEncode(-2147483647), 4294967293); + assert_eq!(zigzagEncode(2147483647), 4294967294); + assert_eq!(zigzagEncode(-2147483648), 4294967295); + } + + #[test] + fn castFloatBytesToInt_test() { + assert_eq!(castFloatBytesToInt(0.0), 0); + assert_eq!(castFloatBytesToInt(2.0), 0x40000000); + assert_eq!(castFloatBytesToInt(4.5), 0x40900000); + } +} diff --git a/src/test/unit/encoding_unittest.cc b/src/test/unit/encoding_unittest.cc deleted file mode 100644 index 6e7cb29d5a..0000000000 --- a/src/test/unit/encoding_unittest.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Cleanflight. - * - * Cleanflight is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Cleanflight is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Cleanflight. If not, see . - */ -#include - -extern "C" { - #include "common/encoding.h" -} - -#include "unittest_macros.h" -#include "gtest/gtest.h" - -typedef struct zigzagEncodingExpectation_s { - int32_t input; - uint32_t expected; -} zigzagEncodingExpectation_t; - -typedef struct floatToIntEncodingExpectation_s { - float input; - uint32_t expected; -} floatToIntEncodingExpectation_t; - -TEST(EncodingTest, ZigzagEncodingTest) -{ - // given - zigzagEncodingExpectation_t expectations[] = { - { 0, 0}, - {-1, 1}, - { 1, 2}, - {-2, 3}, - { 2, 4}, - - { 2147483646, 4294967292}, - {-2147483647, 4294967293}, - { 2147483647, 4294967294}, - {-2147483648, 4294967295}, - }; - int expectationCount = sizeof(expectations) / sizeof(expectations[0]); - - // expect - - for (int i = 0; i < expectationCount; i++) { - zigzagEncodingExpectation_t *expectation = &expectations[i]; - - EXPECT_EQ(expectation->expected, zigzagEncode(expectation->input)); - } -} - -TEST(EncodingTest, FloatToIntEncodingTest) -{ - // given - floatToIntEncodingExpectation_t expectations[] = { - {0.0, 0x00000000}, - {2.0, 0x40000000}, // Exponent should be in the top bits - {4.5, 0x40900000} - }; - int expectationCount = sizeof(expectations) / sizeof(expectations[0]); - - // expect - - for (int i = 0; i < expectationCount; i++) { - floatToIntEncodingExpectation_t *expectation = &expectations[i]; - - EXPECT_EQ(expectation->expected, castFloatBytesToInt(expectation->input)); - } -} - -// STUBS - -extern "C" { -}