【RT-Thread基礎教程】郵箱的使用

文章目錄

  • 前言
  • 一、郵箱的特性
  • 二、郵箱操作函數
  • 2.1 創建郵箱
      • 創建動態郵箱
      • 創建靜態郵箱
    • 2.2 刪除郵箱
    • 2.3 發郵件
      • 2.4 取郵件
  • 三、示例代碼
  • 總結


前言

RT-Thread是一個開源的實時嵌入式操作系統,廣泛應用于各種嵌入式系統和物聯網設備。在RT-Thread中,郵箱是一種常用的線程間通信機制,用于實現不同線程之間的消息傳遞。本教程將介紹如何在RT-Thread中使用郵箱,以便開發者更好地利用這一功能。


一、郵箱的特性

郵箱的本質是環形緩沖區:

郵箱中的每一封郵件,只能容納 4 字節內容(對于 32 位系統,指針大小剛好為 4 字節);

  • 郵件的發送通常是非阻塞的,線程、中斷都可以發送郵件;也可使用阻塞方式發送;
    • 郵件的接收通常是阻塞的,取決于郵箱中是否有郵件;
    • 當一個線程向郵箱發送郵件時:
      • 如果郵箱沒滿,就把數值寫入郵箱中
    • 如果郵箱滿了:
      • 發送線程可以直接返回RT_EFULL
      • 也可以掛起一段時間,在掛起的期間,別的線程或中斷服務程序讀了郵箱,會喚醒掛起的線程。
  • 當一個線程從郵箱接收郵件時:
    • 如果郵箱不為空,就讀取郵箱中的數值
    • 如果郵箱為空:
      • 接收線可以直接返回RT_ETIMOUT
      • 也可以掛起一段時間,在掛起的期間,別的線程或中斷服務程序寫了郵箱,會喚醒掛起的線程。

二、郵箱操作函數

郵箱由郵箱控制塊管理,由結構體 rt_mailbox 表示。
使用郵箱的流程:創建/初始化郵箱、發送郵件、接收郵件、刪除/脫離郵箱
在這里插入圖片描述

2.1 創建郵箱

創建動態郵箱

我們可以使用下面這個函數創建動態郵箱:

rt_mailbox_t rt_mb_create (const char* name, rt_size_t size, rt_uint8_t flag);

參數說明:
name 郵箱名稱
size 郵箱容量
flag 郵箱采用的等待方式: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO
返回值 郵箱對象的句柄:成功,返回句柄,以后使用句柄來操作郵箱,RT_NULL:失敗

創建靜態郵箱

我們可以使用下面這個函數創建靜態郵箱:

 rt_err_t rt_mb_init(rt_mailbox_t mb,const char* name,void* msgpool,rt_size_t size,rt_uint8_t flag);

參數說明:
mb 郵箱對象的句柄
name 郵箱的名字
msgpool 緩沖區指針
size 郵箱容量
flag 郵箱采用的等待方式: RT_IPC_FLAG_FIFO 或 RT_IPC_FLAG_PRIO
返回值 RT_EOK:成功

2.2 刪除郵箱

我們可以使用下面這個函數刪除rt_mb_create 函數創建的郵箱:

rt_err_t rt_mb_delete (rt_mailbox_t mb);

參數為郵箱的handle

我們可以使用下面這個函數刪除rt_mb_init創建的郵箱:

rt_err_t rt_mb_detach(rt_mailbox_t mb);

參數為郵箱的handle

他們的返回值為RT_ERROR時,表示出錯了

2.3 發郵件

  1. 我們可以使用下面這個函數來發送郵件:
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value);

參數1為郵箱的handle
參數2為要發送的值

  1. 我們可以使用下面這個函數來發送郵件,并等待一定的tick:
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,rt_ubase_t   value,rt_int32_t   timeout);

參數1為郵箱的handle
參數2為要發送的值
參數3為等待的tick

  1. 我們可以使用下面這個函數來發送緊急郵件:
rt_err_t rt_mb_urgent (rt_mailbox_t mb, rt_ubase_t value);

參數1為郵箱的handle
參數2為要發送的值

2.4 取郵件

我們可以使用下面這個函數來收郵件:

rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32_t* value, rt_int32_t timeout);

參數1為郵箱的handle
參數2為存儲的地址
參數3為等待時間

三、示例代碼

