⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memdrv.c

📁 很多嵌入式VxWorks的实验程序
💻 C
字号:
#include "copyright_wrs.h"#include "vxWorks.h"#include "ioLib.h"#include "iosLib.h"#include "stat.h"#include "dirent.h"#include "memLib.h"#include "errnoLib.h"#include "string.h"#include "stdlib.h"#include "stdio.h"#include "memDrv.h"typedef struct		  /* MEM_DEV - memory device descriptor */    {    DEV_HDR devHdr;    MEM_DRV_DIRENTRY dir; /* Contents of this memDrv device */    int allowOffset;	  /* Allow files to be opened with an offset. */    } MEM_DEV;typedef struct		  /* MEM_FILE_DESC - memory file descriptor */    {    MEM_DEV *pDevice;	  /* The memory device of this file */    MEM_DRV_DIRENTRY *pDir;/* Directory entry for this file */    int offset;		  /* current position */    int mode;		  /* O_RDONLY, O_WRONLY, O_RDWR */    } MEM_FILE_DESC;LOCAL int memDrvNum;	  /* driver number of memory driver *//* forward declarations */LOCAL MEM_DRV_DIRENTRY *memFindFile ();LOCAL MEM_FILE_DESC *memOpen ();LOCAL STATUS memFileStatGet ();LOCAL int memRead ();LOCAL int memWrite ();LOCAL int memClose ();LOCAL STATUS memIoctl ();/********************************************************************************* memDrv - install a memory driver** This routine initializes the memory driver.  It must be called first,* before any other routine in the driver.** RETURNS: OK, or ERROR if the I/O system cannot install the driver.*/STATUS memDrv (void)    {    if (memDrvNum > 0)	return (OK);	/* driver already installed */    memDrvNum = iosDrvInstall ((FUNCPTR) memOpen, (FUNCPTR) NULL,			       (FUNCPTR) memOpen, memClose,			       memRead, memWrite, memIoctl);    return (memDrvNum == ERROR ? ERROR : OK);    }STATUS memDevCreate     (    char * name,		/* device name		    */    char * base,		/* where to start in memory */    int    length		/* number of bytes	    */    )    {    STATUS status;    FAST MEM_DEV *pMemDv;    if (memDrvNum < 1)        {        errnoSet (S_ioLib_NO_DRIVER);        return (ERROR);        }    if ((pMemDv = (MEM_DEV *) calloc (1, sizeof (MEM_DEV))) == NULL)	return (ERROR);    pMemDv->dir.name  = "";    pMemDv->dir.base  = base;    pMemDv->dir.pDir  = NULL;    pMemDv->dir.length = length;    pMemDv->allowOffset = 1;    /*     * XXX     * Specify byte,word,long accesses.     * Semaphore read/write? */    status = iosDevAdd ((DEV_HDR *) pMemDv, name, memDrvNum);    if (status == ERROR)	free ((char *) pMemDv);    return (status);    }/********************************************************************************* memDevCreateDir - create a memory device for multiple files** This routine creates a memory device for a collection of files* organised into directories.  The given array of directory entry* records describes a number of files, some of which may be directories,* represented by their own directory entry arrays.  The structure may* be arbitrarily deep.  This effectively allows a filesystem to* be created and installed in VxWorks, for essentially read-only use.* The filesystem structure can be created on the host using the* memdrvbuild utility.** Note that the array supplied is not copied; a reference to it is* kept.  This array should not be modified after being passed to* memDevCreateDir.** RETURNS:  OK, or ERROR if memory is insufficient or the I/O system cannot*           add the device.** ERRNO: S_ioLib_NO_DRIVER**/STATUS memDevCreateDir    (    char * name,		/* device name		    */    MEM_DRV_DIRENTRY * files,	/* array of dir. entries - not copied */    int    numFiles		/* number of entries	    */    )    {    STATUS status;    FAST MEM_DEV *pMemDv;    if (memDrvNum < 1)        {        errnoSet (S_ioLib_NO_DRIVER);        return (ERROR);        }    if ((pMemDv = (MEM_DEV *) calloc (1, sizeof (MEM_DEV))) == NULL)	return (ERROR);    pMemDv->dir.name  = "";    pMemDv->dir.base  = NULL;    pMemDv->dir.pDir  = files;    pMemDv->dir.length = numFiles;    /*     * Let's not allow the "offset" notation for opening files, at     * least for now, when we have "real" subdirectories.     */    pMemDv->allowOffset = 0;    /*     * XXX     * Specify byte,word,long accesses.     * Semaphore read/write?     */    status = iosDevAdd ((DEV_HDR *) pMemDv, name, memDrvNum);    if (status == ERROR)	free ((char *) pMemDv);    return (status);    }/********************************************************************************* memDevDelete - delete a memory device** This routine deletes a memory device containing a single file or a* collection of files. The device is deleted with it own name.** For example, to delete the device created by memDevCreate ("/mem/cpu0/", 0,* sysMemTop()), the proper call would be:* .CS* 	memDevDelete ("/mem/cpu0/");* .CE*  * RETURNS: OK, or ERROR if the device doesn't exist.*/STATUS memDevDelete    (    char * name			/* device name */    )    {    DEV_HDR * pDevHdr;    /* get the device pointer corresponding to the device name */     if ((pDevHdr = iosDevFind (name, NULL)) == NULL)        return (ERROR);    /* delete the device from the I/O system */    iosDevDelete (pDevHdr);    /* free the device pointer */    free ((MEM_DEV *) pDevHdr);    return (OK);    }/********************************************************************************* memFindFile - find a memory file by name** RETURNS: The file descriptor number, or ERROR if the name is not a*  valid number.*/LOCAL MEM_DRV_DIRENTRY *memFindFile    (    MEM_DEV *pMemDv,		/* Device we are looking in. */    char *name,			/* name of file to find */    MEM_DRV_DIRENTRY *pDir,	/* pointer to memory device descriptor */    int *pOffset			/* returned file pOffset */    )    {    MEM_DRV_DIRENTRY *pFile = NULL;    *pOffset = 0;    /* Protect against NULL. */    if (name == NULL)	name = "";    while (*name == '/')	++name;    if (strcmp (pDir->name, name) == 0)	{	pFile = pDir;	}    else if (strncmp (pDir->name, name, strlen (pDir->name)) == 0)	{	int index;	name += strlen (pDir->name);	if (pDir->pDir != NULL)	    {	    /* Search for the referenced file in this directory. */	    for (index = 0; index < pDir->length; ++index)		{		pFile = memFindFile (pMemDv, name, &pDir->pDir[index], pOffset);		if (pFile != NULL) break;		}	    }	else if (pMemDv->allowOffset)	    {	    int off = 0;	    while (*name == '/')		++name;	    if (sscanf (name, "%d", &off) == 1)		{		pFile = pDir;		*pOffset = off;		}	    }	}    return pFile;    }/********************************************************************************* memOpen - open a memory file** RETURNS: The file descriptor number, or ERROR if the name is not a*          valid number.** ERRNO: EINVAL**/LOCAL MEM_FILE_DESC *memOpen    (    MEM_DEV *pMemDv,	/* pointer to memory device descriptor */    char *name,		/* name of file to open (a number) */    int mode		/* access mode (O_RDONLY,O_WRONLY,O_RDWR) */    )    {    MEM_DRV_DIRENTRY *pFile = NULL;    MEM_FILE_DESC *pMemFd = NULL;    int offset = 0;    int isDir = 0;    pFile = memFindFile (pMemDv, name, &pMemDv->dir, &offset);    if (pFile != NULL)	{	/* Directories open for read only. */	isDir = (pFile->pDir != NULL);	if (!isDir || mode == O_RDONLY)	    {	    /* Get a free file descriptor */	    pMemFd = (MEM_FILE_DESC *) calloc (1, sizeof (MEM_FILE_DESC));	    if (pMemFd != NULL)		{		pMemFd->pDevice = pMemDv;		pMemFd->pDir = pFile;		pMemFd->offset = offset;		pMemFd->mode   = mode;		}	    }	}    if (pMemFd != NULL)	return pMemFd;    else	{	errnoSet (EINVAL);	return (MEM_FILE_DESC *) ERROR;	}    }/********************************************************************************* memFileStatGet - get file status (directory entry data)** This routine is called via an ioctl() call, using the FIOFSTATGET* function code.  The passed stat structure is filled, using data* obtained from the directory entry which describes the file.** RETURNS: ERROR or OK** ERRNO: EINVAL**/LOCAL STATUS memFileStatGet    (    MEM_FILE_DESC * pfd,	/* pointer to file descriptor */    struct stat	* pStat		/* structure to fill with data */    )    {    MEM_DEV *pMemDv = pfd->pDevice;	/* pointer to device */    MEM_DRV_DIRENTRY *pDir = pfd->pDir;	/* pointer to file info */    int isDir = 0;    if (pStat == NULL || pDir == NULL)	{	errnoSet (EINVAL);	return ERROR;	}    bzero ((char *) pStat, sizeof (struct stat)); /* zero out stat struct */    isDir = (pDir->pDir != NULL);    /* Fill stat structure */    pStat->st_dev     = (ULONG) pMemDv;		/* device ID = DEV_HDR addr */    pStat->st_ino     = 0;			/* no file serial number */    pStat->st_nlink   = 1;			/* always only one link */    pStat->st_uid     = 0;			/* no user ID */    pStat->st_gid     = 0;			/* no group ID */    pStat->st_rdev    = 0;			/* no special device ID */    pStat->st_size    = isDir ? 0 : pDir->length; /* file size, in bytes */    pStat->st_atime   = 0;			/* no last-access time */    pStat->st_mtime   = 0;			/* no last-modified time */    pStat->st_ctime   = 0;			/* no last-change time */    pStat->st_attrib  = 0;			/* file attribute byte */        /*     * Set file access permissions to be read/write by all; for     * directories, add exec (search).     */    pStat->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | 		       S_IWUSR | S_IWGRP | S_IWOTH);    if (isDir)	pStat->st_mode |= (S_IXUSR | S_IXGRP | S_IXOTH);    /* Is it a file or directory? */    if (isDir)	pStat->st_mode |= S_IFDIR;		/*  it is a directory */    else	pStat->st_mode |= S_IFREG;		/*  it is a regular file */    return (OK);    }/********************************************************************************* memRead - read from a memory file** RETURNS: ERROR if the file open mode is O_WRONLY; otherwise, the number of*          bytes read (may be less than the amount requested), or 0 if the*          file is at EOF.** ERRNO: EINVAL, EISDIR**/LOCAL int memRead    (    MEM_FILE_DESC *pfd,	/* file descriptor of file to read */    char *buffer,	/* buffer to receive data */    int maxbytes	/* max bytes to read in to buffer */    )    {    MEM_DRV_DIRENTRY *pDir = pfd->pDir;	/* pointer to file info */    int lLeft;    /* Fail if the mode is invalid, or if it's a directory. */    if (pfd->mode == O_WRONLY)	{	errnoSet (EINVAL);	return (ERROR);	}    if (pDir == NULL || pDir->pDir != NULL)	{	errnoSet (EISDIR);	return (ERROR);	}    /* calculate #bytes left to read */    lLeft = pDir->length - pfd->offset;    if (lLeft < 0) lLeft = 0;    /* limit maxbytes to minimum of bytes left or buffer length */    if (maxbytes > lLeft) maxbytes = lLeft;    if (maxbytes > 0)        {        bcopy (pDir->base + pfd->offset, buffer, maxbytes);        pfd->offset += maxbytes;        }    return (maxbytes);    }/********************************************************************************* memWrite - write to a memory file** RETURNS: The number of bytes written, or ERROR if past the end of memory or*          is O_RDONLY only.** ERRNO: EINVAL, EISDIR**/LOCAL int memWrite    (    MEM_FILE_DESC *pfd,	/* file descriptor of file to write */    char *buffer,	/* buffer to be written */    int nbytes		/* number of bytes to write from buffer */    )    {    MEM_DRV_DIRENTRY *pDir = pfd->pDir;	/* pointer to file info */    int lLeft;    /* Fail if the mode is invalid, or if it's a directory. */    if (pfd->mode == O_RDONLY)	{	errnoSet (EINVAL);	return (ERROR);	}    if (pDir == NULL || pDir->pDir != NULL)	{	errnoSet (EISDIR);	return (ERROR);	}    /* calculate #bytes left to write */    lLeft = pDir->length - pfd->offset;    if (lLeft < 0) lLeft = 0;    /* If write is too large, truncate it */    if (nbytes > lLeft) nbytes = lLeft;    if (nbytes > 0)        {	bcopy (buffer, pDir->base + pfd->offset, nbytes);	pfd->offset += nbytes;        }    return (nbytes);    }/********************************************************************************* memIoctl - do device specific control function** Only the FIONREAD, FIOSEEK, FIOWHERE, FIOGETFL, FIOFSTATGET, and* FIOREADDIR options are supported.** RETURNS: OK, or ERROR if seeking passed the end of memory.** ERRNO: EINVAL, S_ioLib_UNKNOWN_REQUEST**/LOCAL STATUS memIoctl (pfd, function, arg)    FAST MEM_FILE_DESC *pfd;	/* descriptor to control */    FAST int function;		/* function code */    int	arg;			/* some argument */    {    MEM_DRV_DIRENTRY *pDir = pfd->pDir;	/* pointer to file info */    DIR *dirp;    int isDir = 0;    int status = OK;    if (pDir == NULL)	{	errnoSet (EINVAL);	status = ERROR;	}    else	{	isDir = (pDir->pDir != NULL);	switch (function)	    {	    case FIONREAD:		if (isDir)		    {		    errnoSet (EINVAL);		    status = ERROR;		    }		else		    {		    *((int *) arg) = pDir->length - pfd->offset;		    }		break;	    case FIOSEEK:		if (isDir || arg > pDir->length)		    {		    errnoSet (EINVAL);		    status = ERROR;		    }		else		    {		    pfd->offset = arg;		    }		break;	    case FIOWHERE:		if (isDir)		    status = 0;		else		    status = pfd->offset;		break;	    case FIOGETFL:		*((int *) arg) = pfd->mode;		break;	    case FIOFSTATGET:		status = memFileStatGet (pfd, (struct stat *) arg);		break;	    case FIOREADDIR:		/*		 * The index of the directory entry required is passed in via		 * dirp->dd_cookie.  We're supposed to return the name in		 * dirp->dd_dirent.		 */		dirp = (DIR *) arg;		if (!isDir || dirp->dd_cookie >= pDir->length)		    {		    errnoSet (EINVAL);		    status = ERROR;		    }		else		    {		    strcpy (dirp->dd_dirent.d_name, pDir->pDir[dirp->dd_cookie].name);		    ++dirp->dd_cookie;		    }		break;	    default:		errnoSet (S_ioLib_UNKNOWN_REQUEST);		status = ERROR;		break;	    }	}    return (status);    }/********************************************************************************* memClose - close a memory file** RETURNS: OK, or ERROR if file couldn't be flushed or entry couldn't *  be found.*/LOCAL STATUS memClose (pfd)    MEM_FILE_DESC *pfd;	/* file descriptor of file to close */    {    free (pfd);    return OK;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -