📄 vxworks2linux.c
字号:
/************************************************************************************
Copyright (c) 1999-2006 Zhejiang Nanwang
Multimedia Information CO. LTD.
PROPRIETARY RIGHTS of Zhejiang Nanwang Multimedia Information
CO., LTD.are involved in the subject matter of this material.
All manufacturing, reproduction, use, and sales rights pertaining to
this subject matter are governed by the license agreement.
******************************************************************************************
FILE NAME
Vxworks2Linux.c - vxwork下一些系统调用函数的linux移植,主要有:
消息队列:创建,消息的接收与发送,消息个数的获取等
二进制信号量:信号量的创建,give和take,delete
watchdog:wdCreate,wdStart,wdCancel
******************************************************************************************
modification history
2006-2-10 11:11 youyan created the file
2006-2-18 16:49 youyan added vxworks eventSend() eventReceive system call function
******************************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <asm/ioctl.h>
#include <errno.h>
#include <linux/rtc.h>
#include <sys/syscall.h>
#include <sys/msg.h>
#include <asm/param.h>
#include <semaphore.h>
#include <sched.h>
#include <time.h>
#include <sys/time.h>
/*#include <mqueue.h>*/
#include "Vxworks2Linux.h"
/*#include <linux/jiffies.h>*//*qyu 2006-3-1 14:39 !!!*/
VXSEMAPHORE VxSem[MAXSEM];
VXWATCHDOG VxWatchD[MAXWATCHDOG];
VXEVENT Vxevent[MAXTHREADS];
char msgName[100][3];/*quy 2006-3-8 15:11*/
int msgNameId;/*quy 2006-3-8 15:11*/
/******************************************************
函数名:taskSpawn
功能:创建linux线程
char * name, 任务的名称
int priority, 实时任务的优先级 1-99
int options, 选项
int stackSize, 任务堆栈的大小
void * (*entryPt)(void *), 任务的函数入口
int arg1, 这是一个指针值,任务入口函数的入参
int arg2, 下面的参数不使用
int arg3,
int arg4,
int arg5,
int arg6,
int arg7,
int arg8,
int arg9, 指定fifo 、rr或者normal调度方法
int arg10 nice值
引用全局变量:
输入参数说明:
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int taskSpawn(char *name,int priority,int options,int stackSize,
FUNCPTR entryPt/*void * (*entryPt)(void *)*/,int arg1,int arg2,int arg3,
int arg4,int arg5,int arg6, int arg7,int arg8,int arg9,int arg10)
{
int nRet = 0;
struct sched_param tSchParam;
pthread_attr_t tThreadAttr;
pthread_t thread_id;
int nSchPolicy;
int ps;/*pagesize*/
int i;
VXEVENT *pEvent;
sem_t sem;
int tempPriority;
/*判断优先级的正确性
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)
{
if(priority<200)
{
tempPriority=85+(priority-100)/10;
}
else
{
tempPriority=95+(priority-200)/10;
}
priority=tempPriority;
}
/*printf("taskSpawn name=%s,priority=%d\n",name,priority);*/
/*判断优先级的正确性*/
if (priority > 99 || priority < 0)
{
printf("priority must be between 0 and 99n");
return ERROR;
}
for(i=0;i<MAXTHREADS;i++)
{
if(!Vxevent[i].nThreadId)
break;
}
if(i >= MAXTHREADS)
{
printf("No find empty position\n");
return ERROR;
}
pEvent = &Vxevent[i];
if(sem_init(&sem,0,0) < 0 )
{
printf("sem_init Error\n");
return ERROR;
}
pEvent->Sem = sem;
pEvent->nEvent = 0;
pEvent->Flag = 0;
/*初始化线程参数*/
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
{
}
/*printf("stackSize1=%d\n", stackSize);*/
/*设置堆栈的大小*/
/*ps = __getpagesize ();
tThreadAttr.__stacksize = stackSize - ps;*/
tThreadAttr.__stacksize=stackSize;
/*printf("stackSize2=%d\n", tThreadAttr.__stacksize);*/
nRet = pthread_create(&thread_id, &tThreadAttr, entryPt, (void *)arg1);
if(nRet != OK)
{
sem_destroy(&sem);
pEvent->nThreadId = 0;
return (ERROR);
}
else
{
pEvent->nThreadId = thread_id;
return thread_id;
}
}
int taskDelete(int tid )
{
if (pthread_cancel(tid) == ERROR)
{
return ERROR;
}
return OK;
}
/*当linux线程被取消的时候将执行的指定函数*/
/*
#define taskDeleteHookAdd(void* deleteHook)
{
struct _pthread_cleanup_buffer buffer;
_pthread_cleanup_push(&buffer, deleteHook, NULL);
}
*/
/*对linux线程进行的操作*/
void initLinuxTask(void)
{
/*设置进程可被其他线程杀死,具体可通过在linux下
执行man pthread_setcancelstate来获得帮助*/
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/*设置线程收到中止信号后立即中止, 不需要等执行到到取消点*/
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}
int taskDelay(int ticks)
{
/* sleep(1);*/
usleep(ticks*1000);/*youy 2006-3-10 15:32*/
return OK;
}
/******************************************************
函数名:msgQDelete
功能:删除linux消息队列
引用全局变量:
输入参数说明:
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int msgQDelete( int msgQId )
{
#ifndef POSIX_CALL
return msgctl(msgQId, IPC_RMID, NULL);
#else
#endif
}
/******************************************************
函数名:msgQCreate
功能:创建linux消息队列
int maxMsgs, 最大消息个数
int maxMsgLength,单个消息最大长度
int options选项,linux未使用
返回值说明:成功返回msgQid, 失败将返回NULL
*******************************************************/
#if 1
int msgQCreate(int maxMsgs, int maxMsgLength,int options)
{
int msgQid = 0;
struct msqid_ds msg_info;
/*创建了一个消息队列,0666指定了访问权限,所有进程都可以访问*/
msgQid = msgget(IPC_PRIVATE, IPC_CREAT|IPC_EXCL|0666);
if(msgQid == -1)
{
if(errno==EACCES)
printf("\n\n EACCES\n\n");
else if(errno==EEXIST)
printf("\n\n EEXIST\n\n");
else if(errno==ENOENT)
printf("\n\n ENOENT\n\n");
else if(errno==ENOMEM)
printf("\n\n ENOMEM\n\n");
else if(errno==ENOSPC)
printf("\n\n ENOSPC\n\n");
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;
}
#endif
/*void msgNameInit(void)
{
int i;
for(i=0;i<100;i++)
{
msgName[i][0]=0x30+(i%10);
msgName[i][1]=0x30+(i/10);
msgName[i][2]=0x30+(i/100);
}
msgNameId=0;
}
int msgQCreate(int maxMsgs, int maxMsgLength,int options)
{
int msgQid = 0;
msgQid=mq_open(msgName[msgNameId],options);
return msgQid;
}*/
/******************************************************
函数名:msgQSend
功能:向linux消息队列发送消息,
int option 对于linux,该项无效
返回值说明:成功返回OK(0), 失败将返回ERROR(-1)
*******************************************************/
int msgQSend(int msgQId, char *buffer, unsigned int nBytes, int timeout, int option)
{
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消息队列接收消息
int msgQId, 队列id
char * buffer, 接收缓冲
unsigned int maxNBytes, 缓冲区长度
int timeout NO_WAIT(队列空时立即返回),WAIT_FOREVER(队列空时将阻塞,直到队列不为空)
返回值说明:成功返回消息大小, 失败将返回ERROR(-1)
*******************************************************/
int msgQReceive(int msgQId,char *buffer,unsigned int maxNBytes,int timeout)
{
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( int msgQId )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -