📄 memdrv.c
字号:
/* memDrv.c - pseudo memory device driver */
/*程序实现功能是把内存中一段区域模拟字符型IO设备来操作。*/
#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;
char *MemBase;
int allowOffset1;
/* Allow files to be opened with an offset. */
} MEM_DEV;
typedef struct /* MEM_DEV - memory device descriptor */
{
MEM_DEV *pMemDev;
int allowOffset2; /* Allow files to be opened with an offset. */
} MEM_DEV_PER_FD;
MEM_DEV_PER_FD pMemDevPerFd;
LOCAL int memDrvNum; /* driver number of memory driver */
/* forward declarations */
LOCAL MEM_DEV_PER_FD *memOpen ();
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);
}
/*******************************************************************************
*
* memDevCreate - create a memory device
*
* This routine creates a memory device containing a single file.
* Memory for the device is simply an absolute memory location
* beginning at <base>. The <length> parameter indicates the size of
* memory.
*
* For example, to create the device "/mem/cpu0/", a device for accessing
* the entire memory of the local processor, the proper call would be:
* .CS
* memDevCreate ("/mem/cpu0/", 0, sysMemTop())
* .CE
* The device is created with the specified name, start location, and size.
*
* To open a file descriptor to the memory, use open(). Specify a
* pseudo-file name of the byte offset desired, or open the "raw" file at the
* beginning and specify a position to seek to. For example, the following
* call to open() allows memory to be read starting at decimal offset 1000.
* .CS
* -> fd = open ("/mem/cpu0/1000", O_RDONLY, 0)
* .CE
* Pseudo-file name offsets are scanned with "%d".
*
* CAVEAT
* The FIOSEEK operation overrides the offset given via the pseudo-file name
* at open time.
*
* EXAMPLE
* Consider a system configured with two CPUs in the backplane and a separate
* dual-ported memory board, each with 1 megabyte of memory. The first CPU
* is mapped at VMEbus address 0x00400000 (4 Meg.), the second at bus
* address 0x00800000 (8 Meg.), the dual-ported memory board at 0x00c00000
* (12 Meg.). Three devices can be created on each CPU as follows. On
* processor 0:
* .CS
* -> memDevCreate ("/mem/local/", 0, sysMemTop())
* ...
* -> memDevCreate ("/mem/cpu1/", 0x00800000, 0x00100000)
* ...
* -> memDevCreate ("/mem/share/", 0x00c00000, 0x00100000)
* .CE
* On processor 1:
* .CS
* -> memDevCreate ("/mem/local/", 0, sysMemTop())
* ...
* -> memDevCreate ("/mem/cpu0/", 0x00400000, 0x00100000)
* ...
* -> memDevCreate ("/mem/share/", 0x00c00000, 0x00100000)
* .CE
* Processor 0 has a local disk. Data or an object module needs to be
* passed from processor 0 to processor 1. To accomplish this, processor 0
* first calls:
* .CS
* -> copy </disk1/module.o >/mem/share/0
* .CE
* Processor 1 can then be given the load command:
* .CS
* -> ld </mem/share/0
* .CE
*
* RETURNS: OK, or ERROR if memory is insufficient or the I/O system cannot add
* the device.
*
* ERRNO: S_ioLib_NO_DRIVER
*
*
*
* iosDrvShow
* memDrv
* memSysPartId to search the free memory
* devs
* d 0x00f1a200
* memDevCreate ("/memIoDevice",0x00f1a200,10)
* devs
* iosFdShow
* fd=open("/memIoDevice",2,0)
* iosFdShow
* yy="hello\n";
* printf yy
* write fd,yy,10
* d 0x00f1a200
* zz=calloc(10,1)
* printf zz
* read fd,zz,10
* printf zz
* iosFdShow
* close fd;
* iosFdShow
*/
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->MemBase=base;
/*
* 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
*
*/
/* memOpen - open a memory file
*
* RETURNS: The file descriptor number, or ERROR if the name is not a
* valid number.
*
* ERRNO: EINVAL
*
*/
LOCAL MEM_DEV_PER_FD *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_DEV_PER_FD *pMemDevPerFd = NULL;
pMemDevPerFd = (MEM_DEV_PER_FD *) calloc(1,sizeof(MEM_DEV_PER_FD));
if (pMemDevPerFd != NULL)
{
pMemDevPerFd->pMemDev = (MEM_DEV *) pMemDv;
pMemDevPerFd->allowOffset2 = 0;
return pMemDevPerFd;
}
else
return (MEM_DEV_PER_FD *) ERROR;
}
/*******************************************************************************
*
* 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_DEV_PER_FD *pfd, /* file descriptor of file to read */
char *buffer, /* buffer to receive data */
int maxbytes /* max bytes to read in to buffer */
)
{
bcopy (pfd->pMemDev->MemBase,buffer, 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_DEV_PER_FD *pfd, /* file descriptor of file to write */
char *buffer, /* buffer to be written */
int nbytes /* number of bytes to write from buffer */
)
{
bcopy (buffer,pfd->pMemDev->MemBase, 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)
MEM_DEV_PER_FD *pfd; /* descriptor to control */
FAST int function; /* function code */
int arg; /* some argument */
{
return (OK);
}
/*******************************************************************************
*
* 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_DEV_PER_FD *pfd; /* file descriptor of file to close */
{
free (pfd);
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -