zoukankan      html  css  js  c++  java
  • 小松之LINUX 驱动学习笔记(二)

    这两天一直在看字符驱动那块,后来从网上找啦几个例子,自己编译啦下,安装啥的都挺正常,就是用测试程序测试的时候总出问题,现在找到一个能测试的代码,自己先看看和原来的那个代码有啥不同,后面会继续更新,说下到底是啥问题导致驱动不能用。先附上能用代码的链接,这里先谢谢作者:

    http://blog.chinaunix.net/uid-22666248-id-3052861.html

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    
    #include <linux/cdev.h>
    #include <linux/device.h>
    #include <linux/slab.h>//kmalloc
    #include <linux/vmalloc.h>//vmalloc()
    #include <linux/types.h>//ssize_t
    #include <linux/fs.h>//file_operaiotns
    #include <linux/uaccess.h>//copy_from_user
    
    #define MEM_MALLOC_SIZE 4096 ////缓冲区大小
    #define MEM_MAJOR    240 ////主设备号
    #define MEM_MINOR    0
    
    char *mem_spvm = NULL; ////缓冲区指针,指向内存区
    struct cdev *mem_cdev = NULL; //字符设备对象指针
    struct class *mem_class = NULL; //设备类指针
    
    static int __init mem_init(void);
    static void __exit mem_exit(void);
    static int mem_open(struct inode *inode,struct file *filp);
    static int mem_release(struct inode *inode, struct file *filp);
    static ssize_t mem_read(struct file *filp,char __user *buf,size_t count,loff_t *fpos);
    static ssize_t mem_write(struct file *filp, char __user *buf,size_t count ,loff_t *fops);
    
    static const struct file_operations mem_fops={
        .owner = THIS_MODULE,
        .open = mem_open,
        .release = mem_release,
        .read = mem_read,
        .write = mem_write,
    };
    
    static int __init mem_init(void)
    {
        int ret;
        //创建设备号 主次设备号
        int devno = MKDEV(MEM_MAJOR,MEM_MINOR);
        printk("mem_init initial...
    ");
    
        //开辟内核内存缓冲区
        mem_spvm = (char *)vmalloc(MEM_MALLOC_SIZE);
        if(mem_spvm == NULL)
        {
            printk("vmalloc mem_spvm error
    ");
            return -ENOMEM;//
        }
        
        //
        mem_cdev = cdev_alloc();
        if(mem_cdev == NULL)
        {
            printk("cdev_alloc error
    ");
            return -ENOMEM;
        }
        cdev_init(mem_cdev,&mem_fops);
        mem_cdev->owner = THIS_MODULE;
        ret = cdev_add(mem_cdev,devno,1);//将字符设备键入内核系统
        if(ret)
        {
            cdev_del(mem_cdev);
            mem_cdev = NULL;
            printk("cdev_add error
    ");
            return -1;
        }
    
        //
        mem_class = class_create(THIS_MODULE,"ywx_class_char");
        if(IS_ERR(mem_class))
        {
            printk("class_create error..
    ");
            return -1;
        }
        device_create(mem_class,NULL,MKDEV(MEM_MAJOR,MEM_MINOR),NULL,"ywx_device_char");
        
        printk("init finished..
    ");
        return 0;
    }
    
    static void __exit mem_exit(void)
    {
        printk("mem_exit starting..
    ");
        if(mem_cdev != NULL)
            cdev_del(mem_cdev);
        printk("cdev_del ok
    ");
    
        device_destroy(mem_class,MKDEV(MEM_MAJOR,MEM_MINOR));
        class_destroy(mem_class);
    
        if(mem_spvm != NULL)
            vfree(mem_spvm);
    
        printk("vfree ok
    ");
        printk("mem_exit finished..
    ");
    }
    
    static int mem_open(struct inode *inode,struct file *filp)
    {
        printk("open vmalloc space..
    ");
        try_module_get(THIS_MODULE);//模块引用计数器自加
        printk("open vamlloc space ok..
    ");
        return 0;
    }
    static int mem_release(struct inode *inode, struct file *filp)
    {
        printk("close vmalloc space..
    ");
        module_put(THIS_MODULE);//模块引用计数器自减
        return 0;
    }
    static ssize_t mem_read(struct file *filp,char __user *buf,size_t count,loff_t *fpos)
    {
        int ret = -1;
        char *tmp;
        printk("copy data to the user space
    ");
        tmp = mem_spvm;
        if(count > MEM_MALLOC_SIZE)
            count = MEM_MALLOC_SIZE;
        if(tmp != NULL)//将内核数据写入到用户空间
            ret = copy_to_user(buf,tmp,count);
        if(ret == 0)
        {
            printk("read copy data success
    ");
            return count;
        }
        else
        {
            printk("read copy data error
    ");
            return 0;
        }
    }
    static ssize_t mem_write(struct file *filp, char __user *buf,size_t count ,loff_t *fops)
    {
        int ret = -1;
        char *tmp;
        printk("read data from the user space.
    ");
        tmp = mem_spvm;
        if(count > MEM_MALLOC_SIZE)
            count = MEM_MALLOC_SIZE;
        if(tmp != NULL)
            ret = copy_from_user(tmp,buf,count);
        if(ret == 0)
        {
            printk("write copy data success.
    ");
            return count;
        }
        else
        {
            printk("write copy data error.
    ");
            return 0;    
        }
    }
    
    MODULE_LICENSE("GPL");
    module_init(mem_init);
    module_exit(mem_exit);
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <string.h>//memset()
    
    int main(int argc, char *argv[])
    {
        int fd,cnt;
        char buf[256];
        int i;
        printf("char device testing..
    ");
        fd = open("/dev/ywx_device_char",O_RDWR);
        if(fd == 0)
        {
            printf("open failed.
    ");
            return 1;
        }
        
        printf("input the data for kernel:");
        scanf("%s",buf);
        cnt = write(fd,buf,256);
        if(cnt == 0)
            printf("write error
    ");
        
        printf("clear buf,and will read from kernel...
    ");
        for(i=0;i<256;i++)
            buf[i] = 32;//32 =" "
    
        cnt = read(fd,buf,256);
        if(cnt > 0)
            printf("read data from kernel is:%s
    ",buf);
        else
            printf("read data error
    ");
        close(fd);
        printf("close app..
    ");
        return 0;
    }

    运行的时候用root用户运行,可以看到/dev目录下有设备节点,然后运行test文件,可以看到能运行。

    make;sudo insmod xxx.ko; sudo ./app

  • 相关阅读:
    android数据恢复
    UVA 690 Pipeline Scheduling
    2017 国庆湖南 Day4
    2017 国庆湖南 Day5
    2017 国庆湖南 Day6
    2017国庆 清北学堂 北京综合强化班 Day1
    2017 国庆湖南Day2
    bzoj 2962 序列操作
    UVA 818 Cutting Chains
    UVA 211 The Domino Effect
  • 原文地址:https://www.cnblogs.com/cainiaoaixuexi/p/3688424.html
Copyright © 2011-2022 走看看