【LiteOS】LiteOS消息队列使用总结

LiteOS针对队列读写提供带拷贝和不带拷贝的两种方式,这两种方式在使用上有所区别,如不注意就会入坑,故此总结一下。
消息队列,是一种常用于任务间通信的数据结构,实现了接收来自任务或中断的不固定长度的消息,并根据不同的接口选择传递消息是否存放在自己空间。队列提供一部处理机制,可以起到缓存消息的作用。

队列创建

LiteOS创建队列的函数如下:

UINT32 LOS_QueueCreate(CHAR *pcQueueName,
                             UINT16 usLen,
                             UINT32 *puwQueueID,
                             UINT32 uwFlags,
                             UINT16 usMaxMsgSize);
//usLen    队列长度(消息数量),即队列可以存多少条消息
//uwFlags  队列类型 FIFO or PRIO,暂时保留未用
//usMaxMsgSize  消息最大字节数(消息长度)

注意: LOS_QueueCreate 会根据传入的队列长度、消息长度来动态申请内存空间,用于缓存用户写入队列的数据。usMaxMsgSize 队列消息的最大长度,LiteOS实际在申请空间时,会将该值再加上4,这多出来的4字节空间用于保存消息的实际长度。

UINT16          usMsgSize = usMaxMsgSize + sizeof(UINT32);

不带拷贝读写方式

不带拷贝的读写方式,本质上是将消息的地址存入消息队列中,即4字节的指针。
但是:不带拷贝的读写方式,不会保存消息的长度,即用户是无法传递不定长的消息的。这块应该是LiteOS的一个bug,原则上也是可以保存的,需要修改下源码

不带拷贝的读写函数接口如下:

UINT32 LOS_QueueWrite(UINT32 uwQueueID, 
                        VOID *pBufferAddr, 
                        UINT32 uwBufferSize, UINT32 uwTimeOut)
//pBufferAddr 要写入的数据起始地址
//uwBufferSize 写入长度,在不带拷贝模式下,该值在代码中被固定修改为4字节(指针长度)
//uwTimeOut 超时时间. 0表示不阻塞,最大值为 LOS_WAIT_FOREVER 

UINT32 LOS_QueueRead(UINT32  uwQueueID, 
                        VOID *pBufferAddr, 
                        UINT32 uwBufferSize, UINT32 uwTimeOut)
//pBufferAddr 存储获取到的数据地址(读取的数据要保存的目的位置)
//uwBufferSize 缓冲区长度,大于等于创建队列时的最大消息长度,尽量传入最大值

注意: 不带拷贝的读取函数,需要传入缓存长度uwBufferSize,该值必须初始化为一个大于等于队列最大消息长度的值

带拷贝的读写方式

带拷贝的读写方式,就将指定地址的消息数据全部存入消息队列中,同时队列中也会保存消息的实际长度。
带拷贝的读写函数接口如下:

//带拷贝的写入
UINT32 LOS_QueueWriteCopy(UINT32 uwQueueID,
                            VOID *pBufferAddr,
                            UINT32 uwBufferSize,
                            UINT32 uwTimeOut);
//带拷贝的读取
UINT32 LOS_QueueReadCopy(UINT32 uwQueueID,
                                VOID *pBufferAddr,
                                UINT32 *puwBufferSize,
                                UINT32 uwTimeOut);
// pBufferAddr 缓存地址
// puwBufferSize 通过该指针返回读取到的消息长度。
// 使用前,该变量需要初始为大于等于队列最大消息长度的值(队列创建时指定)
// 该值可以理解为我们将要存储消息的缓存长度,它必须是能够放得下最大长度的消息
//读取结束后,该变量保存之际读取到的消息长度

注意: 带拷贝的读取函数,需要传入指针变量puwBufferSize,函数会通过该指针返回实际读取到的消息长度。但是该指针指向的值,在使用前必须初始化为一个大于等于队列最大消息长度的值
按照如下方式使用队列读取函数:

UINT32 rxLen = 10; //rxLen的初始必须大于队列消息最大长度
uwRet = LOS_QueueReadCopy(QueID,buffer,&rxLen,0);

猜你喜欢

转载自blog.csdn.net/llb19900510/article/details/104842692