ARM&Linux 下驱动开发第三节

后台驱动代码如下:比较昨天的,添加了读写指针位置移动操作
#include<linux/init.h>

#include<linux/module.h>

#include<linux/kernel.h>

#include <linux/poll.h>    /* COPY_TO_USER */

#include<linux/errno.h>

#include <linux/cdev.h>

#include <linux/slab.h>



#define DEV_NAME "rwtest"

#define DEV_NUM 2

#define DEV_MEM_SIZE 4096



static int major=0;

//static int MAX_BUF_LEN=1024;

static char drv_buffer[2][1024];

//static char drv_buf0[1024];

//static char drv_buf1[1024];

//static int WRI_LENGTH=0;

struct cdev cdev;

struct mem_dev * mem_devp; /*璁惧缁撴瀯浣撴寚閽?/



/*mem璁惧鎻忚堪缁撴瀯浣?/

struct mem_dev                                     

{                                                        

  char *data;                      

  unsigned long size;       

};



/***********鍐欏叆*************************/

static ssize_t  dx_write(struct file *filp, const char __user *buffer, size_t size, loff_t * ppos)

{ 

    unsigned long p=*ppos;

    unsigned int count =size;

    int ret=0;

    char * data=filp->private_data ;

    //struct mem_dev *dev = filp->private_data; /*鑾峰緱璁惧缁撴瀯浣撴寚閽?/

    //struct mem_dev *dev=&mem_devp[0];/*鑾峰緱璁惧缁撴瀯浣撴寚閽?  [0]*/

    printk("data:::%s\n",data);

    if(p>=DEV_MEM_SIZE)return 0;

    if(count>DEV_MEM_SIZE-p)

    {

        count=DEV_MEM_SIZE-p;

    }

    printk("write p::%ld\n",p);

    /*浠庤繃鎴风┖闂村啓鍏ユ暟鎹?/

    if(copy_from_user(data + p,buffer,count))

    {

        ret=-EFAULT;

    }

    else

    {

        *ppos +=count;

        ret=count;

        printk(KERN_INFO "written %d bytes from %ld\n",count,p);

    }

    printk("write:%s\n",(char *)(filp->private_data+p));

    printk("write buffer:%s\n",buffer);

    return count;

}

/**************************************璇诲彇***********************************************/

static ssize_t  dx_read(struct file *filp, char __user *buffer, size_t size, loff_t *ppos)

{    

    //鏂囦欢璇诲彇浣嶇疆

    unsigned long p=*ppos;

    unsigned int count =size;//瑕佽鍙栫殑,澶у皬

    int ret=0;

    char * data=filp->private_data ;

    //struct mem_dev *dev = filp->private_data; /*鑾峰緱璁惧缁撴瀯浣撴寚閽?/

    //struct mem_dev *dev=&mem_devp[0];/*鑾峰緱璁惧缁撴瀯浣撴寚閽?  [0]*/

    

    if(p>=DEV_MEM_SIZE)

        return 0;

    if(count>DEV_MEM_SIZE-p)

    {

        count=DEV_MEM_SIZE-p;

    }

    printk("read p::%ld\n",p);

    /*浠庢暟鎹鍒扮敤鎴风┖闂?*/

    if(copy_to_user(buffer,data + p,count))

    {

        ret=-EFAULT;

    }

    else

    {

        *ppos +=count;

        ret=count;

        printk(KERN_INFO "written %d bytes from %ld\n",count,p);

    }

    printk("read:%s\n",(char *)(filp->private_data));

    printk("read buffer:%s\n",buffer);

    return count;

}

 //===========================鎵撳紑=========================================

static int dx_open(struct inode *inode, struct file *filp)

{

    //printk("device open sucess!\n");

    //struct mem_dev *dev;

    /*鑾峰彇娆¤澶囧彿*/

    int num = MINOR(inode->i_rdev);



    if (num >= DEV_NUM) 

        return -ENODEV;

    //dev = &mem_devp[num];

    //dev = drv_buffer[num];

    printk("num:%d\n",num);

    /*灏嗚澶囨弿杩扮粨鏋勬寚閽堣祴鍊肩粰鏂囦欢绉佹湁鏁版嵁鎸囬拡*/

    filp->private_data = drv_buffer[num];

    filp->f_pos +=strlen(drv_buffer[num]);

    printk("open:%s\n",(char *)filp->private_data);

    return 0;

}

/**********************************release***************************************************/

static int  dx_release(struct inode *inode, struct file *filp)

{

    printk("device release\n");

    return 0;

}



 

static loff_t dx_llseek(struct file *filp, loff_t offset, int whence)

{ 

    loff_t newpos;



    switch(whence) {

        case 0: /* SEEK_SET */

            newpos = offset;//鏂囦欢寮€濮嬩綅缃姞鍋忕Щ閲?            break;

        case 1: /* SEEK_CUR */

            newpos = filp->f_pos + offset;//褰撳墠鎸囬拡浣嶇疆鍔犲亸绉婚噺

            break;

        case 2: /* SEEK_END */

            newpos = DEV_MEM_SIZE -1 + offset;//鏂囦欢鏈熬鍔犲亸绉婚噺(鏈€鍚庝竴浣嶄负'\0')

            break;

        default: /* can't happen */

            return -EINVAL;

    }

    if ((newpos<0) || (newpos>DEV_MEM_SIZE))

        return -EINVAL;

    filp->f_pos = newpos;

    return newpos;

}





//===============缁撴瀯浣?椹卞姩鍚勫睘鎬?=========

static struct file_operations file_opt = {

    .owner=    THIS_MODULE,

    .llseek=  dx_llseek,

    .write=    dx_write,    

    .read=    dx_read,    

    .open=    dx_open,  

    .release=dx_release,

};

//----------------------------------------------------------------------

static int __init qudong_init(void)

{

    int ret;

     ret = register_chrdev(0, DEV_NAME, &file_opt);

     if(ret<0)

     {

         printk(DEV_NAME " can't get major number\n");

        return 0;

     }

     major=ret;

     printk("dx module major number is %d\n", ret);

     return 0;

}

//-----------------------------------------------------------------------

static void __exit qudong_exit(void)

{

    /*娉ㄩ攢璁惧*/

    cdev_del(&cdev);

    //kfree(mem_devp);     /*閲婃斁璁惧缁撴瀯浣撳唴瀛?/

    unregister_chrdev_region(MKDEV(major,0),1);/*閲婃斁璁惧鍙?/

    printk("exit\n");

}

module_init(qudong_init);

module_exit(qudong_exit);

MODULE_LICENSE("GPL");/*浣跨敤鏉冮檺*/

MODULE_AUTHOR("Made in China  <[email protected]>");/*浣滆€?/

MODULE_DESCRIPTION("s3c6410 Hypervisor Filesystem");/*鐗堟湰*/
View Code

测试代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include<string.h>

int main()

{

    int fd0=0;

    int fd1=0;

    int ret=0;

    char bufw[100]={'\0'};

    char bufr[100]={'\0'};

    char bufw1[100]={'\0'};

    char bufr1[100]={'\0'};

    fd0=open("/dev/rw0",O_RDWR);

    if(fd0<0)

    {

        perror("open error\n");

        return 0;

    }

    fd1=open("/dev/rw1",O_RDWR);

    if(fd1<0)

    {

        perror("open error\n");

        return 0;

    }

    printf("Please input string:\n");

    scanf("%s",bufw);

    ret=write(fd0,bufw,strlen(bufw));

    if(ret<0)

    {

        perror("write bufw error\n");

        return 0;

    }

    printf("burw====%s\n",bufw);

    printf("Please input string:\n");

    scanf("%s",bufw1);

    ret=write(fd1,bufw1,strlen(bufw1));

    if(ret<0)

    {

        perror("write bufw1 error\n");

        return 0;

    }

    printf("burw1====%s\n",bufw1);

    int num0=strlen(bufw);

    printf("num0:%d\n",num0);

    lseek(fd0,-(num0),SEEK_CUR);

    //lseek(fd0,0,SEEK_CUR);

    ret=read(fd0,bufr,99);

    if(ret<0)

    {

        perror("read bufr error\n");

        return 0;

    }

    printf("bufr====%s\n",bufr);

    int num1=strlen(bufw1);

    printf("num1:%d\n",num1);

    lseek(fd1,-(num1),SEEK_CUR);

    //lseek(fd1,0,SEEK_SET);

    ret=read(fd1,bufr1,99);

    if(ret<0)

    {

        perror("read bufr1 error\n");

        return 0;

    }

    printf("bufr1====%s\n",bufr1);

    

    close(fd0);

    close(fd1);

    return 0;

}
View Code

Makefile文件:

## Makefile template.



 

obj-m := qudong.o

UNAME := $(shell uname -r)

PWD := $(shell pwd)

ADVMOD := qudong

 

defualt:

    @make -C /lib/modules/$(UNAME)/build SUBDIRS=$(PWD) modules

 

clean:    

    @rm -f *.o    

    @rm -f *.ko

    @rm -f *.mod.c

    @rm -f .*.cmd

    @rm -rf .tmp_versions

#endif
View Code

 

你可能感兴趣的:(linux)