zoukankan      html  css  js  c++  java
  • linux 2.6 驱动笔记(二)

    字符设备驱动

    linux 2.6的字符驱动由cdev结构体描述,具体参考globalmem例子,代码主要分以下几部分:

    1. 定义一个字符类型设备驱动的结构体

    struct globalmem_dev{
        struct cdev cdev; /*linux 2.6 内核表示一个字符设备结构体 */
        unsigned char mem[200];
    };

    其中cdev在cdev.h文件中定义如下:

    struct cdev {
        struct kobject kobj;
        struct module *owner;
        struct file_operations *ops; //文件操作结构体
        struct list_head list;
        dev_t dev; //设备号 unsigned long
        unsigned int count;
    };

    2. 在驱动模块的加载、卸载函数中注册设备,同时绑定文件操作结构体

    static const struct file_operations globalmem_fops = {
        .owner     = THIS_MODULE,
        .llseek    = globalmem_llseek,
        .read   = globalmem_read,
        .write  = globalmem_write,
        .open   = globalmem_open,
        .release= globalmem_release};
    
    //设备驱动加载
    int globalmem_init(void){
        int result;
        dev_t devno = MKDEV(200, 0);
    
        result = register_chrdev_region(devno, 1, "globalmem");//注册字符设备编号
        globalmem_devp= kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL);
        memset(globalmem_devp, 0, sizeof(struct globalmem_dev));
    
        cdev_init(&globalmem_devp->cdev, &globalmem_fops);
        globalmem_devp->cdev.owner = THIS_MODULE;
    
        int err = cdev_add(&globalmem_devp->cdev, devno, 1);
    
        return result;
    }

    3. 实现文件操作的具体接口,以文件写为例:

    static ssize_t globalmem_read(struct file *flip, char __user *buf, size_t size, loff_t *ppos){
           //....
        
        struct globalmem_dev *dev = flip->private_data;
        copy_to_user(buf, (void*)(dev->mem+p), count); //内核空间拷贝至用户空间
        *ppos += count;

    测试用应用代码如下:

    #include<sys/types.h>
    #include<sys/stat.h>
    #include<stdio.h>
    #include<fcntl.h>
    
    void main(){
        int fd,num;
    
        fd = open("/dev/globalmem", O_RDWR);
    
        if(fd != -1){
            read(fd, &num, sizeof(int));
            printf("the globalmem is %d
    ", num);
    
            scanf("%d", &num);
            printf("the input is %d
    ", num);
            write(fd, &num, sizeof(int));
    
            read(fd, &num, sizeof(int));
            printf("the new globalmem is %d/n", num);
        
            close(fd);
            
        }else{
            printf("device err!");
        }
        return;
    }
  • 相关阅读:
    python通过帐号和密码访问mysql
    pyqt5简单登陆界面
    PyQt5点击按钮产生新窗体
    ubuntu访问win10下的磁盘
    python平均值和加权平均值
    牛顿迭代法求高次方程的根
    运用模逆运算(同余方程)来解决Matlab课上的一道思考题
    线程实现方式与临界区保护
    线程调度的问题:Lock Convoy(锁封护)与Priority Inversion(优先级反转)
    C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)
  • 原文地址:https://www.cnblogs.com/Fredric-2013/p/3153569.html
Copyright © 2011-2022 走看看