首页
登录 | 注册

VxWorks的ram disk驱动,block设备驱动

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);
}
 

相关文章

  • 从linux设备驱动模型看virtio初始化
    从linux设备驱动模型看virtio初始化 --lvyilong316 我们看linux kernel中virtio驱动相关代码,会发现有很多相关文件.首先有virtio.c这种文件,其次还有virtio_pci.c,virtio_scs ...
  • 一.板级设备扫描         针对上一篇博客最后的i2c_scan_static_board_info(adap)函数处,首先先看下在系统启动的时候板级设备的注册.         针对我现在使用的开发板,对于I2C设备注册程序如下: ...
  • 一.i2c-dev驱动分析 1.1.设备驱动注册         分析这个驱动,还是从module_init()和module_exit()开始,程序如下: static int __init i2c_dev_init(void) {    ...
  • 网络数据包收发流程(一):从驱动到协议栈
    早就想整理网络数据包收发流程了,一直太懒没动笔.今天下决心写了 一.硬件环境 intel82546:PHY与MAC集成在一起的PCI网卡芯片,很强大 bcm5461:   PHY芯片,与之对应的MAC是TSEC TSEC:      Thr ...
  •         一个类是一个设备的高层视图,它抽象掉了底层的实现细节.例如,在驱动层面时,你可能会见到SCSI磁盘或者ATA磁盘:但在类层面时,它们都是磁盘.类允许用户空间基于它们做什么来使用设备,而不是它们如何被连接或者它们如何工作.   ...
  • Linux  I2C驱动分析(一)----I2C架构和总线驱动
    一.I2C总线原理         I2C是一种常用的串行总线,由串行数据线SDA 和串线时钟线SCL组成.I2C是一种多主机控制总线,它和USB总线不同,USB是基于master-slave机制,任何设备的通信必须由主机发起才可以,而 I ...

2020 unjeep.com webmaster#unjeep.com
12 q. 0.013 s.
京ICP备10005923号