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
",data);
    if(p>=DEV_MEM_SIZE)return 0;
    if(count>DEV_MEM_SIZE-p)
    {
        count=DEV_MEM_SIZE-p;
    }
    printk("write p::%ld
",p);
    /*浠庤繃鎴风┖闂村啓鍏ユ暟鎹?/
    if(copy_from_user(data + p,buffer,count))
    {
        ret=-EFAULT;
    }
    else
    {
        *ppos +=count;
        ret=count;
        printk(KERN_INFO "written %d bytes from %ld
",count,p);
    }
    printk("write:%s
",(char *)(filp->private_data+p));
    printk("write buffer:%s
",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
",p);
    /*浠庢暟鎹��鍒扮敤鎴风┖闂?*/
    if(copy_to_user(buffer,data + p,count))
    {
        ret=-EFAULT;
    }
    else
    {
        *ppos +=count;
        ret=count;
        printk(KERN_INFO "written %d bytes from %ld
",count,p);
    }
    printk("read:%s
",(char *)(filp->private_data));
    printk("read buffer:%s
",buffer);
    return count;
}
 //===========================鎵撳紑=========================================
static int dx_open(struct inode *inode, struct file *filp)
{
    //printk("device open sucess!
");
    //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
",num);
    /*灏嗚�澶囨弿杩扮粨鏋勬寚閽堣祴鍊肩粰鏂囦欢绉佹湁鏁版嵁鎸囬拡*/
    filp->private_data = drv_buffer[num];
    filp->f_pos +=strlen(drv_buffer[num]);
    printk("open:%s
",(char *)filp->private_data);
    return 0;
}
/**********************************release***************************************************/
static int  dx_release(struct inode *inode, struct file *filp)
{
    printk("device release
");
    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;//鏂囦欢鏈�熬鍔犲亸绉婚噺(鏈€鍚庝竴浣嶄负'')
            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
");
        return 0;
     }
     major=ret;
     printk("dx module major number is %d
", ret);
     return 0;
}
//-----------------------------------------------------------------------
static void __exit qudong_exit(void)
{
    /*娉ㄩ攢璁惧�*/
    cdev_del(&cdev);
    //kfree(mem_devp);     /*閲婃斁璁惧�缁撴瀯浣撳唴瀛?/
    unregister_chrdev_region(MKDEV(major,0),1);/*閲婃斁璁惧�鍙?/
    printk("exit
");
}
module_init(qudong_init);
module_exit(qudong_exit);
MODULE_LICENSE("GPL");/*浣跨敤鏉冮檺*/
MODULE_AUTHOR("Made in China  <china@hotmail.com>");/*浣滆€?/
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]={''};
    char bufr[100]={''};
    char bufw1[100]={''};
    char bufr1[100]={''};
    fd0=open("/dev/rw0",O_RDWR);
    if(fd0<0)
    {
        perror("open error
");
        return 0;
    }
    fd1=open("/dev/rw1",O_RDWR);
    if(fd1<0)
    {
        perror("open error
");
        return 0;
    }
    printf("Please input string:
");
    scanf("%s",bufw);
    ret=write(fd0,bufw,strlen(bufw));
    if(ret<0)
    {
        perror("write bufw error
");
        return 0;
    }
    printf("burw====%s
",bufw);
    printf("Please input string:
");
    scanf("%s",bufw1);
    ret=write(fd1,bufw1,strlen(bufw1));
    if(ret<0)
    {
        perror("write bufw1 error
");
        return 0;
    }
    printf("burw1====%s
",bufw1);
    int num0=strlen(bufw);
    printf("num0:%d
",num0);
    lseek(fd0,-(num0),SEEK_CUR);
    //lseek(fd0,0,SEEK_CUR);
    ret=read(fd0,bufr,99);
    if(ret<0)
    {
        perror("read bufr error
");
        return 0;
    }
    printf("bufr====%s
",bufr);
    int num1=strlen(bufw1);
    printf("num1:%d
",num1);
    lseek(fd1,-(num1),SEEK_CUR);
    //lseek(fd1,0,SEEK_SET);
    ret=read(fd1,bufr1,99);
    if(ret<0)
    {
        perror("read bufr1 error
");
        return 0;
    }
    printf("bufr1====%s
",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
原文地址:https://www.cnblogs.com/linkong1081/p/3584365.html