设备驱动框架简介

来源:互联网 发布:自古枪兵幸运e 知乎 编辑:程序博客网 时间:2024/05/16 15:32

1 API

(1)register_chrdev_region(dev_t from,unsinged count,const char *name);(2)cdev_init(struct cdev*,struct file_operations *);(3)cdev_add(struct cdev*,dev_t,unsinged);

2 字符设备驱动组成

(1)字符设备驱动模块加载与卸载函数

在字符设备驱动模块加载函数中应该实现设备号的申请和cdev的注册,而在卸载函数中应实现设备号的释放和cdev的注销。

//设备结构体    struct xxx_dev_t{        struct cdev cdev;        ...    }xxx_dev;    //设备驱动模块加载函数    static int __init xxx_init(void){    ...    cdev_init(&xxx_dev.cdev,&xxx_fops);//初始化cdev    xxx_dev.cdev.owner=THIS_MODULE;    //获取字符设备号    if(xxx_major){        register_chrdev_region(xxx_dev_no,1,DEV_NAME);    }else{        alloc_chrdev_region(&xxx_dev_no,0,1,DEV_NAME);    }        ret=cdev_add(&xxx_dev.cdev,xxx_dev_no,1);注册设备    }    //设备驱动模块卸载函数    static void __exit xxx_exit(void){    unregister_chrdev_region(xxx_dev_no,1);    cdev_del(&xxx_dev.cdev);    }
(2) 字符设备驱动的file_operations结构体file_operations结构体中的成员函数是字符设备驱动与内核的接口,是用户控件对Linux进行系统调用最终的落实者。大多数字符设备驱动会实现read()、write()、ioctl()函数,形式如下:
file_operations结构体中的成员函数是字符设备驱动与内核的接口,是用户控件对Linux进行系统调用最终的落实者。大多数字符设备驱动会实现read()、write()、ioctl()函数,形式如下:    //读设备    sszie_t xxx_read(struct file *filep,char __user *buf,size_t count,loff_t *f_pos){        ...        copy_to_user(buf,...,...);        ...    }    //写设备    sszie_t xxx_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos){        ...        copy_from_user(...,buf,...);        ...    }    int XXX_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){        ...        swtich(cmd){            case xxx:            break;            ...            default:        }    }    filp是文件结构体指针,buf是用户控件内存地址,该地址在内核空间不能直接读写,count是要读的字节数,f_pos是读的位置相对于文件开头的便宜。
    由于内核空间与用户控件的内存不能直接互访,因此借助copy_from_user和copy_to_user。    如果要复制的内存是简单类型,如char,则可以使用简单的put_user()和get_user(),如下所示:    int val;//内核空间整型变量    ...    get_user(val,(int*)arg);//用户空间到内核空间,arg是用户空间的地址    ...    put_user(val,(int*)arg);//内核空间到用户空间,arg是用户空间的地址    读和写函数中的__user是一个宏,表明气候的指针指向用户空间,定义如下:
    #ifdef _ _CHECKER_ _    # define _ _user _ _attribute_ _((noderef, address_space(1)))    #else    # define _ _user    #endif
0 1
原创粉丝点击