# messages-handler-rust **Repository Path**: why100/messages-handler-rust ## Basic Information - **Project Name**: messages-handler-rust - **Description**: messages handler rust - **Primary Language**: Rust - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-23 - **Last Updated**: 2026-04-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Message Handler Rust 工程 类似 Android Handler/Looper 的消息处理机制,纯 Rust 实现,支持 no_std 环境,适用于 RTOS/嵌入式。 ## 目录结构 ``` message_handler_rust/ ├── Cargo.toml # Workspace 配置 ├── msghandler/ # 库 crate │ ├── Cargo.toml │ ├── src/ │ │ ├── lib.rs # 库入口 │ │ ├── message.rs # Message 结构 │ │ ├── handler.rs # Handler 实现 │ │ ├── looper.rs # Looper 实现 │ │ ├── message_queue.rs │ │ ├── message_pool.rs │ │ ├── handler_thread.rs │ │ ├── thread_local.rs │ │ └── os/ # OS 抽象层 │ │ ├── mod.rs │ │ ├── traits.rs │ │ ├── std_impl.rs │ │ ├── freertos_impl.rs │ │ ├── rtthread_impl.rs │ │ └── no_std_impl.rs │ └── tests/ │ ├── test_basic.rs │ └── test_multi_handler.rs └── demo/ # Demo 程序 ├── Cargo.toml └── src/main.rs ``` --- ## 快速开始 ### 1. 构建库 ```bash # 标准库版本 cargo build -p msghandler --features use-std # Release 版本 cargo build -p msghandler --features use-std --release ``` ### 2. 运行测试 ```bash # 运行所有测试 cargo test -p msghandler --features use-std # 显示测试输出 cargo test -p msghandler --features use-std -- --nocapture # 运行特定测试文件 cargo test -p msghandler --features use-std --test test_basic cargo test -p msghandler --features use-std --test test_multi_handler ``` ### 3. 运行 Demo ```bash cargo run -p message-handler-demo ``` --- ## 编译方法 ### Feature 配置 | Feature | 说明 | |---------|------| | `use-std` | 标准库模式,用于 Linux/macOS 测试 | | `no-std` | 无标准库模式(通用实现) | | `rtos-freertos` | FreeRTOS 适配(ARM 交叉编译) | | `rtos-rtthread` | RT-Thread 适配(ARM 交叉编译) | ### OS 实现编译机制 通过 Cargo feature 控制不同 OS 实现编译进库,使用条件编译 `#![cfg(feature = "...")]`: ```rust // os/mod.rs #[cfg(feature = "use-std")] mod std_impl; // 编译 std 实现 #[cfg(feature = "rtos-freertos")] mod freertos_impl; // 编译 FreeRTOS 实现 #[cfg(feature = "rtos-rtthread")] mod rtthread_impl; // 编译 RT-Thread 实现 // 默认(无 feature):编译通用 no_std 实现 #[cfg(all(not(feature = "use-std"), not(feature = "rtos-freertos"), not(feature = "rtos-rtthread")))] mod no_std_impl; ``` **编译选择规则**: - `use-std` → std_impl(使用 Rust 标准库线程) - `rtos-freertos` → freertos_impl(使用 FreeRTOS xTaskCreate) - `rtos-rtthread` → rtthread_impl(使用 RT-Thread rt_thread_create) - 无上述 feature → no_std_impl(空实现,需要外部提供线程) ### 编译命令 **注意**: RTOS 版本(rtos-freertos, rtos-rtthread)需要 ARM 交叉编译工具链。 #### 1. 标准库版本(用于测试/开发) ```bash # 调试版本 cargo build -p msghandler --features use-std # 发布版本 cargo build -p msghandler --features use-std --release ``` #### 2. FreeRTOS 版本(ARM 交叉编译) ```bash # 需要先安装 target: rustup target add thumbv7em-none-eabihf # 调试版本 cargo build -p msghandler --target thumbv7em-none-eabihf --no-default-features --features rtos-freertos # 发布版本 cargo build -p msghandler --target thumbv7em-none-eabihf --no-default-features --features rtos-freertos --release ``` #### 3. RT-Thread 版本(ARM 交叉编译) ```bash # 调试版本 cargo build -p msghandler --target thumbv7em-none-eabihf --no-default-features --features rtos-rtthread # 发布版本 cargo build -p msghandler --target thumbv7em-none-eabihf --no-default-features --features rtos-rtthread --release ``` #### 4. 运行 Demo ```bash cargo run -p message-handler-demo ``` ### 安装 ARM 交叉编译工具链 ```bash # 添加 ARM Cortex-M target rustup target add thumbv7em-none-eabihf # 如果需要链接器(调试版本需要) # 方式1: 使用 xtools(macOS) brew install --cask gcc-arm-embedded # 方式2: 使用 arm-none-eabi-gcc(Linux) sudo apt install gcc-arm-none-eabi ``` --- ## Rust API ### HandlerThread(类似 Android HandlerThread) ```rust use msghandler::{HandlerThread, Handler, Message}; // 创建 HandlerThread let thread = HandlerThread::new("MyThread", true); // 启动后台线程 unsafe { (&mut *thread).start() }; // 创建带回调的 Handler let handler = unsafe { (&mut *thread).create_handler(|msg| { let what = unsafe { (*msg).what }; let arg1 = unsafe { (*msg).arg1 }; println!("Received: what={}, arg1={}", what, arg1); }) }; // 发送消息 let msg = Message::new(100); unsafe { (*msg).arg1 = 42; } unsafe { (*handler).send_message(msg); } // 退出线程 unsafe { (&mut *thread).quit() }; ``` ### Message ```rust // 创建消息 let msg = Message::new(what: i32) -> *mut Message // 回收消息 msg.recycle(); // 发送消息 handler.send_message(msg); // 延迟发送(毫秒) handler.send_message_delay(msg, delay_ms: u64); ``` ### Handler ```rust // 创建 Handler(使用 Rust 闭包) let handler = Handler::new(looper, |msg| { // 处理消息 }); // 发送消息 handler.send_message(msg); handler.send_empty_message(what: i32); handler.send_message_delay(msg, delay_ms: u64); // 获取关联的 Looper handler.get_looper() -> *mut Looper; ``` ### Looper ```rust // 创建 Looper let looper = Looper::new(quit_allowed: bool) -> *mut Looper; // 获取/设置队列 looper.get_queue() -> *mut MessageQueue; looper.set_queue(queue: *mut MessageQueue); // 退出控制 looper.is_quit_allowed() -> bool; looper.is_quitting() -> bool; looper.set_quitting(quitting: bool); ``` ### MessageQueue ```rust // 创建队列 let queue = MessageQueue::new() -> *mut MessageQueue; // 入队/出队 queue.enqueue_message(msg: *mut Message); queue.next(timeout_ms: u64) -> *mut Message; // 非阻塞 // 查询 queue.is_empty() -> bool; queue.size() -> usize; ``` ### MessagePool ```rust // 创建消息池 let pool = MessagePool::new(max_size: usize) -> *mut MessagePool; // 获取/回收消息 pool.obtain(what: i32) -> *mut Message; pool.recycle(msg: *mut Message); // 查询 pool.available() -> usize; pool.size() -> usize; ``` --- ## Demo 程序说明 Demo 位于 `demo/src/main.rs`,演示了 Message Handler 库的 5 种典型用法: ### Demo 1: 基本消息发送接收 演示创建 Looper、MessageQueue、MessagePool 和 Handler,通过 Handler 发送消息并处理。 ```rust // 创建组件 let looper = Looper::new(true); let queue = MessageQueue::new(); let pool = MessagePool::new(10); unsafe { (*looper).set_queue(queue); } // 创建 Handler(带闭包回调) let handler = Handler::new(looper, |msg| { unsafe { println!("[Callback] what={}, arg1={}, arg2={}", (*msg).what, (*msg).arg1, (*msg).arg2); } }); // 发送消息 let msg = unsafe { (*pool).obtain(1) }; // what = 1 unsafe { (*msg).arg1 = 10; (*msg).arg2 = 100; (*msg).target = handler as *mut c_void; (*queue).enqueue_message(msg); } // 消费消息 let msg = unsafe { (*queue).next(100) }; // 100ms 超时 if !msg.is_null() { let target = unsafe { (*msg).target }; let h = unsafe { &*(target as *mut Handler) }; h.dispatch(msg); // 调用回调 unsafe { (*pool).recycle(msg) }; // 回收 } ``` **运行输出**: ``` === Demo 1: Basic Messaging === Sending 3 messages... Sent: what=1, arg1=10, arg2=100 Processing messages... [Callback] Message: what=1, arg1=10, arg2=100 Processed 1 messages ``` ### Demo 2: 消息池复用 演示 MessagePool 的 `obtain()` 和 `recycle()` 如何实现消息复用,避免频繁分配内存。 ```rust let pool = MessagePool::new(5); // 最多 5 条消息 // 获取消息 let msg1 = unsafe { (*pool).obtain(1) }; let msg2 = unsafe { (*pool).obtain(2) }; // 回收消息到池中 unsafe { (*pool).recycle(msg1) }; unsafe { (*pool).recycle(msg2) }; // 再次获取,会复用刚才回收的槽位 let msg3 = unsafe { (*pool).obtain(10) }; ``` ### Demo 3: 多 Handler 共享 Looper 演示多个 Handler 绑定到同一个 Looper,通过 `msg.target` 区分消息的目标处理器。 ```rust // 两个 Handler 共享同一个 Looper let handler1 = Handler::new(looper, |msg| { println!("[Handler1] what={}, arg1={}", unsafe { (*msg).what }, unsafe { (*msg).arg1 }); }); let handler2 = Handler::new(looper, |msg| { println!("[Handler2] what={}, arg2={}", unsafe { (*msg).what }, unsafe { (*msg).arg2 }); }); // 分别发送消息,通过 target 区分 unsafe { (*msg1).target = handler1 as *mut c_void; // 发给 handler1 (*msg2).target = handler2 as *mut c_void; // 发给 handler2 } ``` ### Demo 4: Looper Quit 演示 Looper 的退出控制。 ```rust let looper = Looper::new(true); // 允许退出 unsafe { println!("is_quit_allowed: {}", (*looper).is_quit_allowed()); // true println!("is_quitting: {}", (*looper).is_quitting()); // false (*looper).set_quitting(true); println!("is_quitting: {}", (*looper).is_quitting()); // true } ``` ### Demo 5: HandlerThread 后台线程 演示 HandlerThread 创建独立后台线程,自动运行 Looper 消息循环。 ```rust // 创建 HandlerThread(自动创建 Looper + Queue + Pool) let thread_ptr = HandlerThread::new("DemoThread", true); unsafe { let thread = &mut *thread_ptr; // 启动后台线程 thread.start(); // 创建带回调的 Handler let handler = thread.create_handler(|msg| { println!("[HandlerThread] what={}, arg1={}", unsafe { (*msg).what }, unsafe { (*msg).arg1 }); }); // 发送消息(会自动发送到后台线程的队列) let msg = Message::new(100); unsafe { (*msg).arg1 = 42; } unsafe { (*handler).send_message(msg) }; // 等待消息处理 std::thread::sleep(std::time::Duration::from_millis(200)); // 退出线程 thread.quit(); } ``` **运行输出**: ``` === Demo 5: HandlerThread (Background Thread) === HandlerThread created: DemoThread Starting HandlerThread... Handler created on HandlerThread Sent message via HandlerThread: what=100 [HandlerThread Callback] what=100, arg1=42 Quitting HandlerThread... HandlerThread quit ``` --- ## no_std 模式下的完整 Demo 代码 在 no_std(RTOS/嵌入式)环境下,不能使用 Rust 闭包,必须使用 C 函数指针作为回调。以下是核心层每个结构每个 API 的详细用法示例。 ### 前提条件:用户需实现的 FFI 函数 ```rust // 用户必须提供以下 FFI 函数(通过 #[no_mangle] 导出) // 内存分配:对应 OsMemory trait #[no_mangle] pub extern "C" fn my_malloc(size: usize) -> *mut c_void { // 实现方式取决于 RTOS: // - FreeRTOS: pvPortMalloc(size) // - RT-Thread: rt_malloc(size) // - bare-metal: static pool unimplemented!() } #[no_mangle] pub extern "C" fn my_free(ptr: *mut c_void) { // 实现方式取决于 RTOS unimplemented!() } // 时间接口:对应 OsTime trait #[no_mangle] pub extern "C" fn my_get_tick_ms() -> u64 { // 实现方式取决于 RTOS: // - FreeRTOS: xTaskGetTickCount() * portTICK_PERIOD_MS // - RT-Thread: rt_tick_get() unimplemented!() } // 线程创建:对应 OsThreadSpawn trait(HandlerThread 需要) #[no_mangle] pub extern "C" fn my_thread_spawn( name: *const c_void, stack_size: u32, priority: u32, entry: extern "C" fn(*mut c_void), arg: *mut c_void, ) -> *mut c_void { // 实现方式取决于 RTOS: // - FreeRTOS: xTaskCreate(entry, name, stack_size, arg, priority, NULL) // - RT-Thread: rt_thread_create(name, entry, arg, stack_size, priority) unimplemented!() } ``` ### 完整 Demo:核心层所有 API 用法 ```rust // no_std 环境下的消息处理完整示例 #![no_std] #![no_main] extern crate alloc; use core::ffi::c_void; use core::ptr; use msghandler::{ // ============================================================ // 1. Message 结构 - 所有 API // ============================================================ Message, // Message 常量 // - MSG_QUIT: i32 = 0, 退出消息标记 // - FLAG_IN_USE: i32 = 1 << 0, 使用中标志 // - FLAG_ASYNC: i32 = 1 << 1, 异步消息标志 // Message 公共字段(可直接访问): // - what: i32, 消息类型标识 // - arg1: i32, 第一个参数 // - arg2: i32, 第二个参数 // - obj: *mut c_void, 用户数据指针 // - when: u64, 消息触发时间戳(毫秒) // - target: *mut Handler, 目标 Handler // - user_obj: *mut c_void, 用户对象指针 // - next: *mut Message, 链表下一个消息 // ============================================================ // 2. Handler 结构 - 所有 API // ============================================================ Handler, // ============================================================ // 3. Looper 结构 - 所有 API // ============================================================ Looper, // ============================================================ // 4. MessageQueue 结构 - 所有 API // ============================================================ MessageQueue, // ============================================================ // 5. MessagePool 结构 - 所有 API // ============================================================ MessagePool, // ============================================================ // 6. HandlerThread 结构 - 所有 API // ============================================================ HandlerThread, // ============================================================ // 7. ArrayList 结构 - 所有 API // ============================================================ ArrayList, // ============================================================ // 8. Bundle 结构 - 所有 API // ============================================================ Bundle, // ============================================================ // 9. AsyncResult 结构 - 所有 API // ============================================================ AsyncResult, // ============================================================ // 10. Registrant 结构 - 所有 API // ============================================================ Registrant, // ============================================================ // 11. RegistrantList 结构 - 所有 API // ============================================================ RegistrantList, }; // ============================================================ // 用户回调函数 // ============================================================ extern "C" fn handle_message(msg: *mut Message) { if msg.is_null() { return; } unsafe { // -------------------- Message 字段访问 -------------------- let what = (*msg).what; // 消息类型 let arg1 = (*msg).arg1; // 第一个参数 let arg2 = (*msg).arg2; // 第二个参数 let obj = (*msg).obj; // 用户数据指针 let when = (*msg).when; // 触发时间戳 let target = (*msg).target; // 目标 Handler let user_obj = (*msg).user_obj; // 用户对象 // -------------------- Message API 调用 -------------------- // 获取/设置 target let current_target = (*msg).get_target(); (*msg).set_target(ptr::null_mut()); // 获取/设置 when let current_when = (*msg).get_when(); (*msg).set_when(1000); // 获取/设置 obj if (*msg).has_obj() { let existing_obj = (*msg).get_obj(); (*msg).set_obj(ptr::null_mut()); } // -------------------- Message 标志 API -------------------- // 检查消息是否在使用中 if (*msg).is_in_use() { (*msg).clear_in_use(); } else { (*msg).mark_in_use(); } // 检查/设置异步标志 if (*msg).is_async() { (*msg).set_async(false); } else { (*msg).set_async(true); } // -------------------- 处理消息 -------------------- match what { 1 => { /* 处理 what=1 */ } 2 => { /* 处理 what=2 */ } _ => { /* 未知消息 */ } } } } // ============================================================ // 主任务入口 // ============================================================ #[no_mangle] pub extern "C" fn app_main(_arg: *mut c_void) { // ========================================================================= // 1. MessagePool - 消息池,管理消息复用 // ========================================================================= // pub struct MessagePool // pub fn new(max_size: usize) -> *mut MessagePool // pub fn obtain(&mut self, what: i32) -> *mut Message // pub fn recycle(&mut self, msg: *mut Message) // pub fn available(&self) -> usize // pub fn size(&self) -> usize // pub fn is_empty(&self) -> bool let pool = MessagePool::new(10); // 最多 10 条消息 if pool.is_null() { return; } // obtain() - 从池中获取消息(池满时可能创建新的) let msg1 = unsafe { (*pool).obtain(1) }; // what = 1 let msg2 = unsafe { (*pool).obtain(2) }; // what = 2 let msg3 = unsafe { (*pool).obtain(3) }; // what = 3 // available() - 池中可用消息数 let avail = unsafe { (*pool).available() }; // size() - 当前池大小 let pool_size = unsafe { (*pool).size() }; // is_empty() - 池是否为空 if !unsafe { (*pool).is_empty() } { // 池不为空,可以继续获取消息 } // recycle() - 回收消息到池中 unsafe { (*pool).recycle(msg1) }; unsafe { (*pool).recycle(msg2) }; unsafe { (*pool).recycle(msg3) }; // ========================================================================= // 2. Message - 消息结构 // ========================================================================= // pub fn new(what: i32) -> *mut Message // pub fn recycle(&mut self) // pub fn send_to_target(&mut self) // pub fn set_target(&mut self, target: *mut Handler) // pub fn get_target(&self) -> *mut Handler // pub fn get_when(&self) -> u64 // pub fn set_when(&mut self, when: u64) // pub fn copy_from(&mut self, other: *mut Message) // pub fn is_in_use(&self) -> bool // pub fn mark_in_use(&mut self) // pub fn clear_in_use(&mut self) // pub fn is_async(&self) -> bool // pub fn set_async(&mut self, async_flag: bool) // pub fn recycle_unchecked(&mut self) // pub fn has_obj(&self) -> bool // pub fn set_obj(&mut self, obj: *mut c_void) // pub fn get_obj(&self) -> *mut c_void let msg = unsafe { (*pool).obtain(100) }; if !msg.is_null() { unsafe { // 字段直接访问 (*msg).what = 100; (*msg).arg1 = 10; (*msg).arg2 = 20; (*msg).obj = ptr::null_mut(); (*msg).user_obj = ptr::null_mut(); // recycle() - 回收消息(清除所有字段) (*msg).recycle(); // recycle_unchecked() - 不清除标志的回收(用于池复用) (*msg).recycle_unchecked(); } // copy_from() - 从另一个消息复制所有字段 let msg_src = unsafe { (*pool).obtain(200) }; if !msg_src.is_null() { unsafe { (*msg).copy_from(msg_src) }; unsafe { (*pool).recycle(msg_src) }; } // send_to_target() - 发送到目标 Handler unsafe { (*msg).send_to_target() }; // 重新获取并测试各个 API let msg = unsafe { (*pool).obtain(300) }; if !msg.is_null() { unsafe { // is_in_use / mark_in_use / clear_in_use let used = (*msg).is_in_use(); (*msg).mark_in_use(); let used2 = (*msg).is_in_use(); (*msg).clear_in_use(); // is_async / set_async let is_async = (*msg).is_async(); (*msg).set_async(true); let is_async2 = (*msg).is_async(); (*msg).set_async(false); // has_obj / set_obj / get_obj (*msg).set_obj(0x1000 as *mut c_void); let has = (*msg).has_obj(); let obj = (*msg).get_obj(); // get_when / set_when let when = (*msg).get_when(); (*msg).set_when(when + 1000); // get_target / set_target let target = (*msg).get_target(); (*msg).set_target(ptr::null_mut()); // 回收 (*pool).recycle(msg); } } } // ========================================================================= // 3. MessageQueue - 消息队列 // ========================================================================= // pub fn new() -> *mut MessageQueue // pub fn enqueue_message(&mut self, msg: *mut Message) // pub fn enqueue_message_at_front(&mut self, msg: *mut Message) // pub fn next(&mut self, timeout_ms: u64) -> *mut Message // pub fn is_empty(&self) -> bool // pub fn size(&self) -> usize // pub fn set_quitting(&mut self, quitting: bool) // pub fn get_message_count(&self) -> usize // pub fn is_quitting(&self) -> bool // pub fn remove_messages(&mut self, what: i32) -> usize // pub fn get_head(&self) -> *mut Message let queue = MessageQueue::new(); if queue.is_null() { return; } // enqueue_message() - 入队(添加到队列尾部,FIFO) let qmsg1 = unsafe { (*pool).obtain(1) }; let qmsg2 = unsafe { (*pool).obtain(2) }; let qmsg3 = unsafe { (*pool).obtain(3) }; unsafe { (*queue).enqueue_message(qmsg1); (*queue).enqueue_message(qmsg2); } // enqueue_message_at_front() - 入队到队列头部(优先执行) unsafe { (*queue).enqueue_message_at_front(qmsg3) }; // is_empty() - 检查队列是否为空 let empty = unsafe { (*queue).is_empty() }; // size() / get_message_count() - 获取消息数量 let queue_size = unsafe { (*queue).size() }; let msg_count = unsafe { (*queue).get_message_count() }; // next() - 获取下一条消息(非阻塞,timeout_ms 被忽略) let next_msg = unsafe { (*queue).next(0) }; // get_head() - 查看队首消息(不移除) let head = unsafe { (*queue).get_head() }; // remove_messages() - 移除所有指定 what 的消息,返回移除数量 let removed = unsafe { (*queue).remove_messages(2) }; // set_quitting() / is_quitting() - 退出控制 unsafe { (*queue).set_quitting(true) }; let quitting = unsafe { (*queue).is_quitting() }; // 清理 while !unsafe { (*queue).is_empty() } { let msg = unsafe { (*queue).next(0) }; if !msg.is_null() { unsafe { (*pool).recycle(msg) }; } } // ========================================================================= // 4. Looper - 消息循环器 // ========================================================================= // pub fn new(quit_allowed: bool) -> *mut Looper // pub fn is_quit_allowed(&self) -> bool // pub fn is_quitting(&self) -> bool // pub fn set_quitting(&mut self, quitting: bool) // pub fn set_queue(&mut self, queue: *mut MessageQueue) // pub fn get_queue(&self) -> *mut MessageQueue let looper = Looper::new(true); // 允许 quit if looper.is_null() { return; } unsafe { // is_quit_allowed() - 是否允许退出 let allow_quit = (*looper).is_quit_allowed(); // is_quitting() / set_quitting() - 退出状态 let quitting = (*looper).is_quitting(); (*looper).set_quitting(true); let quitting2 = (*looper).is_quitting(); // set_queue() / get_queue() - 队列关联 (*looper).set_queue(queue); let q = (*looper).get_queue(); } // ========================================================================= // 5. Handler - 消息处理器 // ========================================================================= // pub fn new(looper: *mut Looper, callback: extern "C" fn(*mut Message)) -> *mut Handler // pub fn new_no_callback(looper: *mut Looper) -> *mut Handler // pub fn get_looper(&self) -> *mut Looper // pub fn get_queue(&self) -> *mut MessageQueue // pub fn dispatch(&self, msg: *mut Message) // pub fn send_message(&self, msg: *mut Message) -> bool // pub fn send_empty_message(&self, what: i32) -> bool // pub fn remove_messages(&mut self, what: i32) // pub fn has_messages(&self, what: i32) -> bool // pub fn remove_all_messages(&mut self) // pub fn obtain(pool: &mut MessagePool, what: i32) -> *mut Message // pub fn post(&self, callback: extern "C" fn(*mut c_void), arg: *mut c_void) -> bool let handler = Handler::new(looper, handle_message); if handler.is_null() { return; } let handler_no_cb = Handler::new_no_callback(looper); unsafe { // get_looper() / get_queue() let h_looper = (*handler).get_looper(); let h_queue = (*handler).get_queue(); // -------------------- 发送消息 -------------------- // send_message() - 发送消息到队列 let hmsg = (*pool).obtain(10); if !hmsg.is_null() { (*hmsg).arg1 = 111; (*hmsg).arg2 = 222; let sent = (*handler).send_message(hmsg); } // send_empty_message() - 发送空消息(只有 what) let sent2 = (*handler).send_empty_message(11); // -------------------- 消息管理 -------------------- // has_messages() - 检查队列中是否有指定 what 的消息 let has_msg = (*handler).has_messages(10); // remove_messages() - 移除指定 what 的消息 (*handler).remove_messages(10); // remove_all_messages() - 移除所有消息 (*handler).remove_all_messages(); // -------------------- obtain - 从关联池获取消息 -------------------- // 注意:Handler.obtain 内部会从 Handler 关联的池获取 // 这里需要先建立 Handler 和 Pool 的关联,简化处理用 pool.obtain let hmsg2 = (*pool).obtain(20); if !hmsg2.is_null() { (*hmsg2).what = 20; (*handler).send_message(hmsg2); } // -------------------- post - 发送回调(无参数) -------------------- // no_std 版本使用函数指针 + arg extern "C" fn runnable_cb(arg: *mut c_void) { // 执行回调任务 } let posted = (*handler).post(runnable_cb, ptr::null_mut()); // -------------------- dispatch - 分发消息到回调 -------------------- let dmsg = (*pool).obtain(30); if !dmsg.is_null() { (*dmsg).what = 30; (*dmsg).arg1 = 999; (*handler).dispatch(dmsg); (*pool).recycle(dmsg); } } // ========================================================================= // 6. HandlerThread - 后台线程(需要线程创建支持) // ========================================================================= // pub fn new(name: &'static str, quit_allowed: bool) -> *mut HandlerThread // pub fn start(&mut self) -> bool // pub fn get_looper(&self) -> *mut Looper // pub fn get_handler(&self) -> *mut Handler // pub fn create_handler(&self, callback: extern "C" fn(*mut Message)) -> *mut Handler // pub fn quit(&mut self) -> bool // pub fn quit_safely(&mut self) -> bool // pub fn is_running(&self) -> bool // pub fn get_name(&self) -> &'static str let thread = HandlerThread::new("MyThread", true); if !thread.is_null() { unsafe { // get_name() - 获取线程名称 let name = (*thread).get_name(); // is_running() - 检查线程是否运行中 let running = (*thread).is_running(); // start() - 启动后台线程 // 注意:no_std 下需要用户提供 my_thread_spawn 实现 let started = (*thread).start(); // get_looper() / get_handler() - 获取关联的 Looper/Handler let t_looper = (*thread).get_looper(); let t_handler = (*thread).get_handler(); // create_handler() - 在此线程上创建 Handler let thread_handler = (*thread).create_handler(handle_message); // quit() - 安全退出(等待队列清空) let quit_ok = (*thread).quit(); // quit_safely() - 立即退出 // let quit_now = (*thread).quit_safely(); } } // ========================================================================= // 7. ArrayList - 动态数组 // ========================================================================= // pub fn new() -> *mut ArrayList // pub fn delete(list: *mut ArrayList) // pub fn add(list: *mut ArrayList, data: *mut c_void) // pub fn add_key(list: *mut ArrayList, key: i32, data: *mut c_void) // pub fn add_key_data(list: *mut ArrayList, key: i32, data: *mut c_void, size: usize) // pub fn get_by_key(list: *mut ArrayList, key: i32) -> *mut c_void // pub fn get(list: *mut ArrayList, index: i32) -> *mut c_void // pub fn remove(list: *mut ArrayList, data: *mut c_void) // pub fn remove_key(list: *mut ArrayList, key: i32) -> *mut c_void // pub fn clear(list: *mut ArrayList) // pub fn size(list: *mut ArrayList) -> usize // pub fn is_empty(list: *mut ArrayList) -> bool // pub fn enumerate(list: *mut ArrayList, callback: F) where F: FnMut(*mut c_void) -> bool let list = ArrayList::new(); if !list.is_null() { // add() - 添加数据(无 key) let data1 = 0x1000 as *mut c_void; let data2 = 0x2000 as *mut c_void; ArrayList::add(list, data1); ArrayList::add(list, data2); // add_key() - 添加数据(带 key) let data3 = 0x3000 as *mut c_void; ArrayList::add_key(list, 100, data3); // add_key_data() - 添加数据副本(会复制数据) let data4 = 0x4000 as *mut c_void; ArrayList::add_key_data(list, 200, data4, 16); // get() - 按索引获取 let item0 = ArrayList::get(list, 0); let item1 = ArrayList::get(list, 1); // get_by_key() - 按 key 获取 let item_by_key = ArrayList::get_by_key(list, 100); // size() - 获取元素数量 let list_size = ArrayList::size(list); // is_empty() - 检查是否为空 let list_empty = ArrayList::is_empty(list); // remove() - 按数据指针移除 ArrayList::remove(list, data1); // remove_key() - 按 key 移除 let removed_data = ArrayList::remove_key(list, 100); // enumerate() - 遍历所有元素 // 返回 false 的回调会停止遍历 let mut count = 0; ArrayList::enumerate(list, |item| { count += 1; true // 继续遍历 }); // clear() - 清空所有元素 ArrayList::clear(list); // delete() - 删除列表 ArrayList::delete(list); } // ========================================================================= // 8. Bundle - 键值对存储 // ========================================================================= // pub fn new() -> *mut Bundle // pub fn delete(bundle: *mut Bundle) // pub fn put_object(bundle: *mut Bundle, key: i32, value: *mut c_void, size: usize) // pub fn put_bool(bundle: *mut Bundle, key: i32, value: bool) // pub fn put_int(bundle: *mut Bundle, key: i32, value: i32) // pub fn put_ptr(bundle: *mut Bundle, key: i32, value: *mut c_void) // pub fn get_object(bundle: *mut Bundle, key: i32) -> *mut c_void // pub fn get_bool(bundle: *mut Bundle, key: i32, default_value: bool) -> bool // pub fn get_int(bundle: *mut Bundle, key: i32, default_value: i32) -> i32 // pub fn get_ptr(bundle: *mut Bundle, key: i32) -> *mut c_void // pub fn put_byte_array(bundle: *mut Bundle, key: i32, value: &[u8]) // pub fn get_byte_array(bundle: *mut Bundle, key: i32) -> Option<&'static [u8]> // pub fn contains_key(bundle: *mut Bundle, key: i32) -> bool // pub fn size(bundle: *mut Bundle) -> usize // pub fn is_empty(bundle: *mut Bundle) -> bool let bundle = Bundle::new(); if !bundle.is_null() { // put_int() / get_int() - 存储/获取 i32 Bundle::put_int(bundle, 1, 100); let int_val = Bundle::get_int(bundle, 1, 0); // put_bool() / get_bool() - 存储/获取 bool Bundle::put_bool(bundle, 2, true); let bool_val = Bundle::get_bool(bundle, 2, false); // put_ptr() / get_ptr() - 存储/获取指针 let ptr_val = 0x1234 as *mut c_void; Bundle::put_ptr(bundle, 3, ptr_val); let retrieved_ptr = Bundle::get_ptr(bundle, 3); // put_object() / get_object() - 存储/获取对象指针 let obj_val = 0x5678 as *mut c_void; Bundle::put_object(bundle, 4, obj_val, 8); let retrieved_obj = Bundle::get_object(bundle, 4); // put_byte_array() / get_byte_array() - 存储/获取字节数组 let byte_data = [1u8, 2, 3, 4]; Bundle::put_byte_array(bundle, 5, &byte_data); let retrieved_bytes = Bundle::get_byte_array(bundle, 5); // contains_key() - 检查 key 是否存在 let has_key = Bundle::contains_key(bundle, 1); let no_key = Bundle::contains_key(bundle, 999); // size() / is_empty() - 元素数量和空检查 let bundle_size = Bundle::size(bundle); let bundle_empty = Bundle::is_empty(bundle); // delete() - 删除 bundle Bundle::delete(bundle); } // ========================================================================= // 9. AsyncResult - 异步结果 // ========================================================================= // pub fn new(user_obj: *mut c_void, obj: *mut c_void, obj_size: i32, error: i32) -> *mut AsyncResult // pub fn delete(ar: *mut AsyncResult) // pub fn is_success(&self) -> bool // pub fn get_result_slice(&self) -> Option<&'static [u8]> // pub fn delete_from_message(msg: *mut Message) // pub fn for_message(msg: *mut Message, obj: *mut c_void, obj_size: i32, error: i32) -> *mut AsyncResult let ar = AsyncResult::new( ptr::null_mut(), // user_obj 0x1000 as *mut c_void, // result obj 16, // result size 0 // error code (0 = success) ); if !ar.is_null() { unsafe { // is_success() - 检查是否成功(error_code == 0) let success = (*ar).is_success(); // get_result_slice() - 获取结果数据切片 if let Some(slice) = (*ar).get_result_slice() { // 使用 slice } // 公共字段访问 let user_obj = (*ar).user_obj; let error_code = (*ar).error_code; let result = (*ar).result; let result_size = (*ar).result_size; // delete() - 删除 AsyncResult AsyncResult::delete(ar); } } // for_message() - 创建 AsyncResult 并附加到 Message let ar_msg = unsafe { (*pool).obtain(0) }; if !ar_msg.is_null() { let ar_attached = AsyncResult::for_message( ar_msg, 0x2000 as *mut c_void, 32, 0 ); // delete_from_message() - 从 Message 提取并删除 AsyncResult AsyncResult::delete_from_message(ar_msg); unsafe { (*pool).recycle(ar_msg) }; } // ========================================================================= // 10. Registrant - 注册回调 // ========================================================================= // pub fn new(handler: *mut Handler, what: i32, user_obj: *mut c_void) -> *mut Registrant // pub fn delete(registrant: *mut Registrant) // pub fn notify_async_result(&self, ar: *mut AsyncResult) // pub fn notify(&self, result: *mut c_void, result_size: i32, error: i32) // pub fn is_for_handler(&self, handler: *mut Handler) -> bool let registrant = Registrant::new(handler, 100, ptr::null_mut()); if !registrant.is_null() { unsafe { // 公共字段访问 let reg_handler = (*registrant).handler; let reg_what = (*registrant).what; let reg_user_obj = (*registrant).user_obj; // is_for_handler() - 检查是否关联到指定 Handler let is_for = (*registrant).is_for_handler(handler); let not_for = (*registrant).is_for_handler(ptr::null_mut()); // notify() - 通知 registrant 带结果 (*registrant).notify(0x3000 as *mut c_void, 8, 0); // notify_async_result() - 通知 registrant 带 AsyncResult let ar2 = AsyncResult::new(ptr::null_mut(), 0x4000 as *mut c_void, 16, 0); if !ar2.is_null() { (*registrant).notify_async_result(ar2); AsyncResult::delete(ar2); } // delete() - 删除 registrant Registrant::delete(registrant); } } // ========================================================================= // 11. RegistrantList - 注册回调列表 // ========================================================================= // pub fn new() -> *mut RegistrantList // pub fn delete(list: *mut RegistrantList) // pub fn add_registrant(&self, registrant: *mut Registrant) // pub fn add(&self, handler: *mut Handler, what: i32, user_obj: *mut c_void) // pub fn remove(&self, handler: *mut Handler) // pub fn notify_registrants(&self, ar: *mut AsyncResult) // pub fn size(&self) -> usize // pub fn is_empty(&self) -> bool let reg_list = RegistrantList::new(); if !reg_list.is_null() { // add() - 创建并添加新的 Registrant unsafe { (*reg_list).add(handler, 200, ptr::null_mut()); (*reg_list).add(handler, 201, ptr::null_mut()); (*reg_list).add(handler_no_cb, 300, ptr::null_mut()); } // add_registrant() - 添加已存在的 Registrant let reg2 = Registrant::new(handler, 202, ptr::null_mut()); if !reg2.is_null() { unsafe { (*reg_list).add_registrant(reg2) }; } // size() / is_empty() let reg_count = unsafe { (*reg_list).size() }; let reg_empty = unsafe { (*reg_list).is_empty() }; // notify_registrants() - 通知所有 registrant let ar3 = AsyncResult::new(ptr::null_mut(), 0x5000 as *mut c_void, 24, 0); if !ar3.is_null() { unsafe { (*reg_list).notify_registrants(ar3) }; AsyncResult::delete(ar3); } // remove() - 移除关联到指定 Handler 的所有 registrant unsafe { (*reg_list).remove(handler) }; // delete() - 删除列表及所有 registrant RegistrantList::delete(reg_list); } // ========================================================================= // 消息循环主循环(参考 Android Looper.loop()) // ========================================================================= unsafe { // 设置队列到 Looper (*looper).set_queue(queue); // 清空队列(之前可能有残留) (*handler).remove_all_messages(); } loop { // next() - 获取消息(no_std 无阻塞,timeout_ms 忽略) let msg = unsafe { (*queue).next(100) }; if !msg.is_null() { let what = unsafe { (*msg).what }; // 检查退出消息 if what == Message::QUIT { unsafe { (*pool).recycle(msg) }; break; } // dispatch() - 分发消息到 Handler 回调 unsafe { (*handler).dispatch(msg) }; // 回收消息 unsafe { (*pool).recycle(msg) }; } // 检查 Looper 退出状态 if unsafe { (*looper).is_quitting() } { break; } } // ========================================================================= // 资源清理 // ========================================================================= // 注意:实际清理取决于 RTOS 的内存管理策略 // - 有些 RTOS 自动回收进程内存 // - 有些需要手动释放 // // MessagePool.delete() - 目前未实现,需要时可添加 // MessageQueue.delete() - 目前未实现,需要时可添加 // Looper.delete() - 目前未实现,需要时可添加 // Handler.delete() - 目前未实现,需要时可添加 } // ============================================================ // 辅助:Handler.obtain 的正确用法(从关联池获取消息) // ============================================================ // 注意:Handler.obtain() 方法签名是: // pub fn obtain(pool: &mut MessagePool, what: i32) -> *mut Message // 这是静态方法,需要传入 pool 引用 extern "C" fn handle_for_obtain(msg: *mut Message) { if msg.is_null() { return; } unsafe { // 处理消息 } } #[no_mangle] pub extern "C" fn demo_handler_obtain(pool: *mut MessagePool, handler: *mut Handler) { if pool.is_null() || handler.is_null() { return; } // 使用 Handler::obtain 从池获取消息 let msg = unsafe { Handler::obtain(&mut *pool, 999) }; if !msg.is_null() { unsafe { (*msg).arg1 = 123; (*handler).send_message(msg); } } } ``` ### API 索引表 | 结构 | API 数量 | 关键 API | |------|---------|---------| | Message | 17 | `new`, `recycle`, `send_to_target`, `set_target`, `get_target`, `get_when`, `set_when`, `copy_from`, `is_in_use`, `mark_in_use`, `clear_in_use`, `is_async`, `set_async`, `recycle_unchecked`, `has_obj`, `set_obj`, `get_obj` | | Handler | 12+ | `new`, `new_no_callback`, `get_looper`, `get_queue`, `dispatch`, `send_message`, `send_empty_message`, `remove_messages`, `has_messages`, `remove_all_messages`, `obtain`, `post` | | Looper | 6 | `new`, `is_quit_allowed`, `is_quitting`, `set_quitting`, `set_queue`, `get_queue` | | MessageQueue | 10 | `new`, `enqueue_message`, `enqueue_message_at_front`, `next`, `is_empty`, `size`, `set_quitting`, `get_message_count`, `is_quitting`, `remove_messages`, `get_head` | | MessagePool | 5 | `new`, `obtain`, `recycle`, `available`, `size`, `is_empty` | | HandlerThread | 8 | `new`, `start`, `get_looper`, `get_handler`, `create_handler`, `quit`, `quit_safely`, `is_running`, `get_name` | | ArrayList | 13 | `new`, `delete`, `add`, `add_key`, `add_key_data`, `get_by_key`, `get`, `remove`, `remove_key`, `clear`, `size`, `is_empty`, `enumerate` | | Bundle | 14 | `new`, `delete`, `put_object`, `put_bool`, `put_int`, `put_ptr`, `get_object`, `get_bool`, `get_int`, `get_ptr`, `put_byte_array`, `get_byte_array`, `contains_key`, `size`, `is_empty` | | AsyncResult | 6 | `new`, `delete`, `is_success`, `get_result_slice`, `delete_from_message`, `for_message` | | Registrant | 5 | `new`, `delete`, `notify_async_result`, `notify`, `is_for_handler` | | RegistrantList | 8 | `new`, `delete`, `add_registrant`, `add`, `remove`, `notify_registrants`, `size`, `is_empty` | --- ### no_std 与 use-std 的关键区别 | 特性 | use-std | no_std | |------|---------|--------| | 回调类型 | `Box` 闭包 | `extern "C" fn(*mut Message)` 函数指针 | | Handler 创建 | `Handler::new(looper, \|msg\| { ... })` | `Handler::new(looper, c_callback)` | | 内存分配 | 自动(Rust 堆) | 需要用户实现 `my_malloc/my_free` | | 线程创建 | `std::thread::spawn` | 需要用户提供 `xTaskCreate` 等 | | ThreadLocal | `thread_local!` 宏 | 需要用户提供 TLS 实现 | ### 注意事项 1. **回调函数必须是 `extern "C"`**:FFI 边界只能传递 C 函数指针,Rust 闭包无法跨边界传递 2. **避免捕获上下文**:闭包可以捕获外部变量,但函数指针不行。如果需要共享数据,使用全局变量或 `static mut` 3. **内存分配返回 null**:no_std 模式下 `OsMemory::malloc` 默认返回 `null`,必须由用户提供正确实现 4. **线程安全**:在 RTOS 多任务环境下,需要确保 Mutex/Condvar 实现正确 --- ## 测试用例 | 测试文件 | 测试内容 | |---------|---------| | `test_basic.rs` (7 tests) | Message 创建/属性/回收、Looper 创建/quit/队列关联 | | `test_multi_handler.rs` (10 tests) | Handler 创建/获取Looper、MessageQueue 操作、MessagePool 复用、多Handler共享Looper | --- ## 架构设计 ``` ┌─────────────────────────────────────────────────────────────┐ │ Rust 核心层 │ │ │ │ Message Handler Looper MessageQueue │ │ MessagePool HandlerThread ThreadLocal │ │ │ │ 纯 Rust 实现,平台无关 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ OS 抽象层 (src/os/) │ │ │ │ Mutex Condvar ThreadLocal Memory Time │ │ (trait 定义,由各平台实现) │ └─────────────────────────────────────────────────────────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ std_impl │ │ freertos_impl │ │ rtthread_impl │ │ (Linux/macOS) │ │ (FreeRTOS) │ │ (RT-Thread) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ RTOS C 函数 │ │ (通过 FFI 调用) │ └─────────────────┘ ``` --- ## OS 抽象层 OS 抽象层通过 trait 定义接口,各平台提供具体实现,使核心代码与操作系统解耦。 ### Trait 一览 | Trait | 说明 | 使用场景 | |-------|------|---------| | `OsMutex` | 互斥锁 | 保护消息队列的并发访问 | | `OsCondvar` | 条件变量 | 消息队列等待时的线程阻塞/唤醒 | | `OsThreadLocal` | 线程本地存储 | 存储每个线程的 Looper 指针 | | `OsMemory` | 内存分配 | Message/Handler 等结构体的分配 | | `OsTime` | 时间接口 | 消息延迟发送、队列阻塞超时 | | `OsThreadSpawn` | 线程创建 | HandlerThread 创建后台线程 | | `OsPool` | 服务池 | 统一管理上述所有服务的实例 | ### 1. OsMutex(互斥锁) ```rust pub trait OsMutex { fn lock(&mut self); // 获取锁 fn unlock(&mut self); // 释放锁 fn try_lock(&mut self) -> bool; // 尝试获取锁(非阻塞) } ``` **用途**:保护消息队列的并发访问,防止多线程同时入队/出队导致数据竞争。 **各平台实现**: | 平台 | 实现方式 | |------|---------| | std | `std::sync::Mutex` | | FreeRTOS | `xSemaphoreCreateMutex` / `xSemaphoreTake/Release` | | RT-Thread | `rt_mutex_create` / `rt_mutex_take/release` | | no_std | 空实现(单线程环境) | ### 2. OsCondvar(条件变量) ```rust pub trait OsCondvar { fn wait(&mut self, lock: &mut dyn OsMutex); // 等待信号 fn signal(&mut self); // 唤醒单个线程 fn broadcast(&mut self); // 唤醒所有线程 fn timedwait(&mut self, lock: &mut dyn OsMutex, timeout_ms: u32) -> bool; // 超时等待 } ``` **用途**:消息队列为空时阻塞消费者线程,新消息到达时唤醒。 **各平台实现**: | 平台 | 实现方式 | |------|---------| | std | `std::sync::Condvar` | | FreeRTOS | `xSemaphoreCreateBinary()` 创建二值信号量,`xSemaphoreTake()` 等待,`xSemaphoreGive()` 唤醒 | | RT-Thread | `rt_sem_create()` 创建信号量,`rt_sem_take()` 等待,`rt_sem_release()` 唤醒 | | no_std | 空实现 | ### 3. OsThreadLocal(线程本地存储) ```rust pub trait OsThreadLocal { fn set(&self, ptr: *mut c_void); // 设置当前线程的本地数据 fn get(&self) -> *mut c_void; // 获取当前线程的本地数据 } ``` **用途**:存储当前线程的 Looper 指针,实现 `Looper::my_looper()` 获取调用线程的 Looper。 **各平台实现**: | 平台 | 实现方式 | |------|---------| | std | `thread_local!` 宏 | | FreeRTOS | `vTaskSetThreadLocalStorageValue(task, index, ptr)` / `pvTaskGetThreadLocalStoragePointer(task, index)` | | RT-Thread | `rt_thread_set_user_data(thread, user_data)` / `rt_thread_get_user_data(thread)` | | no_std | 空实现 | ### 4. OsMemory(内存分配) ```rust pub trait OsMemory { fn malloc(&self, size: usize) -> *mut c_void; fn free(&self, ptr: *mut c_void); fn calloc(&self, nmemb: usize, size: usize) -> *mut c_void; // 分配并清零 fn realloc(&self, ptr: *mut c_void, new_size: usize) -> *mut c_void; } ``` **用途**:分配/释放 Message、Handler、Looper 等结构体。 **各平台实现**: | 平台 | 实现方式 | |------|---------| | std | `libc::malloc/free` | | FreeRTOS | `pvPortMalloc/vPortFree` | | RT-Thread | `rt_malloc/rt_free` | | no_std | 空实现(返回 null,需外部提供) | ### 5. OsTime(时间接口) ```rust pub trait OsTime { fn get_tick_ms(&self) -> u64; // 获取系统运行毫秒数 } ``` **用途**: - 消息的 `when` 字段:延迟消息的触发时间 - `queue.next(timeout_ms)`:队列为空时的阻塞超时 **各平台实现**: | 平台 | 实现方式 | |------|---------| | std | `std::time::Instant::now()` | | FreeRTOS | `xTaskGetTickCount()` | | RT-Thread | `rt_tick_get()` | | no_std | 返回 0 | ### 6. OsThreadSpawn(线程创建) ```rust pub trait OsThreadSpawn { // 创建线程,返回句柄 fn spawn(&self, name: &'static str, stack_size: u32, priority: u32, entry: extern "C" fn(*mut c_void), arg: *mut c_void) -> *mut c_void; // 销毁线程 fn destroy(&self, thread: *mut c_void); } ``` **用途**:HandlerThread 启动后台线程,运行 Looper 消息循环。 **各平台实现**: | 平台 | 实现方式 | |------|---------| | std | `std::thread::spawn` | | FreeRTOS | `xTaskCreate` / `vTaskDelete` | | RT-Thread | `rt_thread_create` / `rt_thread_delete` | | no_std | 空实现(返回 null) | ### 7. OsPool(服务池) ```rust pub trait OsPool { type M: OsMemory; type T: OsTime; type TL: OsThreadLocal; type Mut: OsMutex; type Cond: OsCondvar; type TS: OsThreadSpawn; fn memory(&self) -> &Self::M; fn time(&self) -> &Self::T; fn thread_local(&self) -> &Self::TL; fn mutex(&self) -> Self::Mut; fn condvar(&self) -> Self::Cond; fn thread_spawn(&self) -> Self::TS; } ``` **用途**:统一管理所有 OS 服务的实例,提供 `get_os_pool()` 全局访问点。 --- ## 各平台实现对照表 | Trait | std | FreeRTOS | RT-Thread | no_std | |-------|-----|----------|-----------|--------| | OsMutex | `std::sync::Mutex` | `xSemaphoreTake()` / `xSemaphoreGive()` | `rt_mutex_take()` / `rt_mutex_release()` | 空实现 | | OsCondvar | `std::sync::Condvar` | `xSemaphoreCreateBinary()` + `Take()/Give()` | `rt_sem_create()` + `take()/release()` | 空实现 | | OsThreadLocal | `thread_local!` macro | `vTaskSetThreadLocalStorageValue()` / `pvTaskGetThreadLocalStoragePointer()` | `rt_thread_set_user_data()` / `rt_thread_get_user_data()` | 空实现 | | OsMemory | `libc::malloc()` / `libc::free()` | `pvPortMalloc()` / `vPortFree()` | `rt_malloc()` / `rt_free()` | 返回 null | | OsTime | `std::time::Instant::now()` | `xTaskGetTickCount()` | `rt_tick_get()` | 返回 0 | | OsThreadSpawn | `std::thread::spawn()` | `xTaskCreate()` / `vTaskDelete()` | `rt_thread_create()` / `rt_thread_delete()` | 空实现 | --- ## Cargo.toml 配置 ### msghandler/Cargo.toml ```toml [package] name = "msghandler" version = "0.1.0" edition = "2021" [lib] name = "message_handler" crate-type = ["lib", "staticlib", "cdylib"] [features] use-std = ["libc"] # 标准库模式(需要 libc) rtos-freertos = ["no-std"] # FreeRTOS 模式 rtos-rtthread = ["no-std"] # RT-Thread 模式 no-std = [] # 通用 no_std 模式 [dependencies] libc = { version = "0.2", optional = true } # 仅 use-std 需要 [dependencies.compiler_builtins] version = "0.1" optional = true # no_std 模式需要 ``` ### demo/Cargo.toml ```toml [package] name = "message-handler-demo" version = "0.1.0" edition = "2021" [[bin]] name = "demo" path = "src/main.rs" [dependencies] msghandler = { path = "../msghandler", features = ["use-std"] } ``` --- ## FFI 依赖说明 本库在 no_std/RTOS 模式下通过 FFI 调用底层 RTOS 的 C 函数。**这些 C 函数需要用户在实际部署时自行提供或链接对应的 RTOS 库**。 ### FreeRTOS 依赖的 C 函数 | 函数 | 说明 | 来源 | |------|------|------| | `pvPortMalloc()` / `vPortFree()` | 内存分配 | FreeRTOS HAL | | `xTaskCreate()` / `vTaskDelete()` | 任务创建/销毁 | FreeRTOS kernel | | `xSemaphoreCreateMutex()` | 互斥锁创建 | FreeRTOS kernel | | `xSemaphoreCreateBinary()` | 二值信号量创建 | FreeRTOS kernel | | `xSemaphoreTake()` / `xSemaphoreGive()` | 信号量获取/释放 | FreeRTOS kernel | | `xTaskGetTickCount()` | 获取系统 tick | FreeRTOS kernel | | `vTaskSetThreadLocalStorageValue()` | 设置线程本地存储 | FreeRTOS kernel | | `pvTaskGetThreadLocalStoragePointer()` | 获取线程本地存储 | FreeRTOS kernel | ### RT-Thread 依赖的 C 函数 | 函数 | 说明 | 来源 | |------|------|------| | `rt_malloc()` / `rt_free()` | 内存分配 | RT-Thread | | `rt_thread_create()` / `rt_thread_delete()` | 线程创建/销毁 | RT-Thread | | `rt_mutex_create()` / `rt_mutex_take/release()` | 互斥锁 | RT-Thread | | `rt_sem_create()` / `rt_sem_take/release()` | 信号量 | RT-Thread | | `rt_tick_get()` | 获取系统 tick | RT-Thread | | `rt_thread_set_user_data()` / `rt_thread_get_user_data()` | 线程本地存储 | RT-Thread | ### 链接方式 ```bash # 方式1: 链接 FreeRTOS 库 -lfreertos -lhal # 方式2: 自行实现这些函数并链接 # 用户需要提供 pvPortMalloc, xTaskCreate 等函数的实现 ``` --- ## ThreadLocal API ```rust // 获取当前线程的 Looper let looper = Looper::my_looper(); // 设置当前线程的 Looper Looper::prepare(); let looper = Looper::my_looper(); // ThreadLocal 也可用于存储其他线程相关数据 let tl = get_os_pool().thread_local(); tl.set(my_ptr as *mut c_void); let retrieved = tl.get(); ``` --- ## 编译产物 | 平台 | 产物 | 路径 | |------|------|------| | macOS/Linux | `libmessage_handler.rlib`, `libmessage_handler.dylib` | `target/debug/` 或 `target/release/` | | FreeRTOS (ARM) | `libmessage_handler.a` (静态库) | `target/thumbv7em-none-eabihf/debug/` 或 `target/thumbv7em-none-eabihf/release/` | | RT-Thread (ARM) | `libmessage_handler.a` (静态库) | `target/thumbv7em-none-eabihf/debug/` 或 `target/thumbv7em-none-eabihf/release/` | --- ## 内存管理与 Raw Pointer 设计 本库使用原始指针 `*mut Xxx` 设计,这是为了支持 no_std 环境(RTOS/嵌入式),避免 Rust 标准库的内存管理机制带来的开销。 ### 核心原则:谁创建,谁释放 | 操作 | 释放方式 | |------|---------| | `Message::new()` | `MessagePool.recycle()` 或 `Message.recycle()` | | `Handler::new()` | 需手动调用删除接口(暂未实现) | | `Looper::new()` | 需手动调用删除接口(暂未实现) | | `MessageQueue::new()` | 需手动调用删除接口(暂未实现) | | `HandlerThread::new()` | `HandlerThread.quit()` + 析构 | ### Message 生命周期 ``` ┌──────────────────────────────────────────────────────────────┐ │ 1. 创建消息 │ │ let msg = Message::new(what); // 或从池中获取 │ │ unsafe { (*msg).arg1 = 10; } │ │ │ │ 2. 发送消息 │ │ unsafe { (*msg).target = handler; } │ │ handler.send_message(msg); // 消息进入队列 │ │ │ │ 3. Looper 处理(后台线程或主循环) │ │ let msg = queue.next(timeout); │ │ handler.dispatch(msg); // 调用回调 │ │ │ │ 4. 回收消息 │ │ pool.recycle(msg); // 放回池中复用 │ │ │ │ ⚠️ 消息被 send_message 后,所有权转移给队列 │ │ 不应再访问已发送的消息 │ └──────────────────────────────────────────────────────────────┘ ``` ### 指针类型说明 | 类型 | 说明 | 安全性 | |------|------|--------| | `*mut Message` | 可变原始指针,指向堆或静态分配的消息 | unsafe,需手动管理 | | `*mut Handler` | Handler 指针 | unsafe | | `*mut Looper` | Looper 指针 | unsafe | | `*mut c_void` | C 通用指针,用于 user_obj 等 | unsafe | ### 常见错误 **错误 1:发送后访问已释放的消息** ```rust let msg = Message::new(1); handler.send_message(msg); // 此时 msg 已进入队列,不应再访问 unsafe { (*msg).arg1 = 10; } // ❌ 错误:消息已被队列接管 ``` **错误 2:未回收消息导致泄漏** ```rust let msg = Message::new(1); handler.send_message(msg); queue.next(0); // 获取消息 // 如果不回收,消息会泄漏 pool.recycle(msg); // ✓ 正确:处理完后回收 ``` **错误 3:重复回收** ```rust pool.recycle(msg); pool.recycle(msg); // ❌ 错误:重复回收可能导致问题 ``` ### no_std 模式下的内存分配 在 no_std/RTOS 模式下,内存分配通过 OS 抽象层提供: ```rust // OsMemory trait trait OsMemory { fn malloc(&self, size: usize) -> *mut c_void; fn free(&self, ptr: *mut c_void); } ``` 用户需要确保 RTOS 提供了正确的内存分配实现,否则 `Message::new()` 等会返回 `null`。 --- ## 设计灵感 本项目灵感来自 **Android Handler/Looper 消息机制**: ``` ┌─────────────┐ send_message ┌─────────────┐ │ Handler │ ─────────────────► │ Looper │ │ (发送端) │ │ (循环处理) │ └─────────────┘ └──────┬──────┘ │ getQueue() │ ┌──────▼──────┐ │ MessageQueue │ │ (消息队列) │ └──────┬──────┘ │ next() 获取 │ ┌──────▼──────┐ │ Message │ │ (消息内容) │ └─────────────┘ ``` **Android 对应关系**: | Android | 本库 | 说明 | |---------|------|------| | `Handler.sendMessage()` | `Handler.send_message()` | 发送消息到 Looper | | `Looper.loop()` | `HandlerThread` 后台线程 | 循环读取队列 | | `Handler.handleMessage()` | 闭包回调 | 处理消息 | | `MessageQueue` | `MessageQueue` | 消息队列 | | `Message.obtain()` | `MessagePool.obtain()` | 消息池复用 | | `Looper.myLooper()` | `Looper::my_looper()` | 获取线程本地 Looper |