消息队列的使用方法.docx
- 文档编号:4016444
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:16
- 大小:18.25KB
消息队列的使用方法.docx
《消息队列的使用方法.docx》由会员分享,可在线阅读,更多相关《消息队列的使用方法.docx(16页珍藏版)》请在冰点文库上搜索。
消息队列的使用方法
uCOSII消息队列的使用方法
需在以下文件中配置如下内容:
OS_CFG.H
OS_MAX_QSN你需要的值
根据需要自己配置
#defineOS_Q_EN1/*Enable
(1)orDisable(0)codegenerationforQUEUES*/
#defineOS_Q_ACCEPT_EN1/*IncludecodeforOSQAccept()*/
#defineOS_Q_DEL_EN1/*IncludecodeforOSQDel()*/
#defineOS_Q_FLUSH_EN1/*IncludecodeforOSQFlush()*/
#defineOS_Q_POST_EN1/*IncludecodeforOSQPost()*/
#defineOS_Q_POST_FRONT_EN1/*IncludecodeforOSQPostFront()*/
#defineOS_Q_POST_OPT_EN1/*IncludecodeforOSQPostOpt()*/
#defineOS_Q_QUERY_EN1/*IncludecodeforOSQQuery()*/
2、建立一个指向消息数组的指针和数组的大小,该指针数组必须申明为void类型,如下:
void*MyArrayOfMsg[SIZE];
3、声明一个OS_EVENT类型的指针指向生成的队列,如下:
OS_EVENT*QSem;
4、调用OSQcreate()函数创建消息队列,如下:
QSem=OSQcreate(&MyArrayOfMsg[0],SIZE);
5、等待消息队列中的消息,OSQPend()。
void*OSQPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err):
必须保证消息队列已经被建立。
timeout定义的是等待超时时间,如果为0则表示无期限的等待
err表示的是在等待消息队列出错时的返回类型,有以下几种:
OS_ERR_PEVENT_NULL//消息队列不存在
OS_ERR_EVENT_TYPE
OS_TIMEOUT//消息队列等待超时
OS_NO_ERR//消息队列接收到消息
获得消息队列示例
type*GETQ;
INT8Uerr;
GETQ=(type*)OSQPend(QSem,time,&err);
if(err==OS_NO_ERR){
无错处理
}
else{
出错处理
}
6.1向消息队列发送一则消息(FIFO),OSQPost();INT8UOSQPost(OS_EVENT*pevent,void*msg):
函数返回值有:
OS_ERR_PEVENT_NULL
OS_ERR_POST_NULL_PTR
OS_ERR_EVENT_TYPE
OS_Q_FULL
OS_NO_ERR
参数:
pevent,*msg
6.2向消息队列发送一则消息(LIFO)INT8UOSQPostFront(OS_EVENT*pevent,void*msg)
6.3向消息队列发送一则消息(LIFO或者FIFO)INT8UOSQPostOpt(OS_EVENT*pevent,void*msg,INT8Uopt)
参数:
opt
如果经opt参数中的OS_POST_OPT_BROADCAST位置为1,则所有正在等待消息的任务都能接收到这则消息,并且被OS_EventTaskRdy()从等待列表中删除
如果不是广播方式,则只有等待消息的任务中优先级最高的任务能够进入就绪态。
然后,OS_EventTaskRdy()从等待列表中把等待消息的任务中优先级最高的任务删除。
注:
如果此函数由ISR调用,则不会发生任务切换,直到中断嵌套的最外层中断服务子程序调用OSIntExit()函数时,才能进行任务切换
7、无等待的从消息队列中获得消息,OSQAccept();void*OSQAccept(OS_EVENT*pevent,INT8U*err)
err可能的返回值:
OS_ERR_PEVENT_NULL
OS_Q_EMPTY
OS_NO_ERR
函数的返回值:
消息,0
8、清空消息队列INT8UOSQFlush(OS_EVENT*pevent)
函数返回值:
OS_ERR_PEVENT_NULL
OS_ERR_EVENT_TYPE
OS_NO_ERR
9、获取消息队列的状态,OSQQuery();INT8UOSQQuery(OS_EVENT*pevent,OS_Q_DATA*p_q_data)
函数返回值:
OS_ERR_PEVENT_NULL
OS_ERR_EVENT_TYPE
OS_NO_ERR
OS_Q_DATA数据结构在ucos_ii.h中
//采用消息队列的ADC采样任务原型代码,建议与uC/OS-II作者的ADC通用例程一起使用
//说明这里消息队列msg_q不用于储存ADC结果。
voidADCTask(void*pParam)
{
char*cmd;
pParam=pParam;
while
(1)
{
cmd=OSQPend(msg_q,100,&err);//waitingforcommand
if(err==OS_NO_ERR)
{
switch(*cmd)
{
case'1':
printf("Command1\n");break;
case'2':
printf("Command2\n");break;
default:
printf("Errorcommand.\n");break;
}
}
else
{//nocommand,thensampling...
if(err==OS_TIMEOUT)//samplingwhiletimeout.
printf("ADCsampling...");
StoreADResult();
}
}
}
数据队列Queue的使用:
数据队列
数据队列一般用于数据缓存,可以用来平衡速率不同的两个部件,使快速部件无需等待慢速部件。
数据队列一般是先入先出的,但本数据队列可以配置成后入先出。
本数据队列是可配置可裁剪的模块,并且不依赖于操作系统,可以在前后台系统中使用。
数据队列使用的空间由用户分配且由这个空间的地址唯一识别一个数据队列。
API函数
数据队列软件模块包括的API函数如下所示:
API函数名功能简介
QueueCreate建立数据队列
QueueRead获取队列中的数据
QueueWrite先进先出方式发送数据
QueueWriteFront后进先出方式发送数据
QueueFlush清空队列
QueueNData取得队列中已存储数据的数据
QueueSize取得队列中总共可以存储的数据数目
/******************************************************************************************
**文件名:
queue.c
**描述:
数据队列的中间件
********************************************************************************************************/
#include"app_cfg.h"
#defineIN_QUEUE
#defineQUEUE_OK1
#defineNOT_OK0
#defineQUEUE_EMPTY2
#defineQUEUE_FULL3
#defineQ_WRITE_MODE4
#defineQ_WRITE_FRONT_MODE5
#defineQUEUE_DATA_TYPEINT8U
typedefstruct{
QUEUE_DATA_TYPE*pOut;/*指向数据输出位置*/
QUEUE_DATA_TYPE*pIn;/*指向数据输入位置*/
QUEUE_DATA_TYPE*pEnd;/*指向Buf的结束位置*/
uint16nBytesPerRec;/*队列中每个记录包含数据个数*/
uint16nMaxRecNum;/*队列可以存储的记录数目*/
uint16nRecNum;/*队列中数据个数*/
uint8(*ReadEmpty)();/*读空处理函数*/
uint8(*WriteFull)();/*写满处理函数*/
QUEUE_DATA_TYPEBuf[1];/*存储数据的空间*/
}DataQueue;
//SizeOfBuf是Buf的字节长度。
//QUEUE_DATA_TYPE是指可定义的数据类型可以Uint8,Uint32,等。
//Queue是DataQueue型结构体。
/*********************************************************************************************************
**函数名称:
QueueCreate
**功能描述:
初始化数据队列
**输入:
Buf:
为队列分配的存储空间地址
**SizeOfBuf:
为队列分配的存储空间大小(字节)
**BytesPerRec:
队列每个记录占用字节数
**ReadEmpty:
为队列读空时处理程序
**WriteFull:
为队列写满时处理程序
**输出:
NOT_OK:
参数错误
**QUEUE_OK:
成功
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************************************************************/
uint8QueueCreate(void*Buf,uint32SizeOfBuf,uint16BytesPerRec,
uint8(*ReadEmpty)(),uint8(*WriteFull)())
{
DataQueue*Queue;
if(Buf!
=NULL&&SizeOfBuf>=(sizeof(DataQueue)))/*判断参数是否有效*/
{
Queue=(DataQueue*)Buf;
/*初始化结构体数据*/
OS_ENTER_CRITICAL();
Queue->nMaxRecNum=(SizeOfBuf-(uint32)(((DataQueue*)0)->Buf))/
BytesPerRec;/*计算队列可以存储的记录数目*/
Queue->pEnd=Queue->Buf+Queue->nMaxRecNum*BytesPerRec;/*计算数据缓冲的结束地址*/
Queue->pOut=Queue->Buf;
Queue->pIn=Queue->Buf;
Queue->nRecNum=0;
Queue->nBytesPerRec=BytesPerRec;
Queue->ReadEmpty=ReadEmpty;
Queue->WriteFull=WriteFull;
OS_EXIT_CRITICAL();
returnQUEUE_OK;
}
else
{
returnNOT_OK;
}
}
/*********************************************************************************************************
**函数名称:
QueueRead
**功能描述:
获取队列中的数据
**输入:
pRet:
存储返回的记录数据的地址
**Buf:
指向队列的指针
**输出:
NOT_OK:
参数错误
**QUEUE_OK:
收到消息
**QUEUE_EMPTY:
无消息
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************************************************************/
uint8QueueRead(uint8*pRet,void*Buf)
{
uint8err;
uint16i;
DataQueue*Queue;
err=NOT_OK;
if(Buf!
=NULL)/*队列是否有效*/
{/*有效*/
Queue=(DataQueue*)Buf;
OS_ENTER_CRITICAL();
if(Queue->nRecNum>0)/*队列是否为空*/
{/*不空*/
for(i=0;i
*pRet++=*Queue->pOut++;/*数据出队*/
/*调整出队指针*/
if(Queue->pOut>=Queue->pEnd)
{
Queue->pOut=Queue->Buf;
}
Queue->nRecNum--;/*数据减少*/
err=QUEUE_OK;
}
else
{/*空*/
err=QUEUE_EMPTY;
if(Queue->ReadEmpty!
=NULL)/*调用用户处理函数*/
{
err=Queue->ReadEmpty(pRet,Queue);
}
}
OS_EXIT_CRITICAL();
}
returnerr;
}
/*********************************************************************************************************
**函数名称:
QueueWrite
**功能描述:
FIFO方式发送数据
**输入:
Buf:
指向队列的指针
**pRec:
写入记录的首地址
**输出:
NOT_OK:
参数错误
**QUEUE_FULL:
队列满
**QUEUE_OK:
发送成功
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************************************************************/
uint8QueueWrite(void*Buf,uint8*pRec)
{
uint8err;
uint16i;
DataQueue*Queue;
err=NOT_OK;
if(Buf!
=NULL)/*队列是否有效*/
{
Queue=(DataQueue*)Buf;
OS_ENTER_CRITICAL();
if(Queue->nRecNum
{/*不满*/
for(i=0;i
*Queue->pIn++=*pRec++;/*数据入队*/
/*调整入队指针*/
if(Queue->pIn>=Queue->pEnd)
{
Queue->pIn=Queue->Buf;
}
Queue->nRecNum++;/*数据增加*/
err=QUEUE_OK;
}
else
{/*满*/
err=QUEUE_FULL;
if(Queue->WriteFull!
=NULL)/*调用用户处理函数*/
{
err=Queue->WriteFull(Queue,*pRec,Q_WRITE_MODE);
}
}
OS_EXIT_CRITICAL();
}
returnerr;
}
/*********************************************************************************************************
**函数名称:
QueueWriteFront
**功能描述:
LIFO方式发送数据
**输入:
Buf:
指向队列的指针
**pRec:
写入记录的首地址
**输出:
QUEUE_FULL:
队列满
**QUEUE_OK:
发送成功
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************************************************************/
uint8QueueWriteFront(void*Buf,uint8*pRec)
{
uint8err;
uint16i;
DataQueue*Queue;
err=NOT_OK;
if(Buf!
=NULL)/*队列是否有效*/
{
Queue=(DataQueue*)Buf;
OS_ENTER_CRITICAL();
if(Queue->nRecNum
{/*不满*/
Queue->pOut--;/*调整出队指针*/
if(Queue->pOut
{
Queue->pOut=Queue->pEnd-1;
}
for(i=0;i
*Queue->pOut--=*(pRec+Queue->nBytesPerRec-1-i);/*数据入队*/
Queue->pOut++;
Queue->nRecNum++;/*数据数目增加*/
err=QUEUE_OK;
}
else
{/*满*/
err=QUEUE_FULL;
if(Queue->WriteFull!
=NULL)/*调用用户处理函数*/
{
err=Queue->WriteFull(Queue,*pRec,Q_WRITE_FRONT_MODE);
}
}
OS_EXIT_CRITICAL();
}
returnerr;
}
/*********************************************************************************************************
**函数名称:
QueueRecNum
**功能描述:
取得队列中记录数
**输入:
Buf:
指向队列的指针
**输出:
消息数
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************************************************************/
uint16QueueRecNum(void*Buf)
{
uint16temp;
temp=0;/*队列无效返回0*/
if(Buf!
=NULL)
{
OS_ENTER_CRITICAL();
temp=((DataQueue*)Buf)->nRecNum;
OS_EXIT_CRITICAL();
}
returntemp;
}
/*********************************************************************************************************
**函数名称:
QueueMaxRecNum
**功能描述:
取得队列记录总容量
**输入:
Buf:
指向队列的指针
**输出:
队列记录总容量
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************************************************************/
uint16QueueMaxRecNum(void*Buf)
{
uint16temp;
temp=0;/*队列无效返回0*/
if(Buf!
=NULL)
{
OS_ENTER_CRITICAL();
temp=((DataQueue*)Buf)->nMaxRecNum;
OS_EXIT_CRITICAL();
}
returntemp;
}
/*********************************************************************************************************
**函数名称:
OSQFlush
**功能描述:
清空队列
**输入:
Buf:
指向队列的指针
**输出:
无
**全局变量:
无
**调用模块:
OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
*************************************************************************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 消息 队列 使用方法