当前位置:网站首页>RT_ Use of thread mailbox
RT_ Use of thread mailbox
2022-07-28 04:53:00 【The endeavor】
One 、 Mailbox working mechanism
RT_thread The mailbox in the operating system is used for inter thread communication , It is characterized by low cost , High efficiency . Each email in the mailbox can only hold fixed 4 Byte content ( in the light of 32 Bit processing system . The size of the pointer is 4 byte , So an email can just hold a pointer )
A thread or interrupt service routine sends a 4 Bytes of mail is sent to the mailbox , Other threads can receive and process these messages through the mailbox .
Mailbox control block :
RT-Thread Using mailbox to realize thread asynchronous communication , Has the following characteristics :
Mail supports first in first out queuing and priority queuing , Support asynchronous read-write mode .
Both sending and receiving email support timeout mechanism .
A thread can receive and send mail from any message queue .
Multiple threads can send and receive mail to and from the same mailbox .
Each email in the mailbox can only hold fixed 4 Byte content ( Can store address ).
When the queue is finished , You need to delete the mailbox to free memory .
Mailboxes are very similar to message queues , The length of messages in the message queue can be configured by users , But the size of the mail in the mailbox can only be fixed 4 The contents of bytes , therefore , The cost of using email is very small , Because what can only be passed is 4 Contents within bytes , Then its efficiency will be higher .
Operating mechanism
When creating a mailbox object, a mailbox object control block will be created first , And then to The mailbox allocates a piece of memory space for storing mail , This piece of The size of memory is equal to the size of mail (4 byte ) Product of mailbox capacity , Then initialize the offset of received mail and sent mail in the mailbox , Then initialize the message queue , The message queue is empty .
Thread or interrupt service program can send mail to mailbox , Non blocking mail sending process can be safely applied to interrupt service , Interrupt service function 、 Timers are an effective means of sending messages to threads , However, blocking mail sending can only be applied to threads . When sending mail , It can only be sent when the mailbox is not full , If the mailbox is full , You can wait according to the waiting time set by the user , When mail in the mailbox is collected and space is made available , Waiting for the suspended sending thread to be awakened to continue the sending process , When the waiting time is up and the email has not been sent yet , Or wait time is not set , Failed to send mail at this time , The thread sending the mail or the interrupt program will receive an error code (-RT_EFULL). Threads can send mail with blocking , But you can't send mail in any way with blocking during interruption .
Two 、 Operation of mailbox
1、RT-Thread There are two ways to create a mailbox : Dynamically create 、 initiate static .
The system function of dynamically creating a mailbox is as follows , When calling this function to create a mailbox , The kernel will first allocate a mailbox object from the object manager , Then create a mailbox control block , Then initialize the mailbox control block , Include mailbox buffer address 、 Number of messages 、 The offset of sending mail in the mailbox, etc .
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag);
(1) Entrance parameters :
name: E-mail name .
size: Mailbox capacity .
flag: Mailbox logo , It can take the following values :RT_IPC_FLAG_FIFO or RT_IPC_FLAG_PRIO.
(2) Return value :
RT_NULL: Create failure .
Handle to mailbox object : Create success .
2. Delete the dynamic mailbox function : When used rt_mb_create() When the created mailbox is no longer used , It should be deleted to release the corresponding system resources , Once the operation is complete , The mailbox will be permanently deleted . When deleting mailbox , If a thread is suspended on the mailbox object , The kernel first wakes up all threads suspended on the mailbox ( The return value of the thread is RT_ERROR), Then free the memory used by the mailbox , Finally, delete the mailbox object . The function interface of deleting mailbox is as follows :
rt_err_t rt_mb_delete (rt_mailbox_t mb);
(1) Entrance parameters :
mb: Handle to the mailbox object to delete .
(2) Return value :
RT_EOK: success .
3、 Create a static mailbox function :
This is about creating static mailboxes and 《RT-Thread Programming Guide 》 The initialization mailbox is the same , It is similar to dynamically creating mailboxes , Just initialize the mailbox for the initialization of static mailbox objects . Unlike creating mailboxes , The memory of the static mailbox object is allocated by the compiler when the system is compiled , It is generally placed in read-write data segments or uninitialized data segments , The rest of the initialization work is the same as when creating the mailbox . When initializing mailbox , The function interface needs to obtain the mailbox object control block that the user has applied for , Pointer to the buffer , And mailbox name and mailbox capacity ( Number of messages that can be stored ). The function interface is as follows :
rt_err_t rt_mb_init(rt_mailbox_t mb,
const char *name,
void *msgpool,
rt_size_t size,
rt_uint8_t flag);
1) Entrance parameters :
mb: Handle to mailbox object .
name: E-mail name .
msgpool: Buffer pointer .
size: Mailbox capacity .
flag: Mailbox logo , It can take the following values :RT_IPC_FLAG_FIFO or RT_IPC_FLAG_PRIO.
(2) Return value :
RT_EOK: success .
Be careful : there size Parameter specifies the capacity of the mailbox , That is, if msgpool The number of bytes of the buffer pointed to is N, Then the mailbox capacity should be N/4.
4、 Delete the static mailbox function : Delete static mailbox and 《RT-Thread Programming Guide 》 What I said about leaving the mailbox is the same , Detaching the mailbox will detach the statically initialized mailbox object from the kernel object manager , The kernel first wakes up all threads hanging on the mailbox ( The return value obtained by the thread is RT_ERROR), Then detach the mailbox object from the kernel object manager . Leave the mailbox and use the following interface :
rt_err_t rt_mb_detach(rt_mailbox_t mb);
(1) Entrance parameters :
mb: Handle to mailbox object .
(2) Return value :
RT_EOK: success .
5、 Send mail function : Thread or interrupt service program can send mail to other threads through mailbox , The email sent can be 32 Bit arbitrary format data , An integer value or a pointer to a buffer . When the mailbox is full , The thread sending the mail or the interrupt program will receive RT_EFULL The return value of . The function interface is as follows :
rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32_t value);
(1) Entrance parameters :
mb: Handle to mailbox object .
value: Email content .
(2) Return value :
RT_EOK: Send successfully .
RT_EFULL: The mailbox is full .
6、 Wait mode send mail function : Users can also send mail to the specified mailbox through the following function interface :
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
rt_uint32_t value,
rt_int32_t timeout);
rt_mb_send_wait() And rt_mb_send() The difference is that there is waiting time , If the mailbox is full , Then the sending thread will be based on the set timeout Parameter waits for space in the mailbox to be vacated due to receiving mail . If the set timeout time reaches, there is still no free space , At this time, the sending thread will wake up and return the error code .
(1) Entrance parameters :
mb: Handle to mailbox object .
value: Email content .
timeout: Timeout time .
(2) Return value :
RT_EOK: Send successfully .
RT_ETIMEOUT: Overtime .
RT_ERROR: Failure , Returns an error .
7、 Receive mail function : When receiving mail , The recipient needs to specify the mailbox handle to receive the mail , And specify the storage location of the received mail and the maximum timeout time that can be waited . The function interface of receiving mail is as follows :
rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32_t* value, rt_int32_t timeout);
(1) Entrance parameters :
mb: Handle to mailbox object .
value: Email content .
timeout: Timeout time .
(2) Return value :
RT_EOK: Send successfully .
RT_ETIMEOUT: Overtime .
RT_ERROR: Failure , Returns an error .
3、 ... and 、 be based on STM32 Email example for
use RTT& Punctual atom co produces Pandora development board , be based on STM32. Create a mailbox , Two threads , One thread is used to send mail , Another thread receives mail . Send different email contents by pressing different keys , Perform different operations according to the contents of the right email . When the content read is KEY0 Illuminates when pressed RGB A red light , Other extinguish , When the content read is KEY1 Illuminates when pressed RGB Blue light , Other extinguish , When the content read is KEY0 Illuminates when pressed RGB A green light , Other extinguish .
#include "rtthread.h"
#include "string.h"
#include "mailbox_app.h"
#include "led.h"
#include "key.h"
/* Thread handle */
static rt_thread_t thread1 = RT_NULL;
static rt_thread_t thread2 = RT_NULL;
/* Mailbox handle */
static rt_mailbox_t mailbox1 = RT_NULL;
char mailbox_msg_key0_press[] = "mailbox_msg_key0_press";
char mailbox_msg_key1_press[] = "mailbox_msg_key1_press";
char mailbox_msg_key2_press[] = "mailbox_msg_key2_press";
/************************************************************** The name of the function : thread1_recv_mailbox_msg The functionality : Threads 1 Entry function , For receiving mail Input parameters : parameter: Entrance parameters Return value : nothing remarks : nothing **************************************************************/
void thread1_recv_mailbox_msg(void *parameter)
{
char *mb_msg;
while(1)
{
if(rt_mb_recv(mailbox1, (rt_uint32_t *)&mb_msg, RT_WAITING_FOREVER) == RT_EOK)
{
rt_kprintf("recv mb_msg:%s\r\n", mb_msg);
if(0 == strcmp(mb_msg, "mailbox_msg_key0_press"))
{
LED_R(0);
LED_B(1);
LED_G(1);
}
else if(0 == strcmp(mb_msg, "mailbox_msg_key1_press"))
{
LED_R(1);
LED_B(0);
LED_G(1);
}
else if(0 == strcmp(mb_msg, "mailbox_msg_key2_press"))
{
LED_R(1);
LED_B(1);
LED_G(0);
}
}
rt_thread_mdelay(1);
}
}
/************************************************************** The name of the function : thread2_send_mailbox_msg The functionality : Threads 2 Entry function , For sending mail Input parameters : parameter: Entrance parameters Return value : nothing remarks : nothing **************************************************************/
void thread2_send_mailbox_msg(void *parameter)
{
u8 key;
while(1)
{
key = key_scan(0);
if(key== KEY0_PRES)
{
rt_mb_send(mailbox1, (rt_uint32_t)&mailbox_msg_key0_press);
}
else if(key== KEY1_PRES)
{
rt_mb_send(mailbox1, (rt_uint32_t)&mailbox_msg_key1_press);
}
else if(key== KEY2_PRES)
{
rt_mb_send(mailbox1, (rt_uint32_t)&mailbox_msg_key2_press);
}
rt_thread_mdelay(1);
}
}
void rtthread_mailbox_test(void)
{
mailbox1 = rt_mb_create("mailbox1", 12, RT_IPC_FLAG_FIFO); /* FIFO Pattern */
if(mailbox1 != RT_NULL)
{
rt_kprintf("RT-Thread create mailbox successful\r\n");
}
else
{
rt_kprintf("RT-Thread create mailbox failed\r\n");
return;
}
thread1 = rt_thread_create("thread1",
thread1_recv_mailbox_msg,
NULL,
512,
3,
20);
if(thread1 != RT_NULL)
{
rt_thread_startup(thread1);;
}
else
{
rt_kprintf("create thread1 failed\r\n");
return;
}
thread2 = rt_thread_create("thread2",
thread2_send_mailbox_msg,
NULL,
1024,
2,
20);
if(thread2 != RT_NULL)
{
rt_thread_startup(thread2);;
}
else
{
rt_kprintf("create thread2 failed\r\n");
return;
}
}
Four 、 Use occasions and skills of mailbox
Mailbox is a simple way of message transmission between threads , The characteristic is that the cost is relatively low , More efficient . stay RT-Thread The implementation of the operating system can pass one at a time 4 Byte sized mail , And the mailbox has a certain storage function , A certain number of messages can be cached ( Number of messages created by 、 The capacity specified when initializing the mailbox determines ). The maximum length of a message in the mailbox is 4 byte , So mailboxes can be used for no more than 4 Byte messaging .
Because in 32 On the system 4 The contents of the byte can just place a pointer , Therefore, when a large message needs to be delivered between threads , You can send a pointer to a buffer as a mail to the mailbox , That is, the mailbox can also pass pointers , for example :
struct msg
{
rt_uint8_t *data_ptr;
rt_uint32_t data_size;
};
For such a message structure , It contains pointers to data data_ptr And block length data_size. When one thread needs to send this message to another thread , The following operations can be used :
struct msg* msg_ptr;
msg_ptr = (struct msg*)rt_malloc(sizeof(struct msg));
msg_ptr->data_ptr = ...; /* finger towards phase Should be Of Count According to the block The earth site */
msg_ptr->data_size = len; /* Count According to the block Of Long degree */
/* Hair send this individual eliminate Rest finger The needle to mb Post box */
rt_mb_send(mb, (rt_uint32_t)msg_ptr);
Apply for memory space of structure size , The returned pointer points to the structure , When the information in the structure is processed , Then the pointer to the structure can be sent to the mailbox as a mail , The reading operation of the structure information is completed in the thread receiving the mail , Memory should be freed after the operation , Because what you receive is a pointer , and msg_ptr Is a newly allocated memory block , So after the receiving thread finishes processing , The corresponding memory block needs to be released :
struct msg* msg_ptr;
if (rt_mb_recv(mb, (rt_uint32_t*)&msg_ptr) == RT_EOK)
{
/* stay Pick up closed Line cheng It's about The reason is End BI after , Need to be want Interpretation of the discharge phase Should be Of Inside save block */
rt_free(msg_ptr);
}
边栏推荐
- Strlen introduction, and the difference between sizeof
- [Sylar] framework chapter -chapter10-address module
- Phpstorm2022 connect to the database
- 【sylar】实战篇-基于 redis 的参数查询服务
- If mongoose exists, it will be updated; if it does not exist, it will be added
- could only be written to 0 of the 1 minReplication nodes. There are 0 datanode(s) running and 0 node
- Ma Yi, Shen Xiangyang, Cao Ying's latest AI overview is hot! It took 3 months to build, netizens: required papers
- Mac installs mysql5.7 through brew
- set与list性能对比
- [Sylar] practical part - redis based parameter query service
猜你喜欢

