完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
邮箱机制
跟生活中的例子类似,就是用来发送消息的。RT-Thread 操作系统的邮箱用于线程间通信,特点是开销比较低,效率较高。 邮箱中的每一封邮件只能容纳固定的 4 字节内容(针对 32 位处理系统,指针的大小即为 4 个字节,所以一封邮件恰好能够容纳 一个指针)。典型的邮箱也称作交换消息,一个或多个线程可以从邮箱中接收这些邮件并进行处理。 邮箱中一封邮件的最大长度是 4 字节,所以邮箱能够用于不超过 4 字节的消息传递。由于在 32 系统上 4 字节的内容恰好可以放置一个指针,因此当需要在线程间传递比较大的消息时,可以把指向一个缓冲区的指针作为邮件发送到邮箱中,即邮箱也可以传递指针, 非阻塞方式的邮件发送过程能够安全的应用于中断服务中,是线程、中断服务、定时器向线程发送消息的有效手段。通常来说,邮件收取过程可能是阻塞的,这取决于邮箱中是否有邮件,以及收取邮件时设置的超时时间。 当邮箱中不存在邮件且超时时间不为 0 时,邮件收取过程将变成阻塞方式。在这类情况下,只能由线程进行邮件的收取。当一个线程向邮箱发送邮件时,如果邮箱没满,将把邮件复制到邮箱中。如果邮箱已经满了,发送线程可以设置超时时间,选择等待挂起或直接返回 - RT_EFULL。如果发送线程选择挂起等待,那么当邮箱中的邮件被收取而空出空间来时,等待挂起的发送线程将被唤醒继续发送。 当一个线程从邮箱中接收邮件时,如果邮箱是空的,接收线程可以选择是否等待挂起直到收到新的邮件而唤醒,或可以设置超时时间。当达到设置的超时时间,邮箱依然未收到邮件时,这个选择超时等待的线程将被唤醒并返回 - RT_ETIMEOUT。如果邮箱中存在邮件,那么接收线程将复制邮箱中的 4 个字节邮件到接收缓存中。 邮箱机制管理数据结构 /** * 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; 邮箱的定义 struct rt_mailbox static_mailbox; /*静态邮箱*/ rt_mailbox_t dynamic_mailbox; /*动态邮箱*/ 初始化与脱离-同信号量和互斥锁类似,主要针对静态定义 /** * This function will initialize a mailbox and put it under control of resource * management. * * @param mb the mailbox object * @param name the name of mailbox * @param msgpool the begin address of buffer to save received mail * @param size the size of mailbox * @param flag the flag of mailbox 使用方式 RT_IPC_FLAG_FIFO/RT_IPC_FLAG_RRIO * * @return the operation status, RT_EOK on successful */ rt_err_t rt_mb_init(rt_mailbox_t mb, const char *name, void *msgpool, rt_size_t size, rt_uint8_t flag) /** * This function will detach a mailbox from resource management * * @param mb the mailbox object * * @return the operation status, RT_EOK on successful */ rt_err_t rt_mb_detach(rt_mailbox_t mb) 创建和删除-针对动态定义 /** * This function will create a mailbox object from system resource * * @param name the name of mailbox * @param size the size of mailbox * @param flag the flag of mailbox 使用方式 RT_IPC_FLAG_FIFO/RT_IPC_FLAG_RRIO * * @return the created mailbox, RT_NULL on error happen */ rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag) /** * This function will delete a mailbox object and release the memory * * @param mb the mailbox object * * @return the error code */ rt_err_t rt_mb_delete(rt_mailbox_t mb) 发送邮件 如果是在4个字节内那么就可以直接将数据放到value中发送,如果大于4个字节,则可以发送数据的首地址 /** 在中断中使用会导正系统阻塞 * This function will send a mail to mailbox object. If the mailbox is full, * current thread will be suspended until timeout. * * @param mb the mailbox object * @param value the mail * 如果邮箱已满则就等待timeout的时间 * @param timeout the waiting time * @return the error code */ rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_uint32_t value, rt_int32_t timeout) /** 如果邮箱已满则返回false 可以在线程中使用也可以在中断中使用 * This function will send a mail to mailbox object, if there are threads * suspended on mailbox object, it will be waked up. This function will return * immediately, if you want blocking send, use rt_mb_send_wait instead. * * @param mb the mailbox object * @param value the mail * * @return the error code */ rt_err_t rt_mb_send(rt_mailbox_t mb, rt_uint32_t value) 接收邮件 /** * This function will receive a mail from mailbox object, if there is no mail * in mailbox object, the thread shall wait for a specified time. * * @param mb the mailbox object * @param value the received mail will be saved in * @param timeout the waiting time * * @return the error code */ rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout) 参考官网示例 /* * 这个程序会创建2个动态线程,一个静态的邮箱对象,其中一个线程往邮箱中发送邮件, * 一个线程往邮箱中收取邮件。 */ #include #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 mailn"); /* 从邮箱中收取邮件 */ if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK) { rt_kprintf("thread1: get a mail from mailbox, the content:%sn", str); 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 ++; 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; } |
|
|
|
只有小组成员才能发言,加入小组>>
3280 浏览 9 评论
2958 浏览 16 评论
3460 浏览 1 评论
9004 浏览 16 评论
4052 浏览 18 评论
1115浏览 3评论
573浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
571浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2303浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1859浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 13:59 , Processed in 1.506645 second(s), Total 80, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号