邮箱是一种简单的线程间消息传递方式,特点是开销比较低,效率较高。在 RT-Thread 操作系统的实
现中能够一次传递一个 4 字节大小的邮件,并且邮箱具备一定的存储功能,能够缓存一定数量的邮件数 (邮件数由创建、初始化邮箱时指定的容量决定)。邮箱中一封邮件的最大长度是 4 字节,所以邮箱能够用于不超过 4 字节的消息传递。
例一:
static char mb_pool[128]; /* 用 于 放 邮 件 的 内 存 池 */
sizeof(mb_pool) / 4, /* 邮 箱 中 的 邮 件 数 目, 因 为 一 封 邮件 占 4 字 节 */
例二:
static int mb_pool[128]; /* 用 于 放 邮 件 的 内 存 池 */
sizeof(mb_pool) , /* 邮 箱 中 的 邮 件 数 目, 因 为 一 封 邮件 占 4 字 节 */
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
**************************************************************************************************************************************************************
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
通过一个按键发送一个邮件,按一下发数组1,再按一下发数组2. 接收邮件的线程以数组第一个字节区分邮件。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
邮件的发送
static u16 mb_s1[2] = {0x00BC,0x0012};//高
static u16 mb_s2[2] = {0x00BA,0x00BC};//低
Cap_Run.Long_press=!Cap_Run.Long_press;
if(Cap_Run.Long_press==0)
{
uwRet=rt_mb_send(LED1_mb, (uint32_t)&mb_s2);
}
else
{
uwRet= rt_mb_send(LED1_mb, (uint32_t)&mb_s1);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
邮件的接收
static u16 * mb_r1; //定义一个接收变量 用于接收数组
us_flag=rt_mb_recv(LED1_mb,(rt_ubase_t *)&mb_r1 , 0);// 邮箱接收 强制转换成32位 4字节类型
switch ((u8)mb_r1[0])
{
case 0xBA: //如果邮件的第一个字节是0xBA
us_data=mb_r1[1]; //邮件的第2个字节 赋值给us_data
break;
case 0xBC: //如果邮件的第一个字节是0xBC
us_data=mb_r1[1]; //邮件的第2个字节 赋值给us_data
break;
default :break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
创建邮箱
rt_mailbox_t LED1_mb=RT_NULL;
LED1_mb=rt_mb_create("LED1_mb", 64, RT_IPC_FLAG_FIFO);
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
多收时,一个消息发过来,只有一个会收到,并不是广播形式。具体是哪个收到就要看排队情况了。
*******************************************************************************************************************************************************************
消息队列、邮箱特性:可以一个或多个线程获取一个或多个消息或邮件。
注意点:
第一,FIFO方式排队。消息队列里面的消息、邮箱里面的邮件是按照FIFO方式排列的。
第二、优先级排队。当有多个线程读取消息或邮件时可以支持按优先级谁高谁先读取的原则或者按照FIFO方式读取的。
邮件的发送分为:阻塞方式发送、非阻塞方式发送。前者只能用于线程间发送,后者可以用于线程间发送,中断向线程发送邮件。
每封邮件都是固定大小:4字节,所以它只能发送4字节的数据或者存放数据的地址。不像消息大小用户可设。
邮件框里存放一份邮件,消息框里存放一个消息。邮件框总数、消息框总数有用户定义。不同的是消息总大小包含了一个消息头,每个消息框里都有一个消息头来指向消息。消息总大小:[消息头+消息大小]x消息框总数。而邮件框总数计算就简单了:邮件大小4个字节x邮件框总数。
阻塞发送函数与非阻塞发送函数的区别:非阻塞函数是调用阻塞函数只是超时等待时间参数值为0。
阻塞发送函数:邮箱满了就阻塞当前发送函数,有空邮件了,就被恢复线程,然后接着发送邮件,发送完就恢复因为读取邮箱而被阻塞的线程。
接受函数:当邮箱为空时,挂起当前线程,直到在发送函数里恢复被阻塞的线程,然后接着去读取,读完就恢复因发送被阻塞的线程。
这些线程阻塞的方式在创建邮箱的时候定义的是FIFO方式还是优先级方式。
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value) //非阻塞发送
{
return rt_mb_send_wait(mb, value, 0);
}
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
rt_ubase_t value,
rt_int32_t timeout);//超时发送
————————————————
网友评论