#include <rtthread.h>// 定義一個郵箱句柄
static rt_mailbox_t mailbox;// 定義一個線程1
static void thread1_entry(void *parameter)
{rt_uint32_t message = 123;// 發送消息到郵箱rt_mb_send(mailbox, &message, sizeof(message));// 等待一段時間,模擬其他操作rt_thread_delay(50);
}// 定義一個線程2
static void thread2_entry(void *parameter)
{rt_uint32_t message;// 從郵箱接收消息rt_mb_recv(mailbox, &message, RT_WAITING_FOREVER);// 處理接收到的消息rt_kprintf("Received message: %d\n", message);
}int mailbox_example(void)
{// 創建郵箱,設置郵箱大小為5,每個消息大小為4字節mailbox = rt_mb_create("mbox", 5, RT_IPC_FLAG_FIFO);if (mailbox == RT_NULL){rt_kprintf("Failed to create mailbox!\n");return -1;}// 創建線程1rt_thread_t thread1 = rt_thread_create("t1", thread1_entry, RT_NULL, 512, 10, 10);if (thread1 != RT_NULL){rt_thread_startup(thread1);}// 創建線程2rt_thread_t thread2 = rt_thread_create("t2", thread2_entry, RT_NULL, 512, 11, 10);if (thread2 != RT_NULL){rt_thread_startup(thread2);}// 等待線程執行完成rt_thread_mdelay(100);// 刪除郵箱rt_mb_delete(mailbox);return 0;
}// 在RT-Thread的初始化中調用示例函數
INIT_APP_EXPORT(mailbox_example);

在這里插入圖片描述


總結

通過本教程,我們深入了解了在RT-Thread中如何有效地使用郵箱進行線程間通信。郵箱作為一種輕量級的消息傳遞機制,為開發者提供了一種靈活而高效的方式來實現不同線程之間的數據傳遞。通過合理地利用郵箱,我們能夠在嵌入式系統和物聯網設備中構建更為可靠和響應的應用程序。希望本教程能夠幫助開發者更好地利用RT-Thread的功能,提升嵌入式系統的開發效率和性能。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/714577.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714577.shtml
英文地址,請注明出處:http://en.pswp.cn/news/714577.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

輸入一個整數,輸出其最長連續因子。

輸入一個整數&#xff0c;輸出其最長連續因子。 例如 輸入&#xff1a;60 輸出&#xff1a;2 3 4 5 6 注意&#xff1a;1不算因子 輸入輸出格式 輸入描述: 輸入一個整數N&#xff0c;N<10000。 輸出描述: 輸出其最長連續因子&#xff0c;如果有多個最長&#xff0c;輸出…

HTML5浮動

1.標準文檔流組成 塊級元素&#xff08;block&#xff09; 內聯元素&#xff08;inline&#xff09; 2.display屬性 作用&#xff1a;指定HTML標簽的顯示方式 常用屬性 值 說明 block 塊級元素的默認值&#xff0c;元素會被顯示為塊級元素&#xff0c;該元素前后會帶有換行…

Linux UnixODBC安裝配置

配置 UnixODBC 夢之上關注IP屬地: 香港 0.2322020.12.09 13:23:10字數 1,202閱讀 5,447 麒麟&達夢適配系列: 1.麒麟服務器上安裝 DM8 2.配置 UnixODBC 3.beego-ORM 適配達夢 資源緊張的時候&#xff0c;服務器是大家共用的&#xff0c;上面部署了一堆服務。所以選用doc…

Lua速成(7)

一、Lua 元表(Metatable) 在 Lua table 中我們可以訪問對應的 key 來得到 value 值&#xff0c;但是卻無法對兩個 table 進行操作(比如相加)。 因此 Lua 提供了元表(Metatable)&#xff0c;允許我們改變 table 的行為&#xff0c;每個行為關聯了對應的元方法。 例如&#xf…

ShardingJdbc實戰-分庫分表

文章目錄 基本配置分庫分表的分片策略一、inline 行表達時分片策略algorithm-expression行表達式完整案例和配置如下 二、根據實時間日期 - 按照標準規則分庫分表標準分片 - Standard完整案例和配置如下 基本配置 邏輯表 邏輯表是指&#xff1a;水平拆分的數據庫或者數據表的相…

SpringBoot實戰(1)

SpringBoot總結 一,Spring 設計思想 OOP: 面向對象編程-》封裝、繼承、多態 BOP: 面向Bean編程-》一切從Bean開始 AOP: 面向切面編程-》解藕、專 人做專事 IOC: 控制反轉,將new 對象的操作交給Spring統一管理-》轉交控制權 DI/DL: 依賴注入/依賴查找-》自動賦值 DI和AOP…

LLVM 一些重要文檔 LLVM 3.0

基于LLVM 3.0: Documentation for the LLVM System at SVN head LLVM 作為庫的使用方法&#xff1a; Using The LLVM Libraries LLVM C 的編程規范&#xff1a; LLVM Coding Standards

stl 迭代器(Iterator)

定義 迭代器&#xff08;Iterator&#xff09;是STL&#xff08;Standard Template Library&#xff0c;標準模板庫&#xff09;中的一個核心概念&#xff0c;用于提供一種通用的方式來遍歷容器&#xff08;如vector、list、map等&#xff09;中的元素&#xff0c;而無需暴露容…

大小端問題

