曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 7488|回复: 0
打印 上一主题 下一主题

[字符设备] 字符设备驱动的组成

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-8-29 02:06:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在 Linux 系统中,字符设备驱动由如下几个部分组成。

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

在字符设备驱动模块加载函数中应该实现设备号的申请(也可以事先指定)和 cdev 的注册,而在卸载函数中实现设备号的释放和 cdev 的注销。

通常的,习惯将设备定义为一个设备相关的结构体,其包含该设备所涉及的 cdev、私有数据及信号量等信息。常见的设备结构体、模块加载和卸载函数形式如下代码所示:
/*设备结构体*/
struct xxx_dev_t {
        struct cdev cdev;
        ...
}

/*设备驱动模块加载函数*/
static int __init xxx_init(void) {
        ...
        /*初始化 cdev*/
        cdev_init (&xxx_dev.cdev, &xxx_fops);
        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() 函数,常见的字符设备驱动的这 3 个函数形式如下代码所示:
/*读设备*/
ssize_t xxx_read (struct file *filp, char __user *buf, size_t count, loff_t *f_ops)
{
        ...
        copy_to_user (buf, ..., ...);
        ...
}

/*写设备*/
ssize_t xxx_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_ops)
{
        ...
        copy_from_user (..., buf, ...);
        ...
}

/* ioctl 函数 */
int xxx_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
        ...
        switch (cmd) {
                case XXX_CMD1:
                ...
                break;

                case XXX_CMD2:
                ...
                break;

                default:
                /* 不能支持的命令 */
                return -ENOTTY;
        }

        return 0;
}

设备驱动的读函数中,filp 是文件结构体指针,buf 是用户空间内存的地址,该地址在内核空间不能直接读写,count 是要读的字节数,f_ops 是读的位置相对于文件开头的偏移。

写函数与读函数类似。

由于内核空间与用户空间的内存不能直接互访,因此借助函数 copy_from_user() 完成用户空间到内核空间的复制,函数 copy_to_user() 完成内核空间到用户空间的复制。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 00:37 , Processed in 0.074015 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表