全方位分析STEAM和创客教育的差异化
![[daily one] visual studio2015 installation in ancient times](/img/b1/066ed0b9e93b8f378c89ee974163e5.png)
[daily one] visual studio2015 installation in ancient times

Ma Yi, Shen Xiangyang, Cao Ying's latest AI overview is hot! It took 3 months to build, netizens: required papers
![(3.1) [Trojan horse synthesis technology]](/img/e7/0e09c1d1bac23022ead7478ea9898a.png)
(3.1) [Trojan horse synthesis technology]

你必需要了解的saas架构设计?

Wang Shuang assembly language detailed learning notes 3: registers (memory access)

启发国内学子学习少儿机器人编程教育

go-zero单体服务使用泛型简化注册Handler路由

After a year of unemployment, I learned to do cross-border e-commerce and earned 520000. Only then did I know that going to work really delayed making money!

Histogram of pyplot module of Matplotlib (hist(): basic parameter, return value)
随机推荐
塑料可以执行GB/T 2408 -燃烧性能的测定吗
[Sylar] framework -chapter11 socket module
Strlen introduction, and the difference between sizeof
(2.4) [service Trojan -slimftp] introduction and use
MySQL partition table transformation
Explain initialization list
Do you know several assertion methods commonly used by JMeter?
低代码是开发的未来吗?浅谈低代码平台
Cmake usage base summary
王爽汇编语言详细学习笔记三:寄存器(内存访问)
String 0123456789abcdef, what is the number of substrings (not empty and not the same string itself) [Hangzhou multi tester] [Hangzhou multi tester _ Wang Sir]
Inspire domestic students to learn robot programming education for children
Leetcode 18. sum of four numbers
Analysis of the reason why easycvr service can't be started and tips for dealing with easy disk space filling
FPGA:使用PWM波控制LED亮度
Internet of things industrial serial port to WiFi module wireless routing WiFi module selection
If mongoose exists, it will be updated; if it does not exist, it will be added
CPU and memory usage are too high. How to modify RTSP round robin detection parameters to reduce server consumption?
What should testers know about login security?
Destructor of member function