diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e476c406c..bcda8a64d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,6 +42,12 @@ jobs: run: | make arm_sdk_install --trace + - name: Setup Rust + run: | + rustup install nightly + rustup target add thumbv7em-none-eabihf + cargo install cbindgen + # EmuFlight version - name: Get Firmware Version id: get_version diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e4bfaa6eb..230947ffab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,12 @@ jobs: - name: Prepare environment run: make arm_sdk_install + - name: Setup Rust + run: | + rustup update stable + rustup target add thumbv7em-none-eabihf + cargo install cbindgen + - name: Execute Build run: make all RELEASE=${{ inputs.release_build && 'yes' || 'no' }} 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 456205e781..5d25fec59a 100644 --- a/Makefile +++ b/Makefile @@ -218,6 +218,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_SOURCES := $(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 @@ -250,7 +262,7 @@ CC_DEBUG_OPTIMISATION := $(OPTIMISE_DEFAULT) CC_DEFAULT_OPTIMISATION := $(OPTIMISATION_BASE) $(OPTIMISE_DEFAULT) CC_SPEED_OPTIMISATION := $(OPTIMISATION_BASE) $(OPTIMISE_SPEED) CC_SIZE_OPTIMISATION := $(OPTIMISATION_BASE) $(OPTIMISE_SIZE) -CC_NO_OPTIMISATION := +CC_NO_OPTIMISATION := # # Added after GCC version update, remove once the warnings have been fixed @@ -347,6 +359,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_SOURCES) + cd $(RUSTEMU_DIR) && cargo build --release --target thumbv7em-none-eabihf + +$(RUSTEMU_HEADER): $(RUSTEMU_LIBRARY) + cd $(RUSTEMU_DIR) && 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. @@ -357,7 +375,7 @@ ifeq ($(EXST),no) $(TARGET_BIN): $(TARGET_ELF) @echo "Creating BIN $(TARGET_BIN)" "$(STDOUT)" $(V1) $(OBJCOPY) -O binary $< $@ - + $(TARGET_HEX): $(TARGET_ELF) @echo "Creating HEX $(TARGET_HEX)" "$(STDOUT)" $(V1) $(OBJCOPY) -O ihex --set-start 0x8000000 $< $@ @@ -381,8 +399,8 @@ $(TARGET_BIN): $(TARGET_UNPATCHED_BIN) $(V1) dd if=$(TARGET_UNPATCHED_BIN) of=$(TARGET_BIN) conv=notrunc @echo "Generating MD5 hash of binary" "$(STDOUT)" - $(V1) openssl dgst -md5 $(TARGET_BIN) > $(TARGET_UNPATCHED_BIN).md5 - + $(V1) openssl dgst -md5 $(TARGET_BIN) > $(TARGET_UNPATCHED_BIN).md5 + @echo "Patching MD5 hash into binary" "$(STDOUT)" $(V1) cat $(TARGET_UNPATCHED_BIN).md5 | awk '{printf("%08x: %s",(1024*$(FIRMWARE_SIZE))-16,$$2);}' | xxd -r - $(TARGET_BIN) $(V1) echo $(FIRMWARE_SIZE) | awk '{printf("-s 0x%08x -l 16 -c 16 %s",(1024*$$1)-16,"$(TARGET_BIN)");}' | xargs xxd @@ -395,12 +413,12 @@ $(TARGET_BIN): $(TARGET_UNPATCHED_BIN) @echo "Extracting HASH section from unpatched EXST elf $(TARGET_ELF)" "$(STDOUT)" $(OBJCOPY) $(TARGET_ELF) $(TARGET_EXST_ELF).tmp --dump-section .exst_hash=$(TARGET_EXST_HASH_SECTION_FILE) -j .exst_hash rm $(TARGET_EXST_ELF).tmp - + @echo "Patching MD5 hash into HASH section" "$(STDOUT)" $(V1) cat $(TARGET_UNPATCHED_BIN).md5 | awk '{printf("%08x: %s",64-16,$$2);}' | xxd -r - $(TARGET_EXST_HASH_SECTION_FILE) - + # For some currently unknown reason, OBJCOPY, with only input/output files, will generate a file around 2GB for the H730 unless we remove an unused-section -# As a workaround drop the ._user_heap_stack section, which is only used during build to show errors if there's not enough space for the heap/stack. +# As a workaround drop the ._user_heap_stack section, which is only used during build to show errors if there's not enough space for the heap/stack. # The issue can be seen with `readelf -S $(TARGET_EXST_ELF)' vs `readelf -S $(TARGET_ELF)` $(V1) @echo "Patching updated HASH section into $(TARGET_EXST_ELF)" "$(STDOUT)" $(OBJCOPY) $(TARGET_ELF) $(TARGET_EXST_ELF) --remove-section ._user_heap_stack --update-section .exst_hash=$(TARGET_EXST_HASH_SECTION_FILE) @@ -416,7 +434,7 @@ $(TARGET_HEX): $(TARGET_BIN) endif -$(TARGET_ELF): $(TARGET_OBJS) $(LD_SCRIPT) $(LD_SCRIPTS) +$(TARGET_ELF): $(RUSTEMU_HEADER) $(RUSTEMU_LIBRARY) $(TARGET_OBJS) $(LD_SCRIPT) $(LD_SCRIPTS) @echo "Linking $(TARGET)" "$(STDOUT)" $(V1) $(CROSS_CC) -o $@ $(filter-out %.ld,$^) $(LD_FLAGS) $(V1) $(SIZE) $(TARGET_ELF) @@ -708,7 +726,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 552760f141..9c5f77556d 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 200c00b5d7..1d9ba4fd8d 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 3bb2f709ae..0000000000 --- a/src/main/common/encoding.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Cleanflight and Betaflight. - * - * Cleanflight and Betaflight 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 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 8eb845c226..0000000000 --- a/src/main/common/encoding.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Cleanflight and Betaflight. - * - * Cleanflight and Betaflight 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 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..45855cb55c --- /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.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" + +[[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.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +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..ed8afed3fe --- /dev/null +++ b/src/rustemu/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "rustemu" +version = "0.1.0" +edition = "2021" +publish = false + +[profile.dev] +panic = "abort" + +[profile.release] +opt-level = 'z' # turn on maximum optimizations. We only have 64kB +lto = true # Link-time-optimizations for further size reduction +panic = "abort" + +[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/Makefile b/src/test/Makefile index e7a8a242f1..056611e30f 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -17,6 +17,13 @@ ROOT = ../.. OBJECT_DIR = ../../obj/test TARGET_DIR = $(USER_DIR)/target +RUSTEMU_DIR := $(ROOT)/src/rustemu +RUSTEMU_INCLUDE_DIR := $(RUSTEMU_DIR)/include/ +RUSTEMU_TARGET_DIR := $(RUSTEMU_DIR)/target/x86_64-unknown-linux-gnu/release +RUSTEMU_HEADER := $(RUSTEMU_INCLUDE_DIR)/rustemu.h +RUSTEMU_LIBRARY := $(RUSTEMU_TARGET_DIR)/librustemu.a +RUSTEMU_SOURCES := $(shell find $(RUSTEMU_DIR)/src -name '*.rs') + include $(ROOT)/make/system-id.mk include $(ROOT)/make/targets_list.mk @@ -130,10 +137,6 @@ common_filter_unittest_SRC := \ $(USER_DIR)/common/maths.c -encoding_unittest_SRC := \ - $(USER_DIR)/common/encoding.c - - flight_failsafe_unittest_SRC := \ $(USER_DIR)/common/bitarray.c \ $(USER_DIR)/fc/rc_modes.c \ @@ -511,7 +514,7 @@ ifeq ($(shell $(CC) -v 2>&1 | grep -q "clang version" && echo "clang"),clang) # Travis reports CC_VERSION of 4.2.1 CC_VERSION_MAJOR := $(firstword $(subst ., ,$(CC_VERSION))) CC_VERSION_CHECK_MIN := 7 -CC_VERSION_CHECK_MAX := 13 +CC_VERSION_CHECK_MAX := 15 # Added flags for clang 11 - 13 are not backwards compatible ifeq ($(shell expr $(CC_VERSION_MAJOR) \> 10 \& $(CC_VERSION_MAJOR) \< 14), 1) @@ -566,6 +569,7 @@ C_FLAGS += $(COVERAGE_FLAGS) CXX_FLAGS += $(COVERAGE_FLAGS) C_FLAGS += -D_GNU_SOURCE +LD_FLAGS += -L$(RUSTEMU_TARGET_DIR) -lrustemu # Set up the parameter group linker flags according to OS ifeq ($(OSFAMILY), macosx) @@ -674,10 +678,15 @@ $(OBJECT_DIR)/gtest_main.a : $(OBJECT_DIR)/gtest-all.o $(OBJECT_DIR)/gtest_main. -include $(OBJECT_DIR)/gtest-all.d \ $(OBJECT_DIR)/gtest_main.d +$(RUSTEMU_LIBRARY): $(RUSTEMU_SOURCES) + cd $(ROOT)/src/rustemu && cargo +nightly build --release + +$(RUSTEMU_HEADER): $(RUSTEMU_LIBRARY) + cd $(ROOT)/src/rustemu && cbindgen --lang c++ -o $(PWD)/$(RUSTEMU_HEADER) # includes in test dir must override includes in user dir, unless the user # specifies a list of endorsed directories in ${target}_INCLUDE_DIRS. -test_include_dirs = $1 $(TEST_DIR) $(USER_DIR) +test_include_dirs = $1 $(TEST_DIR) $(USER_DIR) $(RUSTEMU_INCLUDE_DIR) test_cflags = $(addprefix -I,$(call test_include_dirs,$1)) @@ -748,7 +757,7 @@ $(OBJECT_DIR)/$1/%.c.o: $(TARGET_DIR)/$(call get_base_target,$(call target,$1))/ -c $$< -o $$@ endif -$(OBJECT_DIR)/$1/$(basename $1).o: $(TEST_DIR)/$(basename $1).cc +$(OBJECT_DIR)/$1/$(basename $1).o: $(RUSTEMU_HEADER) $(TEST_DIR)/$(basename $1).cc @echo "compiling $$<" "$(STDOUT)" $(V1) mkdir -p $$(dir $$@) $(V1) $(CXX) $(CXX_FLAGS) $$(call test_cflags,$$($1_INCLUDE_DIRS)) \ 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" { -}