From 76f1651736186500d11bcc1886fa3faf2fe4b15a Mon Sep 17 00:00:00 2001 From: franchioping Date: Mon, 16 Mar 2026 00:49:02 +0000 Subject: [PATCH] start of rust + c journey --- .envrc | 1 + .gitignore | 2 + components/drone_controller | 2 +- components/rustlib/CMakeLists.txt | 62 ------------------------- components/rustlib/Cargo.toml | 30 ------------ components/rustlib/README.md | 13 ------ components/rustlib/build.rs | 22 --------- components/rustlib/placeholder.c | 13 ------ components/rustlib/rust-toolchain.toml | 3 -- components/rustlib/src/lib.rs | 31 ------------- main/CMakeLists.txt | 2 +- main/main.c | 64 -------------------------- main/main.cpp | 52 +++++++++++++++++++++ 13 files changed, 57 insertions(+), 240 deletions(-) create mode 100644 .envrc delete mode 100644 components/rustlib/CMakeLists.txt delete mode 100644 components/rustlib/Cargo.toml delete mode 100644 components/rustlib/README.md delete mode 100644 components/rustlib/build.rs delete mode 100644 components/rustlib/placeholder.c delete mode 100644 components/rustlib/rust-toolchain.toml delete mode 100644 components/rustlib/src/lib.rs delete mode 100644 main/main.c create mode 100644 main/main.cpp diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 7ec534c..4f14052 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ build/ target/ +.direnv + sdkconfig.old sdkconfig debug/ diff --git a/components/drone_controller b/components/drone_controller index ede4036..8ae1b54 160000 --- a/components/drone_controller +++ b/components/drone_controller @@ -1 +1 @@ -Subproject commit ede403613d96b3233e2c8f8be04dc4cb9efd7569 +Subproject commit 8ae1b54c6100a96a670255e35960f9372c2b4dfb diff --git a/components/rustlib/CMakeLists.txt b/components/rustlib/CMakeLists.txt deleted file mode 100644 index 1722180..0000000 --- a/components/rustlib/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ - -idf_component_register( - SRCS "placeholder.c" - INCLUDE_DIRS "" - PRIV_REQUIRES "${RUST_DEPS}" -) - -set(CARGO_BUILD_TYPE "release") -set(CARGO_BUILD_ARG "--release") -if(CONFIG_IDF_TARGET_ARCH_RISCV) - set(CARGO_TARGET "riscv32imc-esp-espidf") - set(CARGO_FEATURES_ARG "") -elseif(CONFIG_IDF_TARGET_ARCH_XTENSA) - set(CARGO_TARGET "xtensa-esp32-espidf") - set(CARGO_FEATURES_ARG "--features=std") -endif() - -set(RUST_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}") -set(RUST_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}") -set(RUST_TARGET_DIR "${RUST_BUILD_DIR}/target") -set(RUST_INCLUDE_DIR "${RUST_TARGET_DIR}") -set(RUST_INCLUDE_HEADER "${RUST_INCLUDE_DIR}/RustApi.h") -set(RUST_STATIC_LIBRARY "${RUST_TARGET_DIR}/${CARGO_TARGET}/${CARGO_BUILD_TYPE}/librustlib.a") - -idf_build_get_property(sdkconfig SDKCONFIG) - -ExternalProject_Add( - rustlib_project - PREFIX "${RUST_PROJECT_DIR}" - DOWNLOAD_COMMAND "" - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env - CARGO_BUILD_TARGET=${CARGO_TARGET} - CARGO_BUILD_TARGET_DIR=${RUST_TARGET_DIR} - cargo clean - BUILD_COMMAND ${CMAKE_COMMAND} -E env - CARGO_BUILD_TARGET=${CARGO_TARGET} - CARGO_BUILD_TARGET_DIR=${RUST_TARGET_DIR} - CARGO_CMAKE_BUILD_INCLUDES=$ - CARGO_CMAKE_BUILD_LINK_LIBRARIES=$ - CARGO_CMAKE_BUILD_SDKCONFIG=${sdkconfig} - CARGO_CMAKE_BUILD_COMPILER=${CMAKE_C_COMPILER} - cargo build ${CARGO_BUILD_ARG} ${CARGO_FEATURES_ARG} - INSTALL_COMMAND "" - BUILD_ALWAYS TRUE - TMP_DIR "${RUST_BUILD_DIR}/tmp" - STAMP_DIR "${RUST_BUILD_DIR}/stamp" - DOWNLOAD_DIR "${RUST_BUILD_DIR}" - SOURCE_DIR "${RUST_PROJECT_DIR}" - BINARY_DIR "${RUST_PROJECT_DIR}" - INSTALL_DIR "${RUST_BUILD_DIR}" - BUILD_BYPRODUCTS - "${RUST_INCLUDE_HEADER}" - "${RUST_STATIC_LIBRARY}" -) - -set_source_files_properties("${RUST_INCLUDE_HEADER}" PROPERTIES GENERATED true) - -add_prebuilt_library(rustlib_lib "${RUST_STATIC_LIBRARY}" PRIV_REQUIRES "${RUST_DEPS}") -add_dependencies(rustlib_lib rustlib_project) - -target_include_directories(${COMPONENT_LIB} PUBLIC "${RUST_INCLUDE_DIR}") -target_link_libraries(${COMPONENT_LIB} PRIVATE rustlib_lib) diff --git a/components/rustlib/Cargo.toml b/components/rustlib/Cargo.toml deleted file mode 100644 index 968595e..0000000 --- a/components/rustlib/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "rustlib" -version = "0.1.0" -authors = ["Espressif Systems CO LTD", "June Life Inc"] -edition = "2018" - -[lib] -crate-type = ["staticlib"] - -[build-dependencies] -bindgen = "0.58" -cbindgen = "0.19" - -[features] -std = [] - -[profile.dev] -# Optimization level 1 is similar to "g" in gcc/clang, although for some reason -# Cargo doesn't support that flag. -#opt-level = 1 -opt-level = "s" - -[profile.release] -debug = true -opt-level = "z" -#debug = true -#lto = true -#opt-level = "z" -#codegen-units = 1 -#panic = "abort" diff --git a/components/rustlib/README.md b/components/rustlib/README.md deleted file mode 100644 index da414e5..0000000 --- a/components/rustlib/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# rustlib - -This component generates a static library from Rust source code and exposes functions that will be callable from the main IDF application from C. - -This component is responsible for three separate functions: - -* Export C bindings for Rust functions with `cbindgen`. -* Import Rust binding for C functions with `bindgen`. -* Build a top level static library from Rust code. The `cargo` build command is wrapped in a CMake `ExternalProject_Add` command. - -Currently the `build.rs` script expects the `clib` component to export a header with the name `CApi.h`. If the name of the include file changes or if more files are added, the build script must be updated to process the latest headers. - -Depending on the complexity of the project, the `cbindgen` and `bindgen` steps could be broken out into one or more IDF components or Rust crates. However, to prevent redundant duplication of the Rust runtime, all Rust crates should be compiled into a single static library that will be linked into the final IDF application. \ No newline at end of file diff --git a/components/rustlib/build.rs b/components/rustlib/build.rs deleted file mode 100644 index 9f35067..0000000 --- a/components/rustlib/build.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::env; -use std::path::{Path, PathBuf}; - -fn main() { - let cargo_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); - let target_dir = PathBuf::from(env::var("CARGO_BUILD_TARGET_DIR").unwrap()); - - run_cbindgen(&cargo_dir, &target_dir); -} - -fn run_cbindgen(cargo_dir: &Path, target_dir: &Path) { - let out = target_dir.join("RustApi.h"); - - cbindgen::Builder::new() - .with_crate(cargo_dir) - .with_language(cbindgen::Language::C) - .generate() - .expect("Unable to generate bindings") - .write_to_file(&out); - - println!("cargo:rerun-if-changed={}", out.display()); -} diff --git a/components/rustlib/placeholder.c b/components/rustlib/placeholder.c deleted file mode 100644 index de0472a..0000000 --- a/components/rustlib/placeholder.c +++ /dev/null @@ -1,13 +0,0 @@ -/* Hello World Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -/* This is an empty source file to force the build of a CMake library that - can participate in the CMake dependency graph. This placeholder library - will depend on the actual library generated by external Rust build. -*/ \ No newline at end of file diff --git a/components/rustlib/rust-toolchain.toml b/components/rustlib/rust-toolchain.toml deleted file mode 100644 index 4a4152d..0000000 --- a/components/rustlib/rust-toolchain.toml +++ /dev/null @@ -1,3 +0,0 @@ -[toolchain] -channel = "esp" - diff --git a/components/rustlib/src/lib.rs b/components/rustlib/src/lib.rs deleted file mode 100644 index 990e990..0000000 --- a/components/rustlib/src/lib.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(not(version("1.59")), feature(asm))] -#![cfg_attr( - all(version("1.58"), target_arch = "xtensa"), - feature(asm_experimental_arch) -)] -#![feature(cfg_version)] -use core::arch::asm; - -#[cfg(not(feature = "std"))] -use core::panic::PanicInfo; - -#[no_mangle] -pub extern "C" fn add_in_rust(x: i32, y: i32) -> i32 { - x + y -} - -#[no_mangle] -pub extern "C" fn add_in_rust_inline_asm(mut x: i32, y: i32) -> i32 { - unsafe { - // more detail available: https://doc.rust-lang.org/beta/unstable-book/library-features/asm.html - asm!("add {0}, {0}, {1}", inout(reg) x, in(reg) y); - } - x -} - -#[cfg(not(feature = "std"))] -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - loop {} -} diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 8a3ab69..11092b1 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "main.c" +idf_component_register(SRCS "main.cpp" INCLUDE_DIRS "") diff --git a/main/main.c b/main/main.c deleted file mode 100644 index 991a118..0000000 --- a/main/main.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Hello World Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_system.h" -#include "esp_flash.h" -#include "esp_err.h" -#include "esp_idf_version.h" -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) -#include "esp_chip_info.h" -#endif - -#include "RustApi.h" - -void app_main(void) -{ - uint32_t flash_size; - - printf("Hello world!\n"); - - /* Print chip information */ - esp_chip_info_t chip_info; - esp_chip_info(&chip_info); - printf("This is %s chip with %d CPU cores, WiFi%s%s, ", - CONFIG_IDF_TARGET, - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); - - printf("silicon revision %d, ", chip_info.revision); - - ESP_ERROR_CHECK( esp_flash_get_size(NULL, &flash_size) ); - printf("%"PRIu32"MB %s flash\n", flash_size / (1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); - - printf("Free heap: %"PRIu32"\n", esp_get_free_heap_size()); - - int x = 2; - int y = 3; - int sum = add_in_rust(x, y); - printf("Rust calculated %d + %d = %d\n\n", x, y, sum); - - x = 9; - y = 10; - sum = add_in_rust_inline_asm(x, y); - printf("Rust calculated (using asm!) %d + %d = %d\n\n", x, y, sum); - - for (int i = 10; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - printf("Restarting now.\n"); - fflush(stdout); - esp_restart(); -} diff --git a/main/main.cpp b/main/main.cpp new file mode 100644 index 0000000..ad2e797 --- /dev/null +++ b/main/main.cpp @@ -0,0 +1,52 @@ +/* Hello World Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include "esp_err.h" +#include "esp_flash.h" +#include "esp_idf_version.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "sdkconfig.h" +#include +#include +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) +#include "esp_chip_info.h" +#endif + +#include "drone_controller.h" + +extern "C" void app_main(void) { + uint32_t flash_size; + + printf("Hello world!\n"); + + /* Print chip information */ + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + printf("This is %s chip with %d CPU cores, WiFi%s%s, ", CONFIG_IDF_TARGET, + chip_info.cores, (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + + printf("silicon revision %d, ", chip_info.revision); + + ESP_ERROR_CHECK(esp_flash_get_size(NULL, &flash_size)); + printf("%" PRIu32 "MB %s flash\n", flash_size / (1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" + : "external"); + + printf("Free heap: %" PRIu32 "\n", esp_get_free_heap_size()); + + for (int i = 10; i >= 0; i--) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + printf("Restarting now.\n"); + fflush(stdout); + esp_restart(); +}