diff options
| author | zhang san <[email protected]> | 2025-12-08 18:34:25 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-08 18:34:25 +0800 |
| commit | 69980f8b9d29b38dbd4ddf6373b4b45f3a138409 (patch) | |
| tree | 21dd9a8ce80e3d30192e9ffa56ea39a199bae309 /components/rust/core/src/bindings | |
| parent | cd1d47b87c5d47e131730e5506eb3ad77d357653 (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.rs | 76 | ||||
| -rw-r--r-- | components/rust/core/src/bindings/librt.rs | 152 | ||||
| -rw-r--r-- | components/rust/core/src/bindings/mod.rs | 78 |
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 +}; |
