Skip to content

Commit 6e2209e

Browse files
committed
rust: Add a Rust compatible API implementation.
We will gradually add a Rust compatible API implementation conforming to Apache-2. This PR adds an alternative implementation of Common.cpp. Signed-off-by: TOKITA Hiroshi <[email protected]>
1 parent 112d894 commit 6e2209e

File tree

8 files changed

+146
-6
lines changed

8 files changed

+146
-6
lines changed

CMakeLists.txt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,74 @@ if (CONFIG_ARDUINO_API)
1212
zephyr_include_directories(${variant_dir})
1313
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/zephyr/blobs/ArduinoCore-API)
1414

15+
function (rust_target_arch RUST_TARGET)
16+
# Map Zephyr targets to LLVM targets.
17+
if(CONFIG_CPU_CORTEX_M)
18+
if(CONFIG_CPU_CORTEX_M0 OR CONFIG_CPU_CORTEX_M0PLUS OR CONFIG_CPU_CORTEX_M1)
19+
set(${RUST_TARGET} "thumbv6m-none-eabi" PARENT_SCOPE)
20+
elseif(CONFIG_CPU_CORTEX_M3)
21+
set(${RUST_TARGET} "thumbv7m-none-eabi" PARENT_SCOPE)
22+
elseif(CONFIG_CPU_CORTEX_M4 OR CONFIG_CPU_CORTEX_M7)
23+
if(CONFIG_FP_HARDABI OR FORCE_FP_HARDABI)
24+
set(${RUST_TARGET} "thumbv7em-none-eabihf" PARENT_SCOPE)
25+
else()
26+
set(${RUST_TARGET} "thumbv7em-none-eabi" PARENT_SCOPE)
27+
endif()
28+
elseif(CONFIG_CPU_CORTEX_M23)
29+
set(${RUST_TARGET} "thumbv8m.base-none-eabi" PARENT_SCOPE)
30+
elseif(CONFIG_CPU_CORTEX_M33 OR CONFIG_CPU_CORTEX_M55)
31+
# Not a typo, Zephyr, uses ARMV7_M_ARMV8_M_FP to select the FP even on v8m.
32+
if(CONFIG_FP_HARDABI OR FORCE_FP_HARDABI)
33+
set(${RUST_TARGET} "thumbv8m.main-none-eabihf" PARENT_SCOPE)
34+
else()
35+
set(${RUST_TARGET} "thumbv8m.main-none-eabi" PARENT_SCOPE)
36+
endif()
37+
38+
# Todo: The M55 is thumbv8.1m.main-none-eabi, which can be added when Rust
39+
# gain support for this target.
40+
else()
41+
message(FATAL_ERROR "Unknown Cortex-M target.")
42+
endif()
43+
elseif(CONFIG_RISCV)
44+
if(CONFIG_RISCV_ISA_RV64I)
45+
# TODO: Should fail if the extensions don't match.
46+
set(${RUST_TARGET} "riscv64imac-unknown-none-elf" PARENT_SCOPE)
47+
elseif(CONFIG_RISCV_ISA_RV32I)
48+
# TODO: We have multiple choices, try to pick the best.
49+
set(${RUST_TARGET} "riscv32i-unknown-none-elf" PARENT_SCOPE)
50+
else()
51+
message(FATAL_ERROR "Rust: Unsupported riscv ISA")
52+
endif()
53+
elseif(CONFIG_ARCH_POSIX AND CONFIG_64BIT AND (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64"))
54+
set(${RUST_TARGET} "x86_64-unknown-none" PARENT_SCOPE)
55+
elseif(CONFIG_ARCH_POSIX AND CONFIG_64BIT AND (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "aarch64"))
56+
set(${RUST_TARGET} "aarch64-unknown-none" PARENT_SCOPE)
57+
else()
58+
message(FATAL_ERROR "Rust: Add support for other target")
59+
endif()
60+
endfunction()
61+
62+
rust_target_arch(RUST_TARGET_TRIPLE)
63+
64+
set(RUST_CRATE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rust)
65+
set(RUST_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/rust)
66+
set(RUST_LIB ${RUST_OUT_DIR}/target/${RUST_TARGET_TRIPLE}/release/libarduinocore_api_rust.a)
67+
68+
add_custom_command(
69+
OUTPUT ${RUST_LIB}
70+
COMMAND ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${RUST_OUT_DIR}/target
71+
cargo build --manifest-path ${RUST_CRATE_DIR}/Cargo.toml
72+
--target ${RUST_TARGET_TRIPLE} --release
73+
WORKING_DIRECTORY ${RUST_CRATE_DIR}
74+
COMMENT "Building Rust staticlib for ${RUST_TARGET}"
75+
VERBATIM
76+
)
77+
78+
add_custom_target(arduinocore_api_rust_build ALL DEPENDS ${RUST_LIB})
79+
add_library(arduinocore_api_rust STATIC IMPORTED GLOBAL)
80+
set_target_properties(arduinocore_api_rust PROPERTIES IMPORTED_LOCATION ${RUST_LIB})
81+
zephyr_link_libraries(arduinocore_api_rust)
82+
1583
if (CONFIG_CPU_CORTEX_M0PLUS)
1684
set(prebuilt_path ${CMAKE_CURRENT_SOURCE_DIR}/zephyr/blobs/ArduinoCore-API/lib/libarduinocore_api_cortex-m0plus.a)
1785
elseif (CONFIG_CPU_CORTEX_M33)

Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ config ARDUINO_API
1313
imply CBPRINTF_FP_SUPPORT
1414
imply RING_BUFFER
1515
select UART_INTERRUPT_DRIVEN
16+
select RUST
1617
default n
1718

1819
if ARDUINO_API

cores/arduino/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ if(NOT DEFINED ARDUINO_BUILD_PATH)
77
zephyr_sources(zephyrPrint.cpp)
88
zephyr_sources(zephyrSerial.cpp)
99
zephyr_sources(zephyrCommon.cpp)
10+
zephyr_sources(apiCommon.cpp)
1011

1112
if(DEFINED CONFIG_ARDUINO_ENTRY)
1213
zephyr_sources(main.cpp)

cores/arduino/apiCommon.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2025 TOKITA Hiroshi
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <Arduino.h>
8+
#include "zephyrInternal.h"
9+
10+
extern "C" {
11+
int32_t map_i32(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max);
12+
uint16_t makeWord_w(uint16_t w);
13+
uint16_t makeWord_hl(byte h, byte l);
14+
}
15+
16+
long map(long x, long in_min, long in_max, long out_min, long out_max)
17+
{
18+
return map_i32(x, in_min, in_max, out_min, out_max);
19+
}
20+
21+
uint16_t makeWord(uint16_t w) {
22+
return makeWord_w(w);
23+
}
24+
uint16_t makeWord(byte h, byte l) {
25+
return makeWord_hl(h, l);
26+
}

rust/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "arduinocore_api_rust"
3+
version = "0.1.0"
4+
edition = "2024"
5+
license = "Apache-2.0"
6+
7+
[lib]
8+
crate-type = ["staticlib"]

rust/src/common.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2025 TOKITA Hiroshi
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#[unsafe(no_mangle)]
5+
pub extern "C" fn map_i32(
6+
x: i32, in_min: i32, in_max: i32, out_min: i32, out_max: i32
7+
) -> i32 {
8+
let num = x.wrapping_sub(in_min).wrapping_mul(out_max.wrapping_sub(out_min));
9+
let den = in_max.wrapping_sub(in_min);
10+
// Note: To keep compatibility, the panic when den=0 is left as is.
11+
num / den.wrapping_add(out_min)
12+
}
13+
14+
#[unsafe(no_mangle)]
15+
pub extern "C" fn makeWord_w(w: u16) -> u16 {
16+
w
17+
}
18+
19+
#[unsafe(no_mangle)]
20+
pub extern "C" fn makeWord_hl(h: u8, l: u8) -> u16 {
21+
((h as u16) << 8) | (l as u16)
22+
}

rust/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2025 TOKITA Hiroshi
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![no_std]
5+
6+
mod common;
7+
pub use common::*;
8+
9+
use core::panic::PanicInfo;
10+
11+
#[panic_handler]
12+
fn panic(_panic: &PanicInfo<'_>) -> ! {
13+
loop {}
14+
}

zephyr/module.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -303,26 +303,26 @@ blobs:
303303
description: "Arduino Core API Header"
304304
doc-url: https://raw.githubusercontent.com/arduino/ArduinoCore-API/refs/tags/1.5.2/README.md
305305
- path: ArduinoCore-API/lib/libarduinocore_api_cortex-m0plus.a
306-
sha256: acc49f1bb045e1b504e320fb8e539380b9da391e621c0d8cd91a472582f4ecea
306+
sha256: 5e84a0df6243beb811b02bf11dc739c91be80ba40b1cf7a309b233bb9d413997
307307
type: img
308308
version: '1.5.2'
309309
license-path: blobs/ArduinoCore-API/LICENSE.txt
310-
url: https://github.com/soburi/arduinocore-api-builder/releases/download/1.5.2-zephyr0/libarduinocore_api_cortex-m0plus.a
310+
url: https://github.com/soburi/arduinocore-api-builder/releases/download/1.5.2-zephyr1/libarduinocore_api_cortex-m0plus.a
311311
description: "Arduino Core API Prebuilt libarary"
312312
doc-url: https://raw.githubusercontent.com/arduino/ArduinoCore-API/refs/tags/1.5.2/README.md
313313
- path: ArduinoCore-API/lib/libarduinocore_api_cortex-m33.a
314-
sha256: 0858e8ea1c14c3ca8254c9624ed09992c4d66fe928b985cb35ea20723d1110bf
314+
sha256: 6dda5a06953d7b27dd8af35ff918e01cfb25fb05c667e4eef8c2661d897f47b6
315315
type: img
316316
version: '1.5.2'
317317
license-path: blobs/ArduinoCore-API/LICENSE.txt
318-
url: https://github.com/soburi/arduinocore-api-builder/releases/download/1.5.2-zephyr0/libarduinocore_api_cortex-m33.a
318+
url: https://github.com/soburi/arduinocore-api-builder/releases/download/1.5.2-zephyr1/libarduinocore_api_cortex-m33.a
319319
description: "Arduino Core API Prebuilt libarary"
320320
doc-url: https://raw.githubusercontent.com/arduino/ArduinoCore-API/refs/tags/1.5.2/README.md
321321
- path: ArduinoCore-API/lib/libarduinocore_api_cortex-m4.a
322-
sha256: da840b81c145b11f39b0997a7b33d3933f840a3a426f0823fdd267f4690e2311
322+
sha256: 4e0e4d973ca9666616424571384f247db5d88d82337f8db96b20c9f018a215fb
323323
type: img
324324
version: '1.5.2'
325325
license-path: blobs/ArduinoCore-API/LICENSE.txt
326-
url: https://github.com/soburi/arduinocore-api-builder/releases/download/1.5.2-zephyr0/libarduinocore_api_cortex-m4.a
326+
url: https://github.com/soburi/arduinocore-api-builder/releases/download/1.5.2-zephyr1/libarduinocore_api_cortex-m4.a
327327
description: "Arduino Core API Prebuilt libarary"
328328
doc-url: https://raw.githubusercontent.com/arduino/ArduinoCore-API/refs/tags/1.5.2/README.md

0 commit comments

Comments
 (0)