打印

字符驱动之二:实现读写

[复制链接]
193|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1. 驱动层:--相当于下边的 char_read.c 文件    ①先实现 file_operations 结构体中列的我们想要实现的函数,比如        static int hello_open (struct inode *inode, struct file *file)

        static int hello_release (struct inode *inode, struct file *file)

        ssize_t hello_read (struct file *filp, char *buff, size_t count, loff_t *offp)

        ssize_t hello_write (struct file *filp, const char  *buf, size_t count, loff_t *f_pos)

    ②关联上 file_operations 中的入口:        struct file_operations hello_fops = {

            .owner = THIS_MODULE,

            .open  = hello_open,

            .release = hello_release,

            .read  = hello_read,

            .write = hello_write

        };

    ③注册主设备号和填充 cdev 结构体:        dev_t devno = MKDEV (hello_major, hello_minor);

        result = register_chrdev_region (devno, number_of_devices, "hello");

        cdev_init (&cdev, &hello_fops);    //两个THIS_MODULE填充上设备号,hello_fops填充上file_operations(字符设备操作集合)

        cdev.owner = THIS_MODULE;

    ④注册 cdev 结构体:        error = cdev_add (&cdev, devno , 1);

        这一步之后,我们关联的函数的符号就放到了应用程序可以调用的地方了。

    ⑤卸载的时候,先注销 cdev 结构体,再注销主设备号        cdev_del (&cdev);

        unregister_chrdev_region (devno, number_of_devices);

如果是上边的这种思路,还需要手动的创建设备节点,如果需要自动的在程序中创建设备节点,用如下的函数:



device_create函数(linux2.6之后版本):-- 创建设备节点(设备节点所在的位置是 /dev 下)



所需库:

    linux/device.h

原型:

    struct device *device_create(struct class *cls, struct device *parent,

                                                    dev_t devt, void *drvdata,

                                                    const char *fmt, ...);

参数:

    ①cls,指向将要注册设备节点的类

    ②parent,指向这个新的设备节点的类的父类,如果有的话,没有则是NULL

    ③devt,将要添加的字符设备的设备号

    ④drvdata,和类设备有关的设备的数据的指针(a pointer to a struct device that is assiociated with this class device.)

    ⑤fmt,要注册的设备要显示的节点名字

例子:

    device_create(my_class,NULL,devno,NULL,"hello");



class_create函数:-- 创建类(在 /sys/class/ 下)

头文件:

    linux/device.h

原型:

struct class *class_create(struct module *owner, const char *name)

    owner,pointer to the module that is to "own" this struct class

    name,pointer to a string for the name of this class.

例子:

    struct class *my_class = class_create(THIS_MODULE,"char_hello");



他们相应的删除函数:

    device_destroy(my_class, devno);

    class_destroy(my_class);

这两个的顺序不能调换

2. 用户层函数:-- 相当于下边的 test.c 文件2.1 采用访问文件 IO 的方式打开文件        int fd;

        fd = open ("/dev/hello",O_RDWR);

            第一个参数是创建的节点

            第二个参数:

        O_RDONLY:表示对文件只读

        O_WRONLY:表示对文件只写

        O_RDWR:表示对文件可读可写

            上边这3个标志位是互斥的

        O_CREAT:当文件不存在时,创建文件

        O_EXCL:配合O_CREAT使用,当文件已经存在时创建,那么就会出错。

        O_TRUNC:如果文件已经存在,先删除源文件内容。

        O_APPEND:以添加方式打开,对文件的写操作都是在文件的末尾进行





2.2 写:write:--向文件描述符中写入数据

原型:

    ssize_t write(int fd,void *buf,size_t count);

参数:

    fd,要写的文件描述符

    buf,存放要写的数据

    count,期望执行一次write要写的字节个数

返回值:

    实际写入的字节个数。





例子:

         if (write (fd, buff, strlen(buff)) < 0)

        {

            perror("fail to write");

        }



2.3 读:read:--读文件,ssize其实就是int型,从文件描述符中读取数据

原型:

    ssize_t read(int fd,void *buf,size_t count);

参数:

    fd,要读的文件描述符

    buf,存放读取到的数据

    count,期望执行一次read要读取的字节个数

返回值:

    实际读到的字节个数。

    0,网络上断开连接返回

    -1,没有独到

特点:

    read读取数据和\n,\0没任何关系。





例子

        printf ("Read returns %d\n", read (fd, buf, sizeof(buf)));



2.4 文件描述符关闭:        close (fd);



3. 程序:char_read.c

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

457

主题

483

帖子

1

粉丝