admin管理员组文章数量:1516870
邮箱的使用
邮箱的使用
邮箱工作机制
RT-Thread操作系统的邮箱用于线程间通信,特点是开销比较低,效率较高。邮箱中的每一封邮件只能容纳固定的4字节内容(针对32位处理系统,指针的大小即为4个字节,所以一封邮件恰好能够容纳一个指针)。
线程或中断服务例程把一封4字节长度的邮件发送到邮箱中,而其他需要的线程可以从邮箱中接收这些邮件并进行处理。
如下图:线程和中断服务例程通过邮箱控制块向邮箱队列中发送邮件,另一边线程则在等待线程队列中等待获取邮件。
邮箱控制块
在RT-Thread中,邮箱控制块是操作系统用于管理邮箱的一个数据结构。
/* 在rtdef.h中对结构体的定义 */#ifdef RT_USING_MAILBOX
/*** mailbox structure*/
struct rt_mailbox
{struct rt_ipc_object parent; /**< inherit from ipc_object *///邮箱缓冲区地址rt_uint32_t *msg_pool; /**< start address of message buffer *///邮箱容量rt_uint16_t size; /**< size of message pool *///邮箱中邮件的数目rt_uint16_t entry; /**< index of messages in msg_pool *///邮箱的进出偏移量rt_uint16_t in_offset; /**< input offset of the message buffer */rt_uint16_t out_offset; /**< output offset of the message buffer *///记录挂起的发送邮件的线程rt_list_t suspend_sender_thread; /**< sender thread suspended on this mailbox */
};
typedef struct rt_mailbox *rt_mailbox_t;
#endif
struct rt_mailbox static_mb //定义静态邮箱
rt_mailbox_t dynamic_mb //定义动态信号量
邮箱的操作
初始化与脱离
//用于静态邮箱
rt_err_t rt_mb_init(rt_mailbox_t mb, const char *name, void *msgpool, rt_size_t size, rt_uint8_t flag)
/*
*rt_uint8_t flag的选择:
* RT_IPC_FLAG_FIFO:先进先出顺序
* RT_IPC_FLAG_PRIO:优先级顺序
*/
rt_err_t rt_mb_detach(rt_mailbox_t mb)
创建和删除
//用于动态邮箱
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
rt_err_t rt_mb_delete(rt_mailbox_t mb)
发送邮件
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_uint32_t value);
rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_uint32_t value, rt_int32_t timeout)
/* 发送value邮件 二者差别在于立即返回 还是等待一段时间 */
接收邮件
rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout)
/* 接收value邮件 */
小例
代码
/** 程序清单:邮箱例程** 这个程序会创建2个动态线程,一个静态的邮箱对象,其中一个线程往邮箱中发送邮件,* 另一个线程从邮箱中收取邮件。*/
#include <rtthread.h>#define THREAD_PRIORITY 10
#define THREAD_TIMESLICE 5/* 邮箱控制块 */
static struct rt_mailbox mb;
/* 用于放邮件的内存池 */
static char mb_pool[128];static char mb_str1[] = "I'm a mail!";
static char mb_str2[] = "this is another mail!";
static char mb_str3[] = "over";ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;/* 线程1入口 */
static void thread1_entry(void *parameter)
{/* 用于保存邮件内容 */char *str;while (1){rt_kprintf("thread1: try to recv a mail\n");/* 从邮箱中收取邮件 一直等待 */if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK){rt_kprintf("thread1: get a mail from mailbox, the content:%s\n", str);/* 接收到邮件3后退出 */if (str == mb_str3)break;/* 延时100ms */rt_thread_mdelay(100);}}/* 执行邮箱对象脱离 */rt_mb_detach(&mb);
}ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;/* 线程2入口 */
static void thread2_entry(void *parameter)
{rt_uint8_t count;count = 0;while (count < 10){count ++;/* count为奇数发送邮件1 偶数发送邮件2 */if (count & 0x1){/* 发送mb_str1地址到邮箱中 */rt_mb_send(&mb, (rt_uint32_t)&mb_str1);}else{/* 发送mb_str2地址到邮箱中 */rt_mb_send(&mb, (rt_uint32_t)&mb_str2);}/* 延时200ms */rt_thread_mdelay(200);}/* 发送邮件告诉线程1,线程2已经运行结束 */rt_mb_send(&mb, (rt_uint32_t)&mb_str3);
}int mailbox_sample(void)
{rt_err_t result;/* 初始化一个mailbox */result = rt_mb_init(&mb,"mbt", /* 名称是mbt */&mb_pool[0], /* 邮箱用到的内存池是mb_pool */sizeof(mb_pool) / 4, /* 邮箱中的邮件数目,因为一封邮件占4字节 */RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */if (result != RT_EOK){rt_kprintf("init mailbox failed.\n");return -1;}/* 时间片轮询调度 */rt_thread_init(&thread1,"thread1",thread1_entry,RT_NULL,&thread1_stack[0],sizeof(thread1_stack),THREAD_PRIORITY, THREAD_TIMESLICE);rt_thread_startup(&thread1);rt_thread_init(&thread2,"thread2",thread2_entry,RT_NULL,&thread2_stack[0],sizeof(thread2_stack),THREAD_PRIORITY, THREAD_TIMESLICE);rt_thread_startup(&thread2);return 0;
}/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(mailbox_sample, mailbox sample);
结果
本文标签: 邮箱的使用
版权声明:本文标题:邮箱的使用 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/web/1687859601a150184.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论