在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
周自伟 |