在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
周自偉
原文轉自:http://www.anti-gravitydesign.com