基于VxWorks的内存模拟型的字符IO设备驱动程序,并实现任务间通信

要求:基于VxWorks的内存模拟型的字符IO设备驱动程序的设计,并编写应用程序实现任务间的通信,编写makefile文件。

1 内存模拟型的字符IO设备驱动程序memDrv.c

/* memDrv.c - pseudo memory device driver */
#include "memDrv.h"
/*memDrv - install a memory driver*/

STATUS memDrv (void)
    {
    /* If driver already installed, just return */	
    if (memDrvNum > 0)
	  return (OK);	/* driver already installed */
	  
	/* driver initialization, if any, here */
	  
	/* add driver to driver table */
    memDrvNum = iosDrvInstall ((FUNCPTR) NULL, (FUNCPTR) NULL,
			       (FUNCPTR) memOpen, memClose,
			       memRead, memWrite, memIoctl);
    return (memDrvNum == ERROR ? ERROR : OK);
    }
    
/*memDevCreate - create a memory device*/
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;
    status = iosDevAdd ((DEV_HDR *) pMemDv, name, memDrvNum);
    if (status == ERROR)
	  free ((MEM_DEV *) pMemDv);
    return (status);
    }
    
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 IO device*/

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 IO device */

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 */
    )
    {
      temp=pfd->pMemDev->MemBase;
     /* for(count=0;count<nbytes;count++)
          {
            bcopy (buffer,temp, 1);
            buffer=buffer+1;
            temp=temp+1;
            taskDelay(1);
          }    
      */
	  bcopy (buffer,pfd->pMemDev->MemBase, nbytes);
	  
	  return (nbytes);
    }
/* memIoctl - do device specific control function */

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 IO device */

LOCAL STATUS memClose (pfd)
     MEM_DEV_PER_FD *pfd;	/* file descriptor of file to close */
    {
    free (pfd);
    return OK;
    }


STATUS memDevDelete(char * devName)
	{
	DEV_HDR *pDevHdr;
	char *pNameTail;
        pDevHdr = iosDevFind (devName, &pNameTail);
   	if (pDevHdr == NULL || *pNameTail != '\0')
 		return (ERROR);
	iosDevDelete (pDevHdr);
        free ((MEM_DEV *) pDevHdr);
	return (OK);
}
		
		
STATUS memDrvRemove()
	{
	/*check device driver exist */
	if(memDrvNum!=-1)
	{ if(iosDrvRemove(memDrvNum,TRUE)==ERROR)
		{
		printErr("Fail to unload driver.\n");
		return ERROR;	
		}	
	}
	memDrvNum=-1;
	}	

2 设备驱动程序的头文件memDrv.h

#include "copyright_wrs.h"
#include "vxWorks.h"
#include "stat.h"
#include "dirent.h"
#include "memLib.h"
#include "errnoLib.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "ioLib.h"
#include "iosLib.h"

typedef struct	/* MEM_DEV - memory device descriptor */
    {
    DEV_HDR devHdr;
    char *MemBase; 
    int allowOffset1;
    }  MEM_DEV;

typedef struct		  /* MEM_DEV_PER_FD - memory deviceId */
    {
	MEM_DEV *pMemDev;
	int allowOffset2;   
   } MEM_DEV_PER_FD;

/* forward declarations */
LOCAL int memDrvNum;
LOCAL char *temp;	  /* driver number of memory driver */
LOCAL int count;
  /*MEM_DEV_PER_FD pMemDevPerFd;*/  

STATUS memDrv ();
STATUS memDevCreate();
LOCAL MEM_DEV_PER_FD *memOpen ();
LOCAL int memRead ();
LOCAL int memWrite ();
LOCAL int memClose ();
LOCAL STATUS memIoctl ();
STATUS memDevDelete();
STATUS memDrvRemove();

3 IO设备驱动实现任务间的通信的程序代码memIoDemo.c

/* includes */
#include "vxWorks.h"
#include "taskLib.h"
#include "msgQLib.h"
#include "sysLib.h"
#include "stdio.h" 
#include "ioLib.h"  
#include "memDrv.h"

#define  MemIoDev_NAME      "/memIoDevice"  /* 虚拟内存IO设备的文件名*/
#define  PRODUCER_TASK_PRI          98   /* Priority of the producer task */
#define  CONSUMER_TASK_PRI          99   /* Priority of the consumer task */
#define  TASK_STACK_SIZE          5000   /* stack size for spawned tasks */
#define  PRODUCER_TASK_MSG          3
#define  CONSUMER_TASK_MSG          3

struct msg {                             /* data structure for msg passing */
        int tid;                         /* task id */         
        int value;                       /* msg value */
        };

LOCAL int  memIoFd;  
LOCAL BOOL notDone;                      /* Flag to indicate the completion 
                                            of this demo */

/* function prototypes */

LOCAL STATUS producerTaskFunc ();           /* producer task */
LOCAL STATUS consumerTaskFunc ();           /* consumer task */