0. 介紹 大小端計算機存儲數據而安排字節的兩種順序。 針對的是字節。 大端與我們平時書寫的順序一致。 1. 大小端的判定 不需要手動判斷。 有一個頭文件endian.h; 可能會有宏 __BYTE_ORDER __BIG_ENDIAN __LITTLE_ENDIAN通過庫來進行判斷。 手動判斷 根據字節存取的順序…

【JSON2WEB】07 Amis可視化設計器CRUD增刪改查

總算到重點中的核心內容&#xff0c;CRUD也就是增刪改查&#xff0c;一個設計科學合理的管理信息系統&#xff0c;95%的就是CRUD&#xff0c;達不到這個比例要重新考慮一下你的數據庫設計了。 1 新增頁面 Step 1 啟動amis-editor Setp 2 新增頁面 名稱和路徑隨便命名&#xf…

Dynamo幕墻探究系列(一)

一直想寫個系列教程&#xff0c;但是沒有那么多時間整理資料&#xff0c;這次呢&#xff0c;先弄個小系列吧&#xff0c;還是和之前差不多的幕墻測試&#xff0c;我們分幾節課&#xff0c;一步一步深入研究。 今天先開個小頭兒&#xff0c;要弄的&#xff0c;就是下面這么個模型…

對象鎖與類鎖

不同鎖互不影響&#xff0c;共用一個鎖&#xff0c;可能會發生阻塞。 1.在修飾靜態方法時&#xff0c;鎖定的是當前類的 Class 對象&#xff0c;在下面的例子中就是SycTest1.class 2.當修飾非靜態方法時&#xff0c;鎖定的就是 this 對象&#xff0c;即當前的實例化對象 public…

【Git教程】(四)版本庫 —— 存儲系統,存儲目錄,提交對象及其命名、移動與復制~

Git教程 版本庫 1?? 一種簡單而高效的存儲系統2?? 存儲目錄&#xff1a;Blob 與 Tree3?? 相同數據只存儲一次4?? 壓縮相似內容5?? 不同文件的散列值相同6?? 提交對象7?? 提交歷史中的對象重用8?? 重命名、移動與復制&#x1f33e; 總結 事實上&#xff0c;我們…

keil MDK安裝armcc V5編譯器

不知道從什么時候開始&#xff0c;Keil MDK默認不支持V5的編譯器了&#xff0c;里面默認只有V6的編譯器&#xff0c;設置界面跟V5有很大的差異不太熟悉。最可怕的是&#xff0c;之前使用V5編譯的工程&#xff0c;換成V6編譯器后居然報錯...雖然修改一下應該也可以正常編譯&…

神經網絡基礎知識:LeNet的搭建-訓練-預測

1.參考視頻&#xff1a; 2.1 pytorch官方demo(Lenet)_嗶哩嗶哩_bilibili 2.總結&#xff1a; &#xff08;1&#xff09;LeNet網絡就是 我最開始用來預測mnist數據集的那個網絡&#xff0c;簡單的2個conv2個maxpool3個linear層 &#xff08;2&#xff09;up主整理的train.py…

SQL面試題(2)

第一題 創建trade_orders表: create table `trade_orders`( `trade_id` varchar(255) NULL DEFAULT NULL, `uers_id` varchar(255), `trade_fee` int(20), `product_id` varchar(255), `time` varchar(255) )ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_…

web自動化筆記九:驗證碼的處理方式

一、驗證碼常用的處理方式 ①、說明&#xff1a;Selenium中并沒有對驗證碼處理的方法&#xff0c;在這里我們介紹一下針對驗證碼的幾種常用處理方式 ②、方式&#xff1a; 1&#xff09;、去掉驗證碼&#xff08;測試環境下采用&#xff09; …

RDD算子介紹

1. RDD算子 RDD算子也叫RDD方法&#xff0c;主要分為兩大類&#xff1a;轉換和行動。轉換&#xff0c;即一個RDD轉換為另一個RDD&#xff0c;是功能的轉換與補充&#xff0c;比如map&#xff0c;flatMap。行動&#xff0c;則是觸發任務的執行&#xff0c;比如collect。所謂算子…

LeetCode 1551.是數組中所有元素相等的最小操作數

存在一個長度為 n 的數組 arr &#xff0c;其中 arr[i] (2 * i) 1 &#xff08; 0 < i < n &#xff09;。 一次操作中&#xff0c;你可以選出兩個下標&#xff0c;記作 x 和 y &#xff08; 0 < x, y < n &#xff09;并使 arr[x] 減去 1 、arr[y] 加上 1 &…

Mac專用投屏工具AirServer 7.27 for Mac中文版2024最新圖文教程

Mac專用投屏工具AirServer 7.27 for Mac中文版是一款適用于Mac的投屏工具&#xff0c;可以將Mac屏幕快速投影到其他設備上&#xff0c;如電視、投影儀、平板等。 Mac專用投屏工具AirServer 7.27 for Mac中文版具有優秀的兼容性&#xff0c;可以與各種設備配合使用。無論是iPhon…