• 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
  • 相关阅读:
    centos7安装doxygen
    mysql和mariadb支持insert delayed的问题
    Ubuntu用android-ndk-r15c编译boost_1_65_1
    记不住的Android活动的生命周期
    SpringBoot——经典的Hello World【二】
    SpringBoot——报错总结
    SpringBoot——SpringBoot学习记录【一】
    Nginx——配置文件服务下载
    CRAP-API——如何在Linux服务器部署CRAP-API教程
    Linux—— 报错汇总
  • 原文地址:https://www.cnblogs.com/linkong1081/p/3584365.html
Copyright © 2020-2023  润新知