file ramDrv.h
#ifndef __INCramDrvh
#define __INCramDrvh
#ifdef __cplusplus
extern "C" {
#endif
#include "blkIo.h"
/* function declarations */
#if defined(__STDC__) || defined(__cplusplus)
extern STATUS ramDrv (void);
extern BLK_DEV *ramDevCreate (char *ramAddr, int bytesPerSec, int secPerTrack,
int nSectors, int secOffset);
#else
extern STATUS ramDrv ();
extern BLK_DEV *ramDevCreate ();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* __INCramDrvh */
/*******************************************************************************/
file ramDrv.c
#include "vxWorks.h"
#include "blkIo.h"
#include "ioLib.h"
#include "iosLib.h"
#include "memLib.h"
#include "errnoLib.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#define DEFAULT_DISK_SIZE (min (memFindMax()/2, 51200))
#define DEFAULT_SEC_SIZE 512
typedef struct /* RAM_DEV - RAM disk device descriptor */
{
BLK_DEV ram_blkdev; /* generic block device structure */
char *ram_addr; /* memory location of the RAM disk */
int ram_blkOffset; /* block offset of this device from ram_addr */
} RAM_DEV;
/* FORWARD DECLARATIONS */
LOCAL STATUS ramIoctl ();
LOCAL STATUS ramBlkRd ();
LOCAL STATUS ramBlkWrt ();
/*******************************************************************************
*
* ramDrv - prepare a RAM disk driver for use (optional)
*
* This routine performs no real function, except to provide compatibility
* with earlier versions of ramDrv and to parallel the initialization
* function found in true disk device drivers. It also is used in
* usrConfig.c to link in the RAM disk driver when building
* VxWorks. Otherwise, there is no need to call this routine before using
* the RAM disk driver.
*
* RETURNS: OK, always.
*/
STATUS ramDrv (void)
{
return (OK); /* no initialization required */
}
/*******************************************************************************
*
* ramDevCreate - create a RAM disk device
*
* This routine creates a RAM disk device.
*
* Memory for the RAM disk can be pre-allocated separately; if so, the
* parameter should be the address of the pre-allocated device
* memory. Or, memory can be automatically allocated with malloc() by
* setting to zero.
*
* The parameter specifies the size of each logical block
* on the RAM disk. If is zero, 512 is used.
*
* The parameter specifies the number of blocks on each
* logical track of the RAM disk. If is zero, the count of
* blocks per track is set to (i.e., the disk is defined
* as having only one track).
*
* The parameter specifies the size of the disk, in blocks.
* If is zero, a default size is used. The default is calculated
* using a total disk size of either 51,200 bytes or one-half of the size
* of the largest memory area available, whichever is less. This default
* disk size is then divided by to determine the number
* of blocks.
*
* The parameter specifies an offset, in blocks, from the start
* of the device to be used when writing or reading the RAM disk. This
* offset is added to the block numbers passed by the file system during
* disk accesses. (VxWorks file systems always use block numbers beginning
* at zero for the start of a device.) This offset value is typically useful
* only if a specific address is given for . Normally,
* is 0.
*
* FILE SYSTEMS:
* Once the device has been created, it must be associated with a name and a
* file system (dosFs, rt11Fs, or rawFs). This is accomplished using the
* file system's device initialization routine or make-file-system routine,
* e.g., dosFsDevInit() or dosFsMkfs(). The ramDevCreate() call returns a
* pointer to a block device structure (BLK_DEV). This structure contains
* fields that describe the physical properties of a disk device and specify
* the addresses of routines within the ramDrv driver. The BLK_DEV structure
* address must be passed to the desired file system (dosFs, rt11Fs or rawFs)
* via the file system's device initialization or make-file-system routine.
* Only then is a name and file system associated with the device, making it
* available for use.
*
* EXAMPLE:
* In the following example, a 200-Kbyte RAM disk is created with
* automatically allocated memory, 512-byte blocks, a single track, and no
* block offset. The device is then initialized for use with dosFs and assigned
* the name "DEV1:":
* .CS
* BLK_DEV *pBlkDev;
* DOS_VOL_DESC *pVolDesc;
*
* pBlkDev = ramDevCreate (0, 512, 400, 400, 0);
* pVolDesc = dosFsMkfs ("DEV1:", pBlkDev);
* .CE
* The dosFsMkfs() routine calls dosFsDevInit() with default parameters and
* initializes the file system on the disk by calling ioctl() with the
* \%FIODISKINIT function.
*
* If the RAM disk memory already contains a disk image created elsewhere,
* the first argument to ramDevCreate() should be the address in memory, and
* the formatting parameters -- , , , and
* -- must be identical to those used when the image was
* created. For example:
* .CS
* pBlkDev = ramDevCreate (0xc0000, 512, 400, 400, 0);
* pVolDesc = dosFsDevInit ("DEV1:", pBlkDev, NULL);
* .CE
* In this case, dosFsDevInit() must be used instead of dosFsMkfs(), because
* the file system already exists on the disk and should not be
* re-initialized. This procedure is useful if a RAM disk is to be created
* at the same address used in a previous boot of VxWorks. The contents of
* the RAM disk will then be preserved.
*
* These same procedures apply when creating a RAM disk with rt11Fs using
* rt11FsDevInit() and rt11FsMkfs(), or creating a RAM disk with rawFs using
* rawFsDevInit().
*
* RETURNS:
* A pointer to a block device structure (BLK_DEV) or NULL if memory cannot
* be allocated for the device structure or for the RAM disk.
*
* SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),
* rawFsDevInit()
*/
BLK_DEV *ramDevCreate
(
char *ramAddr, /* where it is in memory (0 = malloc) */
FAST int bytesPerBlk, /* number of bytes per block */
int blksPerTrack, /* number of blocks per track */
int nBlocks, /* number of blocks on this device */
int blkOffset /* no. of blks to skip at start of device */
)
{
FAST RAM_DEV *pRamDev; /* ptr to created RAM_DEV struct */
FAST BLK_DEV *pBlkDev; /* ptr to BLK_DEV struct in RAM_DEV */
/* Set up defaults for any values not specified */
if (bytesPerBlk == 0)
bytesPerBlk = DEFAULT_SEC_SIZE;
if (nBlocks == 0)
nBlocks = DEFAULT_DISK_SIZE / bytesPerBlk;
if (blksPerTrack == 0)
blksPerTrack = nBlocks;
/* Allocate a RAM_DEV structure for device */
pRamDev = (RAM_DEV *) malloc (sizeof (RAM_DEV));
if (pRamDev == NULL)
return (NULL); /* no memory */
/* Initialize BLK_DEV structure (in RAM_DEV) */
pBlkDev = &pRamDev->ram_blkdev;
pBlkDev->bd_nBlocks = nBlocks; /* number of blocks */
pBlkDev->bd_bytesPerBlk = bytesPerBlk; /* bytes per block */
pBlkDev->bd_blksPerTrack = blksPerTrack; /* blocks per track */
pBlkDev->bd_nHeads = 1; /* one "head" */
pBlkDev->bd_removable = FALSE; /* not removable */
pBlkDev->bd_retry = 1; /* retry count */
pBlkDev->bd_mode = O_RDWR; /* initial mode for device */
pBlkDev->bd_readyChanged = TRUE; /* new ready status */
pBlkDev->bd_blkRd = ramBlkRd; /* read block function */
pBlkDev->bd_blkWrt = ramBlkWrt; /* write block function */
pBlkDev->bd_ioctl = ramIoctl; /* ioctl function */
pBlkDev->bd_reset = NULL; /* no reset function */
pBlkDev->bd_statusChk = NULL; /* no check-status function */
/* Initialize remainder of device struct */
if (ramAddr == NULL) /* allocate mem if 0 */
{
pRamDev->ram_addr = (char *) malloc ((UINT) (bytesPerBlk * nBlocks));
if (pRamDev->ram_addr == NULL)
{
free ((char *) pRamDev);
return (NULL); /* no memory */
}
}
else
pRamDev->ram_addr = ramAddr;
pRamDev->ram_blkOffset = blkOffset; /* block offset */
return (&pRamDev->ram_blkdev);
}
/*******************************************************************************
*
* ramIoctl - do device specific control function
*
* This routine is called when the file system cannot handle an ioctl()
* function.
*
* The FIODISKFORMAT function always returns OK, since a RAM disk does
* not require formatting. All other requests return ERROR.
*
* RETURNS: OK or ERROR.
*
* ERRNO: S_ioLib_UNKNOWN_REQUEST
*
*/
LOCAL STATUS ramIoctl (pRamDev, function, arg)
RAM_DEV *pRamDev; /* device structure pointer */
int function; /* function code */
int arg; /* some argument */
{
FAST int status; /* returned status value */
switch (function)
{
case FIODISKFORMAT:
status = OK;
break;
default:
errnoSet (S_ioLib_UNKNOWN_REQUEST);
status = ERROR;
}
return (status);
}
/*******************************************************************************
*
* ramBlkRd - read one or more blocks from a RAM disk volume
*
* This routine reads one or more blocks from the specified volume,
* starting with the specified block number. The byte offset is
* calculated and the RAM disk data is copied to the specified buffer.
*
* If any block offset was specified during ramDevCreate(), it is added
* to before the transfer takes place.
*
* RETURNS: OK, always.
*/
LOCAL STATUS ramBlkRd (pRamDev, startBlk, numBlks, pBuffer)
FAST RAM_DEV *pRamDev; /* pointer to device desriptor */
int startBlk; /* starting block number to read */
int numBlks; /* number of blocks to read */
char *pBuffer; /* pointer to buffer to receive data */
{
FAST int bytesPerBlk; /* number of bytes per block */
bytesPerBlk = pRamDev->ram_blkdev.bd_bytesPerBlk;
/* Add in the block offset */
startBlk += pRamDev->ram_blkOffset;
/* Read the block(s) */
bcopy ((pRamDev->ram_addr + (startBlk * bytesPerBlk)), pBuffer,
bytesPerBlk * numBlks);
return (OK);
}
/*******************************************************************************
*
* ramBlkWrt - write one or more blocks to a RAM disk volume
*
* This routine writes one or more blocks to the specified volume,
* starting with the specified block number. The byte offset is
* calculated and the buffer data is copied to the RAM disk.
*
* If any block offset was specified during ramDevCreate(), it is added
* to before the transfer takes place.
*
* RETURNS: OK, always.
*/
LOCAL STATUS ramBlkWrt (pRamDev, startBlk, numBlks, pBuffer)
FAST RAM_DEV *pRamDev; /* pointer to device desriptor */
int startBlk; /* starting block number to write */
int numBlks; /* number of blocks to write */
char *pBuffer; /* pointer to buffer of data to write */
{
FAST int bytesPerBlk; /* number of bytes per block */
bytesPerBlk = pRamDev->ram_blkdev.bd_bytesPerBlk;
/* Add in the block offset */
startBlk += pRamDev->ram_blkOffset;
/* Write the block(s) */
bcopy (pBuffer, (pRamDev->ram_addr + (startBlk * bytesPerBlk)),
bytesPerBlk * numBlks);
return (OK);
}
/*****************************************************************************
函 数 名 : ramDrvTest
功能描述 : ramDrv test
输入参数 : 无
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 :
作 者 :
修改内容 : 新生成函数
*****************************************************************************/
void ramDrvTest()
{
BLK_DEV *pBlkDev;
unsigned char *readBuf;
unsigned char *writeBuf;
int fd = 0;
/* 创建dos文件系统 */
xxramDrv();
pBlkDev = xxramDevCreate(NULL, 512, 400, 400, 0);
dosFsMkfs("/RAM1", pBlkDev);
/* Create and write to a file. Flush to RAM disk */
writeBuf = (unsigned char *)malloc(100 * sizeof(char));
fd = creat("/RAM1/myFile", O_RDWR);
strcpy(writeBuf, "This is a string\n");
write(fd, writeBuf, strlen(writeBuf));
close(fd);
/* Open file and read contents. */
readBuf = (unsigned char *)malloc(100 * sizeof(char));
fd = open("/RAM1/myFile", O_RDWR, 0);
read(fd, readBuf, 100);
printf("readBuf is %s\n", readBuf);
close(fd);
}