diff --git a/examples/c-examples/ex/.gitignore b/examples/c-examples/ex/.gitignore new file mode 100644 index 0000000..3d22ed9 --- /dev/null +++ b/examples/c-examples/ex/.gitignore @@ -0,0 +1,5 @@ +/.vscode +/.embuild +build/ +components/*/target/ +Cargo.lock diff --git a/examples/c-examples/ex/CMakeLists.txt b/examples/c-examples/ex/CMakeLists.txt new file mode 100644 index 0000000..c3e70dd --- /dev/null +++ b/examples/c-examples/ex/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ex) diff --git a/examples/c-examples/ex/components/rust_ex/CMakeLists.txt b/examples/c-examples/ex/components/rust_ex/CMakeLists.txt new file mode 100644 index 0000000..77b8913 --- /dev/null +++ b/examples/c-examples/ex/components/rust_ex/CMakeLists.txt @@ -0,0 +1,81 @@ +# If this component depends on other components - be it ESP-IDF or project-specific ones - enumerate those in the double-quotes below, separated by spaces +# Note that pthread should always be there, or else STD will not work +set(RUST_DEPS "pthread" "driver" "vfs") +# Here's a non-minimal, reasonable set of ESP-IDF components that one might want enabled for Rust: +#set(RUST_DEPS "pthread" "esp_http_client" "esp_http_server" "espcoredump" "app_update" "esp_serial_slave_link" "nvs_flash" "spi_flash" "esp_adc_cal" "mqtt") + +idf_component_register( + SRCS "placeholder.c" + INCLUDE_DIRS "" + PRIV_REQUIRES "${RUST_DEPS}" +) + +if(CONFIG_IDF_TARGET_ARCH_RISCV) + if (CONFIG_IDF_TARGET_ESP32C6 OR CONFIG_IDF_TARGET_ESP32C5 OR CONFIG_IDF_TARGET_ESP32H2) + set(RUST_TARGET "riscv32imac-esp-espidf") + else () + set(RUST_TARGET "riscv32imc-esp-espidf") + endif() +elseif(CONFIG_IDF_TARGET_ESP32) + set(RUST_TARGET "xtensa-esp32-espidf") +elseif(CONFIG_IDF_TARGET_ESP32S2) + set(RUST_TARGET "xtensa-esp32s2-espidf") +elseif(CONFIG_IDF_TARGET_ESP32S3) + set(RUST_TARGET "xtensa-esp32s3-espidf") +else() + message(FATAL_ERROR "Unsupported target ${CONFIG_IDF_TARGET}") +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CARGO_BUILD_TYPE "debug") + set(CARGO_BUILD_ARG "") +else() + set(CARGO_BUILD_TYPE "release") + set(CARGO_BUILD_ARG "--release") +endif() + +set(CARGO_BUILD_STD_ARG -Zbuild-std=std,panic_abort) + +if(IDF_VERSION_MAJOR GREATER "4") +set(ESP_RUSTFLAGS "--cfg espidf_time64") +endif() + +set(CARGO_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}") +set(CARGO_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}") +set(CARGO_TARGET_DIR "${CARGO_BUILD_DIR}/target") + +set(RUST_INCLUDE_DIR "${CARGO_TARGET_DIR}") +# if this component uses CBindGen to generate a C header, uncomment the lines below and adjust the header name accordingly +#set(RUST_INCLUDE_HEADER "${RUST_INCLUDE_DIR}/RustApi.h") +#set_source_files_properties("${RUST_INCLUDE_HEADER}" PROPERTIES GENERATED true) + +idf_build_get_property(sdkconfig SDKCONFIG) +idf_build_get_property(idf_path IDF_PATH) + +ExternalProject_Add( + project_rust_ex + PREFIX "${CARGO_PROJECT_DIR}" + DOWNLOAD_COMMAND "" + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env + cargo clean --target ${RUST_TARGET} --target-dir ${CARGO_TARGET_DIR} + USES_TERMINAL_BUILD true + BUILD_COMMAND ${CMAKE_COMMAND} -E env + CARGO_CMAKE_BUILD_INCLUDES=$ + CARGO_CMAKE_BUILD_LINK_LIBRARIES=$ + CARGO_CMAKE_BUILD_SDKCONFIG=${sdkconfig} + CARGO_CMAKE_BUILD_ESP_IDF=${idf_path} + CARGO_CMAKE_BUILD_COMPILER=${CMAKE_C_COMPILER} + RUSTFLAGS=${ESP_RUSTFLAGS} + MCU=${CONFIG_IDF_TARGET} + cargo build --target ${RUST_TARGET} --target-dir ${CARGO_TARGET_DIR} ${CARGO_BUILD_ARG} ${CARGO_BUILD_STD_ARG} + INSTALL_COMMAND "" + BUILD_ALWAYS TRUE + TMP_DIR "${CARGO_BUILD_DIR}/tmp" + STAMP_DIR "${CARGO_BUILD_DIR}/stamp" + DOWNLOAD_DIR "${CARGO_BUILD_DIR}" + SOURCE_DIR "${CARGO_PROJECT_DIR}" + BINARY_DIR "${CARGO_PROJECT_DIR}" + INSTALL_DIR "${CARGO_BUILD_DIR}" + BUILD_BYPRODUCTS + "${RUST_INCLUDE_HEADER}" +) diff --git a/examples/c-examples/ex/components/rust_ex/Cargo.toml b/examples/c-examples/ex/components/rust_ex/Cargo.toml new file mode 100644 index 0000000..4220b43 --- /dev/null +++ b/examples/c-examples/ex/components/rust_ex/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "rust_ex" +version = "0.1.0" +authors = ["Artem-Nesterenko2005 "] +edition = "2021" +resolver = "2" +rust-version = "1.77" + +[lib] +crate-type = ["staticlib"] +harness = false # do not use the built in cargo test harness -> resolve rust-analyzer errors + + +[profile.release] +opt-level = "s" + +[profile.dev] +debug = true # Symbols are nice and they don't increase the size on Flash +opt-level = "z" + +[features] +default = [] +experimental = ["esp-idf-svc/experimental"] + +[dependencies] +log = "0.4" +esp-idf-svc = { version = "0.49", default-features = false, features = [] } +martos = { version = "0.4.0", path = "../../../../..", features = ["c-library"] } + +[build-dependencies] +embuild = "0.32.0" diff --git a/examples/c-examples/ex/components/rust_ex/build.rs b/examples/c-examples/ex/components/rust_ex/build.rs new file mode 100644 index 0000000..c9f898e --- /dev/null +++ b/examples/c-examples/ex/components/rust_ex/build.rs @@ -0,0 +1,3 @@ +fn main() { + embuild::espidf::sysenv::output(); +} \ No newline at end of file diff --git a/examples/c-examples/ex/components/rust_ex/placeholder.c b/examples/c-examples/ex/components/rust_ex/placeholder.c new file mode 100644 index 0000000..f0e7e01 --- /dev/null +++ b/examples/c-examples/ex/components/rust_ex/placeholder.c @@ -0,0 +1,13 @@ +/* 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. +*/ diff --git a/examples/c-examples/ex/components/rust_ex/rust-toolchain.toml b/examples/c-examples/ex/components/rust_ex/rust-toolchain.toml new file mode 100644 index 0000000..a2f5ab5 --- /dev/null +++ b/examples/c-examples/ex/components/rust_ex/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "esp" diff --git a/examples/c-examples/ex/components/rust_ex/src/lib.rs b/examples/c-examples/ex/components/rust_ex/src/lib.rs new file mode 100644 index 0000000..31861eb --- /dev/null +++ b/examples/c-examples/ex/components/rust_ex/src/lib.rs @@ -0,0 +1,11 @@ +#[no_mangle] +pub extern "C" fn start_task_manager() +{ + martos::c_api::start_task_manager(); +} + +#[no_mangle] +pub extern "C" fn init_system() +{ + martos::init_system(); +} \ No newline at end of file diff --git a/examples/c-examples/ex/diagram.json b/examples/c-examples/ex/diagram.json new file mode 100644 index 0000000..ae36479 --- /dev/null +++ b/examples/c-examples/ex/diagram.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "author": "Artem-Nesterenko2005 ", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-devkit-c-v4", + "id": "esp", + "top": 0, + "left": 0, + "attrs": { + "flashSize": "16" + } + } + ], + "connections": [ + [ + "esp:TX", + "$serialMonitor:RX", + "", + [] + ], + [ + "esp:RX", + "$serialMonitor:TX", + "", + [] + ] + ], + "serialMonitor": { + "display": "terminal", + "convertEol": true + }, + "dependencies": {} +} diff --git a/examples/c-examples/ex/main/CMakeLists.txt b/examples/c-examples/ex/main/CMakeLists.txt index dbc514e..9ae694a 100644 --- a/examples/c-examples/ex/main/CMakeLists.txt +++ b/examples/c-examples/ex/main/CMakeLists.txt @@ -1,6 +1,3 @@ idf_component_register(SRCS "main.c" #INCLUDE_DIRS #"${CMAKE_CURRENT_LIST_DIR}/../rust-ex/src" -REQUIRES rust-ex) - -#target_link_options(${COMPONENT_LIB} PUBLIC -#-Wl,--whole-archive ${CARGO_TARGET_DIR}/librust_ex.a -Wl,--no-whole-archive) \ No newline at end of file +REQUIRES rust_ex) \ No newline at end of file diff --git a/examples/c-examples/ex/main/main.c b/examples/c-examples/ex/main/main.c index 9b781cf..3972799 100644 --- a/examples/c-examples/ex/main/main.c +++ b/examples/c-examples/ex/main/main.c @@ -1,10 +1,9 @@ #include -//#include "rust_lib.h" -extern void init_system(void); -extern void start_task_manager(); +//extern void init_system(void); +//extern void start_task_manager(); void app_main(void) { - init_system(); - start_task_manager(); + //init_system(); + //start_task_manager(); printf("Hello world from C!\n"); } \ No newline at end of file diff --git a/examples/c-examples/ex/sdkconfig.defaults b/examples/c-examples/ex/sdkconfig.defaults new file mode 100644 index 0000000..f19c694 --- /dev/null +++ b/examples/c-examples/ex/sdkconfig.defaults @@ -0,0 +1,6 @@ +# Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 + +# Workaround for https://github.com/espressif/esp-idf/issues/7631 +#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n diff --git a/examples/c-examples/ex/wokwi.toml b/examples/c-examples/ex/wokwi.toml new file mode 100644 index 0000000..ea7164b --- /dev/null +++ b/examples/c-examples/ex/wokwi.toml @@ -0,0 +1,4 @@ +[wokwi] +version = 1 +firmware = 'build/flasher_args.json' +elf = 'build/ex.elf'