知道了消息队列的原理,创建消息队列搭建了一个什么东西,就好理解其他几个操作的函数的含义了。
1、消息队列的创建:
rt_mq_t rt_mq_create(const char * name, //消息队列的名称
rt_size_t msg_size, //消息队列中一条消息的最大长度,单位字节
rt_size_t max_msgs, //消息队列的最大个数
rt_uint8_t flag) //消息队列采用的等待方式
//可以取值:RT_IPC_FLAG_FIFO
// 或RT_IPC_FLAG_PRIO
创建消息队列,根据给的几个参数,创建一个空闲的消息队列,组成消息块链表,
内存的大小= [消息大小+消息头(用于链表连接)] *消息队列最大个数
返回消息队列的句柄
rt_err_t rt_mq_init(rt_mq_t mq, //消息队列句柄
const char *name, //消息队列名称
void *msgpool, //存放消息队列区域的地址的指针
rt_size_t msg_size, //消息队列中一条消息的最大长度,单位字节
rt_size_t pool_size, //存放消息的缓冲区大小
rt_uint8_t flag) //消息队列采用的等待方式
//可以取值:RT_IPC_FLAG_FIFO
// 或RT_IPC_FLAG_PRIO
2、消息队列的删除
rt_err_t rt_mq_detach(rt_mq_t mq)
rt_err_t rt_mq_delete(rt_mq_t mq)
使用该函数接口后,
内核先唤醒所有挂在该消息等待队列对象上的线程(返回值是 - RT_ERROR ),
然后将该消息队列对象从内核对象管理器中删除。
rt_mq_delete在删除前会把消息队列的内存释放掉再删除。
3、发送消息进入消息队列
rt_err_t rt_mq_send_wait(rt_mq_t mq, //mq是指向要发送的消息队列对象的指针
const void *buffer, //buffer是消息的内容
rt_size_t size, //消息的长度(单位:字节)
rt_int32_t timeout) //timeout为超时时间,单位为系统的tick
发送消息进入消息队列会进行这些判断
判断消息队列是否为空?
-->空:写入成功
-->不空:-->返回失败
-->等待一段时间:-->另一个线程读的时候,唤醒陷入等待的线程
-->等待超时,返回失败
当线程选择等待一段时间的时候,会做一下几步操作:
1、会先把自己从系统的readylist里面移除,不在系统的待运行的线程列表里面了。
2、将自己放进mq->parent->suspend_thread 里面,
3、启动线程自己的定时器
当线程等待过程中,有其他线程把数据从消息队列里面读走,会唤醒mq->parent->suspend_thread 里面的线程,这时候这个线程就会再次启动。
若一直没其他线程唤醒,超时之后,线程会把自己的状态修改为TIMEOUT(也许实际不这么写),返回
其他两个发送消息的函数:
rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)
rt_mq_send( ) 其实就是timeout为0的 rt_mq_send_wait( )
rt_mq_urgent( ) 和普通的发送函数的区别是,将最新的消息插入到消息队列的最头部,这样,下一个读队列的函数就会立刻获取到这个消息
4、从消息队列接收消息
rt_err_t rt_mq_recv(rt_mq_t mq, //mq是指向要发送的消息队列对象的指针
const void *buffer, //buffer是消息的内容
rt_size_t size, //消息的长度(单位:字节)
rt_int32_t timeout) //timeout为超时时间,单位为系统的tick
接收消息进入消息队列会进行这些判断
判断消息队列是否为空?
-->不空:读取成功
-->空: -->返回失败
-->等待一段时间:-->另一个线程写的时候,唤醒陷入等待的线程
-->等待超时,返回失败
当线程选择等待一段时间的时候,会做一下几步操作:
1、会先把自己从系统的readylist里面移除,不在系统的待运行的线程列表里面了。
2、将自己放进mq->parent->suspend_thread 里面,
3、启动线程自己的定时器
当线程等待过程中,有其他线程把数据写入消息队列里,会唤醒mq->parent->suspend_thread 里面的线程,这时候这个线程就会再次启动。
若一直没其他线程唤醒,超时之后,线程会把自己的状态修改为TIMEOUT(也许实际不这么写),返回