/*memIoDevDemo  */

int main (void)
    {
    notDone = TRUE;  /* initialize the global flag */
    printf ("memIoDevDemo\r\n");
    
    if(memDrv()== ERROR)
       {
        perror("Error in installing memory IO Device");
       }
   
    if (memDevCreate (MemIoDev_NAME, calloc(1,20), sizeof (struct msg)) == ERROR)  
         {  
         perror ("Error in creating memory IO Device");   
         }  
		 
    if ((memIoFd = open (MemIoDev_NAME, O_RDWR, 0)) == ERROR)  
         {  
         perror  ("Error in opening memory IO device");  
         return (ERROR);  
         }  
  
     /* Spwan the producerTask task */
    if (taskSpawn ("tProducerTask", PRODUCER_TASK_PRI, 0, TASK_STACK_SIZE, 
                   (FUNCPTR) producerTaskFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
                    == ERROR)
        {
        perror ("producerTask: Error in spawning demoTask");
        return (ERROR);
        } 

    /* Spwan the consumerTask task */
    if (taskSpawn ("tConsumerTask", CONSUMER_TASK_PRI, 0, TASK_STACK_SIZE, 
                   (FUNCPTR) consumerTaskFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
                   == ERROR)
        {
        perror ("consumerTask: Error in spawning demoTask");
        return (ERROR);
        }

    return (OK);
    }


/*****************************************************************************
 *  producerTask - produces messages, and sends messages to the consumerTask 
 *                 using the message queue. 
 *
 *  RETURNS: OK or ERROR
 *
 */

STATUS producerTaskFunc (void)
    {
    int count;
    int value;
    struct msg producedItem;           /* producer item - produced data */ 

    printf ("producerTask started: task id = %#x \n", taskIdSelf ());

    /* Produce 2 number of messages and send these messages */

    for (count = 1; count <= PRODUCER_TASK_MSG; count++)
        {
        value = count * 20;   /* produce a value */

        /* Fill in the data structure for message passing */
        producedItem.tid = taskIdSelf ();
        producedItem.value = value;

        /* Send Messages */
    
				
		if ((write (memIoFd, (char *)&producedItem, sizeof (producedItem))) == ERROR)  
             {  
                 perror ("Error in sending the message");  
                 return (ERROR);  
             } 	
		 
        else
            printf ("ProducerTask: tid = %#x, produced value = %d \n", 
                                                      taskIdSelf (), value);
        }

    if(PRODUCER_TASK_PRI > CONSUMER_TASK_PRI)
      {		
       memDevDelete("/memIoDevice");
       memDrvRemove();
       }
    return (OK);
    }

/*****************************************************************************
 *  consumerTask - consumes all the messages from the message queue. 
 *
 *  RETURNS: OK or ERROR
 *
 */

STATUS consumerTaskFunc (void)
    {
    int count;
    struct msg consumedItem;           /* consumer item - consumed data */

    printf ("\n\nConsumerTask: Started -  task id = %#x\n", taskIdSelf());

    /* consume 3 number of messages */
    for (count = 1; count <= CONSUMER_TASK_MSG; count++)
        {
        if (read (memIoFd, (char *)&consumedItem, sizeof (consumedItem)) == ERROR)  
             {  
             perror ("Error in receiving the message");  
             return (ERROR);  
             } 
					 
        else 
            printf ("ConsumerTask: Consuming msg of value %d from tid = %#x\n",
                            consumedItem.value, consumedItem.tid);
        }
    if(PRODUCER_TASK_PRI < CONSUMER_TASK_PRI)
	{		
      memDevDelete("/memIoDevice");
      memDrvRemove();
	}
    return (OK);
    }

4 makefile文件

CC=ccsimpc
CFLAGS=-g -O0 
all:memIoDevDemo.o memDrv.o
	$(CC) $(CFLAGS) memIoDevDemo.o memDrv.o -o all
memIoDevDemo.o:memIoDevDemo.c
	$(CC) $(CFLAGS) -c memIoDevDemo.c -o memIoDevDemo.o
memDrv.o:memDrv.c
	$(CC) $(CFLAGS) -c memDrv.c -o memDrv.o
.phony:clean
clean:
	-vxrm memIoDevDemo.o memDrv.o

5 运行步骤

5.1 在命令提示符下执行make命令

利用命令提示符执行make命令和make clean命令。
在这里插入图片描述

5.2 在windSh下加载模块all

在windSh下加载模块all,并执行main函数。
在这里插入图片描述

5.3 打印任务间通信结果

下图是打印在模拟器上的两任务间通信结果,生产者任务优先级高于消费者,生产者任务先运行,三次向同一段内存分别写入20、40、60。紧接着消费者任务运行,读取生产者写入那段内容,但三次读取到的数据均为60,因为生产者每次写入都会覆盖上一次写入的数据,所以最终只能读到数据60。

在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值