在uclinux下采用vxworks接口定义实现的消息队列代码
时间:2005-02-23 来源:workants
在uclinux下采用vxworks接口定义实现的消息队列代码。
/*msgQ.h*/
#define INUSE
#define NOUSE
#define USE
#define NO
#define ERROR (-1)
#define OK (0)
#define TRUE (1)
#define FALSE (0)
#undef NULL
#define NULL (0)
#define MUST_BE_ZERO (0)
#define NO_WAIT (0)
#define WAIT_FOREVER (-1)
/*包含消息队列模块*/
#define _INC_MSG_Q_
#ifdef _INC_MSG_Q_
/******************************************************
函数名:msgQDelete
功能:删除linux消息队列
引用全局变量:
输入参数说明:
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int msgQDelete
(
INUSE int msgQId /* message queue to delete */
);
/******************************************************
函数名:msgQCreate
功能:创建linux消息队列
返回值说明:成功返回msgQid, 失败将返回NULL
*******************************************************/
int msgQCreate
(
INUSE int maxMsgs, /*最大消息个数*/
INUSE int maxMsgLength,/*单个消息最大长度*/
NOUSE int options/*选项,linux未使用*/
);
/******************************************************
函数名:msgQSend
功能:向linux消息队列发送消息
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int msgQSend
(
INUSE int msgQId, /* 队列id */
INUSE char * buffer, /* 发送缓冲 */
INUSE unsigned int nBytes, /* 缓冲区长度 */
INUSE int timeout, /* NO_WAIT(队列满时立即返回),
WAIT_FOREVER(队列满时将阻塞,直到队列有空间) */
NOUSE int option /* 对于linux,该项无效*/
);
/******************************************************
函数名:msgQReceive
功能:从linux消息队列接收消息
返回值说明:成功返回消息大小, 失败将返回ERROR(-1)
*******************************************************/
int msgQReceive
(
INUSE int msgQId, /* 队列id */
INUSE char * buffer, /* 接收缓冲 */
INUSE unsigned int maxNBytes, /* 缓冲区长度 */
INUSE int timeout /* NO_WAIT(队列空时立即返回),WAIT_FOREVER(队列空时将阻塞,直到队列不为空) */
);
/******************************************************
函数名:msgQNumMsgs
功能:获取linux消息队列中当前消息个数
返回值说明:成功将返回消息个数, 失败将返回ERROR(-1)
*******************************************************/
int msgQNumMsgs
(
INUSE int msgQId /* message queue to examine */
);
#endif
/*msgQ.c*/
#include <signal.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <asm/ioctl.h>
//#include <time.h>
#include <errno.h>
//#include <sys/time.h>
#include <linux/rtc.h>
#include <sys/syscall.h>
#include <sys/msg.h>
#include <asm/param.h>
#include <semaphore.h>
#include <sched.h>
#include <sys/time.h>
#include "platform.h"
int taskSpawn
(
NO char * name, /* 任务的名称 */
USE int priority, /* 实时任务的优先级 1-99 */
NO int options, /* 选项 */
USE int stackSize, /* 任务堆栈的大小 */
USE void * (*entryPt)(void *), /* 任务的函数入口 */
USE int arg1, /* 这是一个指针值,任务入口函数的入参 */
NO int arg2, /*下面的参数不使用*/
NO int arg3,
NO int arg4,
NO int arg5,
NO int arg6,
NO int arg7,
NO int arg8,
NO int arg9,/*指定fifo 、rr或者normal调度方法*/
NO int arg10 /*nice值*/
)
{
int nRet = 0;
struct sched_param tSchParam;
pthread_attr_t tThreadAttr;
pthread_t thread_id;
int nSchPolicy;
int ps;/*pagesize*/
/*判断优先级的正确性
if (priority > sys_sched_get_priority_max(SCHED_FIFO)
||priority < sys_sched_get_priority_min(SCHED_FIFO))
{
printf("priority must be between %d and %dn",
sys_sched_get_priority_min(SCHED_FIFO),
sys_sched_get_priority_max(SCHED_FIFO));
return ERROR;
}*/
/*判断优先级的正确性*/
if (priority > 99 || priority < 0)
{
//printf("priority must be between 0 and 99n");
return ERROR;
}
/*初始化线程参数*/
pthread_attr_init(&tThreadAttr);
/*设置使用tThreadAttr指定的参数,而不是从调用任务那继承*/
tThreadAttr.__inheritsched = PTHREAD_EXPLICIT_SCHED;
/*设置调度策略*/
pthread_attr_getschedpolicy(&tThreadAttr, &nSchPolicy);
nSchPolicy = arg9;/*创建的所有任务都将是实时任务*/
pthread_attr_setschedpolicy(&tThreadAttr, nSchPolicy);
/*设置进程为分离状态,任务分离后将不需要用pthread_join()等待
pthread_attr_setdetachstate(&tThreadAttr, PTHREAD_CREATE_DETACHED);*/
if (arg9 == SCHED_FIFO || arg9 == SCHED_RR)
{
/* 设置实时任务的优先级*/
pthread_attr_getschedparam(&tThreadAttr, &tSchParam);
tSchParam.sched_priority = priority;
pthread_attr_setschedparam(&tThreadAttr, &tSchParam);
}
else
{
}
/*设置堆栈的大小*/
ps = __getpagesize ();
tThreadAttr.__stacksize = stackSize - ps;
nRet = pthread_create(&thread_id, &tThreadAttr, entryPt, (void *)arg1);
if(nRet != OK)
{
perror(NULL); print(__FILE__, __LINE__,name);
return ERROR;
}
else
{
return thread_id;
}
}
int taskDelete
(
int tid /* task ID of task to delete */
)
{
if (pthread_cancel(tid) == ERROR)
{
perror(NULL); print(__FILE__, __LINE__,"taskDeleten");
return ERROR;
}
return OK;
}
/*当linux线程被取消的时候将执行的指定函数*/
#define taskDeleteHookAdd
(
(void*) deleteHook /* routine to be called when a task is deleted */
)
{
struct _pthread_cleanup_buffer buffer;
_pthread_cleanup_push(&buffer, deleteHook, NULL);
}
/*对linux线程进行的操作*/
void initLinuxTask()
{
/*设置进程可被其他线程杀死,具体可通过在linux下
执行man pthread_setcancelstate来获得帮助*/
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/*设置线程收到中止信号后立即中止, 不需要等执行到到取消点*/
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}
int taskDelay
(
int ticks /* number of ticks to delay task */
)
{
sleep(1);
return OK;
//udelay(111);
//mdelay((1000/CLOCKS_PER_SEC)*ticks);
}
#ifdef _INC_MSG_Q_
/******************************************************
函数名:msgQDelete
功能:删除linux消息队列
引用全局变量:
输入参数说明:
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int msgQDelete
(
INUSE int msgQId /* message queue to delete */
)
{
return msgctl(msgQId, IPC_RMID, NULL);
}
/******************************************************
函数名:msgQCreate
功能:创建linux消息队列
返回值说明:成功返回msgQid, 失败将返回NULL
*******************************************************/
int msgQCreate
(
INUSE int maxMsgs, /*最大消息个数*/
INUSE int maxMsgLength,/*单个消息最大长度*/
NOUSE int options/*选项,linux未使用*/
)
{
int msgQid = 0;
struct msqid_ds msg_info;
/*创建了一个消息队列,0666指定了访问权限,所有进程都可以访问*/
msgQid = msgget(IPC_PRIVATE, IPC_CREAT|IPC_EXCL|0666);
if(msgQid == -1)
{
return NULL;
}
/*获取消息队列的属性*/
if (msgctl(msgQid,IPC_STAT,&msg_info) == ERROR)
{
msgctl(msgQid, IPC_RMID, NULL);/*删除队列*/
return NULL;
}
/*根据入参调整消息队列的属性*/
msg_info.msg_qbytes = maxMsgLength*maxMsgs;/*消息队列的最大长度*/
if (msgctl(msgQid, IPC_SET, &msg_info) == ERROR)/*调整队列属性失败*/
{
msgctl(msgQid, IPC_RMID, NULL);/*删除队列*/
return NULL;
}
return msgQid;
}
/******************************************************
函数名:msgQSend
功能:向linux消息队列发送消息
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int msgQSend
(
INUSE int msgQId, /* 队列id */
INUSE char * buffer, /* 发送缓冲 */
INUSE unsigned int nBytes, /* 缓冲区长度 */
INUSE int timeout, /* NO_WAIT(队列满时立即返回),
WAIT_FOREVER(队列满时将阻塞,直到队列有空间) */
NOUSE int option /* 对于linux,该项无效*/
)
{
struct msgbuf
{
int mtype;
char mtext[nBytes];
}buf;
memcpy(buf.mtext,buffer,nBytes);
buf.mtype = 10;
if (timeout == NO_WAIT)
{
return msgsnd(msgQId, &buf, nBytes, IPC_NOWAIT);
}
else if (timeout == WAIT_FOREVER)
{
return msgsnd(msgQId, &buf, nBytes, 0);
}
else
{
return msgsnd(msgQId, &buf, nBytes, 0);
}
}
/******************************************************
函数名:msgQReceive
功能:从linux消息队列接收消息
返回值说明:成功返回消息大小, 失败将返回ERROR(-1)
*******************************************************/
int msgQReceive
(
INUSE int msgQId, /* 队列id */
INUSE char * buffer, /* 接收缓冲 */
INUSE unsigned int maxNBytes, /* 缓冲区长度 */
INUSE int timeout /* NO_WAIT(队列空时立即返回),WAIT_FOREVER(队列空时将阻塞,直到队列不为空) */
)
{
int rcvLen;
struct msgbuf
{
int mtype;
char mtext[maxNBytes];
}buf;
if (timeout == NO_WAIT)
{
rcvLen = msgrcv(msgQId, &buf, maxNBytes, 0, IPC_NOWAIT);
}
else if (timeout == WAIT_FOREVER)
{
rcvLen = msgrcv(msgQId, &buf, maxNBytes, 0, 0);
}
else
{
rcvLen = msgrcv(msgQId, &buf, maxNBytes, 0, 0);
}
if(rcvLen == ERROR)
{
return ERROR;
}
memcpy(buffer, buf.mtext, rcvLen);
return rcvLen;
}
/******************************************************
函数名:msgQNumMsgs
功能:获取linux消息队列中当前消息个数
返回值说明:成功将返回消息个数, 失败将返回ERROR(-1)
*******************************************************/
int msgQNumMsgs
(
INUSE int msgQId /* message queue to examine */
)
{
struct msqid_ds msg_info;
if (msgctl(msgQId,IPC_STAT,&msg_info) == ERROR)
{
return ERROR;
}
else
{
return msg_info.msg_qnum;
}
}
#endif
周自伟