分类:
2010-03-15 12:25:54
Vxworks 字符设备操作
(自己写的东西估计没什么参考价值大侠们就别看了 -------王瑞涛)
从open说起
当用户调用open函数是。系统会调用LOCAL int ioCreateOrOpen()函数
LOCAL int ioCreateOrOpen
(
const char *name, /* name of the file to create */
int flags, /* O_RDONLY, O_WRONLY, O_RDWR or O_CREAT (open call) */
int mode, /* mode of ile to create (if open call) */
BOOL create /* set to TRUE if this is a creat() call */
)
{
DEV_HDR *pDevHdr1;
DEV_HDR *pDevHdr2 = NULL;
int value;
int fd = (int)ERROR;
char fullFileName [MAX_FILENAME_LENGTH];
int error = 0;
char *pPartFileName;
int savtype;
/* don't allow null filename (for user protection) but change
* "." into what null filename would be if we allowed it */
if ((name == NULL) || (name[0] == EOS))
{
errnoSet (S_ioLib_NO_FILENAME);
error = 1;
goto handleError;
}
if (_func_pthread_setcanceltype != NULL)
{
_func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);
}
if (strcmp (name, ".") == 0)
{
/* point to EOS (turn it into null filename) */
++name;
}
if (ioFullFileNameGet (name, &pDevHdr1, fullFileName) == ERROR)
{
error = 1;
goto handleError;
}
if ((fd = iosFdNew (pDevHdr1, (char *)NULL, 0)) == ERROR)//这个关联DEV_HDR 和 FD_ENTRY
{
error = 1;
goto handleError;
}
if (create == TRUE)
{
value = iosCreate (pDevHdr1, fullFileName, flags);
}
else
{
value = iosOpen (pDevHdr1, fullFileName, flags, mode);
}
if (value == ERROR)
{
error = 2;
goto handleError;
}
/* In case the path does not follow the while loop, get the pDevHdr1
recorded in pDevHdr2 for error handling. */
pDevHdr2 = pDevHdr1;
while (value == FOLLOW_LINK)
{
int linkCount = 1;
/* if a file name contains a link, the driver's create routine changed
* fullFileName to incorporate the link's name. Try to create the file
* that the driver's create routine handed back.
*/
if (linkCount++ > ioMaxLinkLevels)
{
errno = ELOOP;
error = 2;
goto handleError;
}
if ((pDevHdr2 = iosDevFind (fullFileName, &pPartFileName)) == NULL)//通过名字找掉对应的DEV_HDR节点
{
error = 2;
goto handleError;
}
if (fullFileName != pPartFileName)
{
/* link file name starts with a vxWorks device name,
* possibly a different device from the current one.
*/
strncpy (fullFileName, pPartFileName, MAX_FILENAME_LENGTH);
}
else
{
/* link file name does not start with a vxWorks device name.
* create the file on the current device.
*/
pDevHdr2 = pDevHdr1;
}
if (create == TRUE)
{
value = iosCreate (pDevHdr2, fullFileName, flags);
}
else
{
value = iosOpen (pDevHdr2, fullFileName, flags, mode);
}
if (value == ERROR)
{
error = 2;
goto handleError;
}
} /* while */
if ((iosFdSet (fd, pDevHdr1, CHAR_FROM_CONST(name), value)) == ERROR)//这个东西郁闷了半天。发现vxworks吧返回值作为在系统调用中传递的东西。真晕啊。不行linux有个private_data 指针
{
error = 3;
goto handleError;
}
if (_func_pthread_setcanceltype != NULL)
{
_func_pthread_setcanceltype(savtype, NULL);
}
return (fd);
handleError:
if (_func_pthread_setcanceltype != NULL)
{
_func_pthread_setcanceltype(savtype, NULL);
}
if (error > 2)
{
iosDelete (pDevHdr2, fullFileName);
}
if (error > 1)
{
iosFdFree (fd);
}
if (error > 0)
{
fd = (int)ERROR;
}
return (fd);
}
这个东西其实就是根据用户在调用open是的名字在系统中找掉一个未用的FD_ENTRY 并且把DEV_HDR 的东西添加到里面。当你调用read write是直接通过fd找去就可以了。最郁闷的是没仔细看这部分源码 对read 里面的第一个参数晕了好几天。回头看看才明白。是驱动中XXDEVOPEN的返回值。
再看看iosread
int iosRead
(
int fd,
char *buffer,
int maxbytes
)
{
FUNCPTR drvRead;
FAST FD_ENTRY *pFdEntry;
FAST int xfd = STD_MAP(fd);
if ((pFdEntry = FD_CHECK (xfd)) == NULL)
return (ERROR);
drvRead = drvTable [pFdEntry->pDevHdr->drvNum].de_read;
if (drvRead == NULL)
{
errno = ENOTSUP;
return (ERROR);
}
else
return ((* drvRead) (pFdEntry->value, buffer, maxbytes));
}
这部分很清晰没啥好说的。
typedef struct dev_hdr /* DEV_HDR - device header for all device structures */
{
DL_NODE node; /* device linked list node */
short drvNum; /* driver number for this device */
const char *name; /* device name */
int drvRefCount; /* counter of concurrent driver invocations */
UINT32 drvRefFlag; /* driver reference flags */
void *pDrvEntry; /* driver table of this device */
FUNCPTR deleteDrv; /* driver called upon device delete */
} DEV_HDR;
/*
typedef struct fdObjEntry /* FD_ENTRY - entries in file table */
{
OBJ_CORE objCore; /* FDs are objects */
DEV_HDR * pDevHdr; /* device header for this file */
void * value; /* driver open file cookie, maybe reloaded */
void * driverCookie; /* driver open file cookie */
#ifdef _WRS_VX_SMP
atomic_t refCnt; /* reference count */
#else
volatile int refCnt; /* reference count */
#endif
int flags; /* fd flags */
DRV_ENTRY * pDrvEntry; /* dev driver, remove support, invalidated fd drv */
DRV_ENTRY * pDevDrvEntry; /* device driver entry slot pointer */
} FD_ENTRY;
刚接触vxworks 一个星期,继续努力哈哈哈