summaryrefslogtreecommitdiff
path: root/components/rust/core/src/bindings
diff options
context:
space:
mode:
authorzhang san <[email protected]>2025-12-08 18:34:25 +0800
committerGitHub <[email protected]>2025-12-08 18:34:25 +0800
commit69980f8b9d29b38dbd4ddf6373b4b45f3a138409 (patch)
tree21dd9a8ce80e3d30192e9ffa56ea39a199bae309 /components/rust/core/src/bindings
parentcd1d47b87c5d47e131730e5506eb3ad77d357653 (diff)
Adding Rust Language Support for RT-Thread #10910
Diffstat (limited to 'components/rust/core/src/bindings')
-rw-r--r--components/rust/core/src/bindings/libc.rs76
-rw-r--r--components/rust/core/src/bindings/librt.rs152
-rw-r--r--components/rust/core/src/bindings/mod.rs78
3 files changed, 306 insertions, 0 deletions
diff --git a/components/rust/core/src/bindings/libc.rs b/components/rust/core/src/bindings/libc.rs
new file mode 100644
index 0000000000..51efc78b35
--- /dev/null
+++ b/components/rust/core/src/bindings/libc.rs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author foxglove
+ * 2025-09-15 foxglove 1.0 version
+ * 2025-09-23 foxglove 1.1 version, add libdl bindings
+ */
+
+/*! C standard library API bindings
+
+Provides Rust wrappers for standard C library functions
+*/
+
+#![allow(non_camel_case_types)]
+
+pub use core::ffi::{c_char, c_int, c_void, c_long, c_ulong};
+
+pub const RTLD_LAZY: c_int = 0x00000; /* Lazy function call binding */
+pub const RTLD_NOW: c_int = 0x00001; /* Immediate function call binding */
+pub const RTLD_GLOBAL: c_int = 0x10000; /* Make symbols globally available */
+pub const RTLD_LOCAL: c_int = 0x00000; /* Default local */
+pub const O_RDONLY: c_int = 0x0000; /* open for reading only */
+pub const O_WRONLY: c_int = 0x0001; /* open for writing only */
+pub const O_RDWR: c_int = 0x0002; /* open for reading and writing */
+pub const O_APPEND: c_int = 0x0008; /* writes done at eof */
+pub const O_CREAT: c_int = 0x0100; /* create and open file */
+pub const O_TRUNC: c_int = 0x0200; /* open and truncate */
+pub const O_EXCL: c_int = 0x0400; /* open only if file doesn't already exist */
+pub type size_t = c_ulong;
+pub type ssize_t = c_long;
+pub type off_t = c_long;
+pub const SEEK_SET: c_int = 0;
+pub const SEEK_CUR: c_int = 1;
+pub const SEEK_END: c_int = 2;
+/* ============== time functions ============== */
+pub type time_t = c_long;
+pub type suseconds_t = c_int;
+#[repr(C)]
+pub struct timeval {
+ pub tv_sec: time_t,
+ pub tv_usec: suseconds_t,
+}
+
+/* ============== libdl functions ============== */
+unsafe extern "C" {
+ pub fn dlopen(filename: *const c_char, flag: c_int) -> *mut c_void;
+ pub fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;
+ pub fn dlclose(handle: *mut c_void) -> c_int;
+ pub fn dlerror() -> *const c_char;
+}
+unsafe extern "C" {
+ pub fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
+ pub fn close(fd: c_int) -> c_int;
+ pub fn read(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t;
+ pub fn write(fd: c_int, buf: *const c_void, count: size_t) -> ssize_t;
+ pub fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t;
+ pub fn fsync(fd: c_int) -> c_int;
+ pub fn ftruncate(fd: c_int, length: off_t) -> c_int;
+}
+
+/* ============== time functions ============== */
+unsafe extern "C" {
+ /* Use local types instead of crate-root paths to avoid E0412 */
+ pub fn gettimeofday(tp: *mut timeval, tz: *mut c_void) -> c_int;
+}
+
+/* Helper: get last libdl error C-string pointer
+ * Safe wrapper around `dlerror()` returning the raw pointer for printing.
+ */
+#[inline]
+pub fn last_error_ptr() -> *const c_char {
+ unsafe { dlerror() }
+}
diff --git a/components/rust/core/src/bindings/librt.rs b/components/rust/core/src/bindings/librt.rs
new file mode 100644
index 0000000000..3f16c014fd
--- /dev/null
+++ b/components/rust/core/src/bindings/librt.rs
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author foxglove
+ * 2025-09-15 foxglove 1.0 version
+ */
+
+/*! RT-Thread OS API bindings
+
+Provides Rust wrappers for RT-Thread kernel and device driver APIs
+*/
+
+#![allow(non_camel_case_types)]
+
+use core::ffi::{c_char, c_int, c_uint, c_void, c_long, c_ulong, c_uchar};
+
+/* RT-Thread basic type definitions */
+pub type rt_base_t = c_long;
+pub type rt_ubase_t = c_ulong;
+pub type rt_err_t = rt_base_t;
+pub type rt_uint32_t = c_uint;
+pub type rt_int32_t = c_int;
+pub type rt_uint8_t = c_uchar;
+pub type rt_tick_t = rt_uint32_t;
+pub type rt_size_t = rt_ubase_t;
+
+pub type rt_thread_t = *mut c_void;
+pub type rt_sem_t = *mut c_void;
+pub type rt_mutex_t = *mut c_void;
+pub type rt_device_t = *mut c_void;
+pub type rt_mq_t = *mut c_void;
+
+/* RT-Thread error codes */
+pub const RT_EOK: rt_err_t = 0;
+pub const RT_ERROR: rt_err_t = 1;
+pub const RT_ETIMEOUT: rt_err_t = 2;
+pub const RT_EFULL: rt_err_t = 3;
+pub const RT_EEMPTY: rt_err_t = 4;
+pub const RT_ENOMEM: rt_err_t = 5;
+pub const RT_ENOSYS: rt_err_t = 6;
+pub const RT_EBUSY: rt_err_t = 7;
+pub const RT_EIO: rt_err_t = 8;
+pub const RT_EINTR: rt_err_t = 9;
+pub const RT_EINVAL: rt_err_t = 10;
+
+/* ============== Kernel object management ============== */
+unsafe extern "C" {
+ pub fn rt_object_get_type(object: *mut c_void) -> u8;
+ pub fn rt_object_find(name: *const c_char, object_type: u8) -> *mut c_void;
+}
+
+/* ============== Thread management ============== */
+unsafe extern "C" {
+ pub fn rt_thread_create(
+ name: *const c_char,
+ entry: extern "C" fn(*mut c_void),
+ parameter: *mut c_void,
+ stack_size: rt_size_t,
+ priority: rt_uint8_t,
+ tick: rt_tick_t,
+ ) -> rt_thread_t;
+
+ pub fn rt_thread_delete(thread: rt_thread_t) -> rt_err_t;
+ pub fn rt_thread_startup(thread: rt_thread_t) -> rt_err_t;
+ pub fn rt_thread_self() -> rt_thread_t;
+ pub fn rt_thread_yield() -> rt_err_t;
+ pub fn rt_thread_delay(tick: rt_tick_t) -> rt_err_t;
+ pub fn rt_thread_mdelay(ms: rt_uint32_t) -> rt_err_t;
+ pub fn rt_thread_suspend(thread: rt_thread_t) -> rt_err_t;
+ pub fn rt_thread_resume(thread: rt_thread_t) -> rt_err_t;
+}
+
+/* ============== Semaphore management ============== */
+unsafe extern "C" {
+ pub fn rt_sem_create(name: *const c_char, value: rt_uint32_t, flag: rt_uint8_t) -> rt_sem_t;
+ pub fn rt_sem_delete(sem: rt_sem_t) -> rt_err_t;
+ pub fn rt_sem_take(sem: rt_sem_t, time: rt_tick_t) -> rt_err_t;
+ pub fn rt_sem_trytake(sem: rt_sem_t) -> rt_err_t;
+ pub fn rt_sem_release(sem: rt_sem_t) -> rt_err_t;
+}
+
+/* ============== Mutex management ============== */
+unsafe extern "C" {
+ pub fn rt_mutex_create(name: *const c_char, flag: rt_uint8_t) -> rt_mutex_t;
+ pub fn rt_mutex_delete(mutex: rt_mutex_t) -> rt_err_t;
+ pub fn rt_mutex_take(mutex: rt_mutex_t, time: rt_tick_t) -> rt_err_t;
+ pub fn rt_mutex_release(mutex: rt_mutex_t) -> rt_err_t;
+}
+/* ============== Message queue management ============== */
+unsafe extern "C" {
+ pub fn rt_mq_create(name: *const c_char, msg_size: rt_size_t, max_msgs: rt_size_t, flag: rt_uint8_t) -> rt_mq_t;
+ pub fn rt_mq_send(mq: rt_mq_t, buffer: *const c_void, size: rt_size_t) -> rt_err_t;
+ pub fn rt_mq_send_wait(mq: rt_mq_t, buffer: *const c_void, size: rt_size_t, timeout: rt_int32_t) -> rt_err_t;
+ pub fn rt_mq_recv(mq: rt_mq_t, buffer: *mut c_void, size: rt_size_t, timeout: rt_int32_t) -> rt_base_t;
+ pub fn rt_mq_delete(mq: rt_mq_t) -> rt_err_t;
+ pub fn rt_mq_detach(mq: rt_mq_t) -> rt_err_t;
+}
+/* ============== Memory management ============== */
+unsafe extern "C" {
+ pub fn rt_malloc(size: rt_size_t) -> *mut c_void;
+ pub fn rt_free(ptr: *mut c_void);
+ pub fn rt_realloc(ptr: *mut c_void, newsize: rt_size_t) -> *mut c_void;
+ pub fn rt_calloc(count: rt_size_t, size: rt_size_t) -> *mut c_void;
+ pub fn rt_malloc_align(size: rt_size_t, align: rt_size_t) -> *mut c_void;
+ pub fn rt_free_align(ptr: *mut c_void);
+}
+
+/* ============== Device management ============== */
+unsafe extern "C" {
+ pub fn rt_device_find(name: *const c_char) -> rt_device_t;
+ pub fn rt_device_open(dev: rt_device_t, oflag: u16) -> rt_err_t;
+ pub fn rt_device_close(dev: rt_device_t) -> rt_err_t;
+ pub fn rt_device_read(
+ dev: rt_device_t,
+ pos: c_ulong,
+ buffer: *mut c_void,
+ size: rt_size_t,
+ ) -> rt_size_t;
+ pub fn rt_device_write(
+ dev: rt_device_t,
+ pos: c_ulong,
+ buffer: *const c_void,
+ size: rt_size_t,
+ ) -> rt_size_t;
+ pub fn rt_device_control(dev: rt_device_t, cmd: c_int, arg: *mut c_void) -> rt_err_t;
+}
+
+/* ============== System tick ============== */
+unsafe extern "C" {
+ pub fn rt_tick_get() -> rt_tick_t;
+ pub fn rt_tick_from_millisecond(ms: c_int) -> rt_tick_t;
+}
+
+/* ============== Debug output ============== */
+unsafe extern "C" {
+ pub fn rt_kprintf(fmt: *const u8, ...) -> c_int;
+ pub fn rt_kputs(str: *const u8) -> c_int;
+}
+
+/* ============== Interrupt management ============== */
+unsafe extern "C" {
+ pub fn rt_hw_interrupt_disable() -> rt_base_t;
+ pub fn rt_hw_interrupt_enable(level: rt_base_t);
+ pub fn rt_cpus_lock() -> rt_base_t;
+ pub fn rt_cpus_unlock(level: rt_base_t);
+ pub fn rt_interrupt_enter();
+ pub fn rt_interrupt_leave();
+ pub fn rt_interrupt_get_nest() -> u8;
+}
diff --git a/components/rust/core/src/bindings/mod.rs b/components/rust/core/src/bindings/mod.rs
new file mode 100644
index 0000000000..ae2610e9c8
--- /dev/null
+++ b/components/rust/core/src/bindings/mod.rs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author notes
+ * 2025-10-10 foxglove Bindings module
+ */
+pub mod libc;
+pub mod librt;
+
+/* Explicitly re-export only the needed items from librt to avoid namespace pollution. */
+/* Basic RT-Thread types */
+pub use librt::{
+ rt_base_t, rt_ubase_t, rt_err_t, rt_uint32_t, rt_int32_t, rt_uint8_t,
+ rt_tick_t, rt_size_t, rt_thread_t, rt_sem_t, rt_mutex_t, rt_device_t, rt_mq_t
+};
+
+/* RT-Thread error codes */
+pub use librt::{
+ RT_EOK, RT_ERROR, RT_ETIMEOUT, RT_EFULL, RT_EEMPTY, RT_ENOMEM,
+ RT_ENOSYS, RT_EBUSY, RT_EIO, RT_EINTR, RT_EINVAL
+};
+
+/* Thread management functions */
+pub use librt::{
+ rt_thread_create, rt_thread_delete, rt_thread_startup, rt_thread_self,
+ rt_thread_yield, rt_thread_delay, rt_thread_mdelay, rt_thread_suspend, rt_thread_resume
+};
+
+/* Semaphore management functions */
+pub use librt::{
+ rt_sem_create, rt_sem_delete, rt_sem_take, rt_sem_trytake, rt_sem_release
+};
+
+/* Mutex management functions */
+pub use librt::{
+ rt_mutex_create, rt_mutex_delete, rt_mutex_take, rt_mutex_release
+};
+
+/* Message queue management functions */
+pub use librt::{
+ rt_mq_create, rt_mq_send, rt_mq_send_wait, rt_mq_recv, rt_mq_delete, rt_mq_detach
+};
+
+/* Memory management functions */
+pub use librt::{
+ rt_malloc, rt_free, rt_realloc, rt_calloc, rt_malloc_align, rt_free_align,
+ rt_safe_malloc, rt_safe_free
+};
+
+/* Device management functions */
+pub use librt::{
+ rt_device_find, rt_device_open, rt_device_close, rt_device_read,
+ rt_device_write, rt_device_control
+};
+
+/* System tick functions */
+pub use librt::{
+ rt_tick_get, rt_tick_from_millisecond
+};
+
+/* Debug output functions */
+pub use librt::{
+ rt_kprintf, rt_kputs
+};
+
+/* Interrupt management functions */
+pub use librt::{
+ rt_hw_interrupt_disable, rt_hw_interrupt_enable, rt_cpus_lock, rt_cpus_unlock,
+ rt_interrupt_enter, rt_interrupt_leave, rt_interrupt_get_nest
+};
+
+/* Object management functions */
+pub use librt::{
+ rt_object_get_type, rt_object_find
+};