字符设备注册/注销

字符设备注册步骤:

1.分配cdev结构体

2.分配设备号,register_chrdev_region()/alloc_chrdev_region();

3.添加设备到系统,cdev_add();

字符设备注销步骤:

1. 从系统中删除设备,cdev_del();

2. 释放设备号,unregister_chrdev_region();

 

除了以上按步骤注册/注销字符设备外,系统也提供了函数直接完成设备的注册与注销。

 1 /**
 2  * __register_chrdev() - create and register a cdev occupying a range of minors
 3  * @major: major device number or 0 for dynamic allocation
 4  * @baseminor: first of the requested range of minor numbers
 5  * @count: the number of minor numbers required
 6  * @name: name of this range of devices
 7  * @fops: file operations associated with this devices
 8  *
 9  * If @major == 0 this functions will dynamically allocate a major and return
10  * its number.
11  *
12  * If @major > 0 this function will attempt to reserve a device with the given
13  * major number and will return zero on success.
14  *
15  * Returns a -ve errno on failure.
16  *
17  * The name of this device has nothing to do with the name of the device in
18  * /dev. It only helps to keep track of the different owners of devices. If
19  * your module name has only one type of devices it's ok to use e.g. the name
20  * of the module here.
21  */
22 int __register_chrdev(unsigned int major, unsigned int baseminor,
23               unsigned int count, const char *name,
24               const struct file_operations *fops)
25 {
26     struct char_device_struct *cd;
27     struct cdev *cdev;
28     int err = -ENOMEM;
29 
30     cd = __register_chrdev_region(major, baseminor, count, name);
31     if (IS_ERR(cd))
32         return PTR_ERR(cd);
33     
34     cdev = cdev_alloc();
35     if (!cdev)
36         goto out2;
37 
38     cdev->owner = fops->owner;
39     cdev->ops = fops;
40     kobject_set_name(&cdev->kobj, "%s", name);
41         
42     err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);
43     if (err)
44         goto out;
45 
46     cd->cdev = cdev;
47 
48     return major ? 0 : cd->major;
49 out:
50     kobject_put(&cdev->kobj);
51 out2:
52     kfree(__unregister_chrdev_region(cd->major, baseminor, count));
53     return err;
54 }
55 static inline int register_chrdev(unsigned int major, const char *name,
56                   const struct file_operations *fops)
57 {
58     return __register_chrdev(major, 0, 256, name, fops);
59 }
register_chrdev()
 1 /**
 2  * __unregister_chrdev - unregister and destroy a cdev
 3  * @major: major device number
 4  * @baseminor: first of the range of minor numbers
 5  * @count: the number of minor numbers this cdev is occupying
 6  * @name: name of this range of devices
 7  *
 8  * Unregister and destroy the cdev occupying the region described by
 9  * @major, @baseminor and @count.  This function undoes what
10  * __register_chrdev() did.
11  */
12 void __unregister_chrdev(unsigned int major, unsigned int baseminor,
13              unsigned int count, const char *name)
14 {
15     struct char_device_struct *cd;
16 
17     cd = __unregister_chrdev_region(major, baseminor, count);
18     if (cd && cd->cdev)
19         cdev_del(cd->cdev);
20     kfree(cd);
21 }
22 static inline void unregister_chrdev(unsigned int major, const char *name)
23 {
24     __unregister_chrdev(major, 0, 256, name);
25 }
unregister_chrdev()

 

转载于:https://www.cnblogs.com/yangjiguang/p/6034851.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux 下字符设备的驱动框架可以分为三个层次:用户空间、内核空间和硬件。 1. 用户空间 在用户空间,应用程序通过标准的文件操作(open, read, write, close, ioctl 等)来访问设备。这些操作被封装成系统调用,应用程序通过系统调用来与设备驱动进行交互。 2. 内核空间 在内核空间,设备驱动程序负责处理用户空间发来的请求,并将它们转换为硬件操作。在 Linux 中,设备驱动程序通常以模块的形式存在,可以通过 insmod 和 rmmod 命令来加载和卸载。 设备驱动程序主要包括以下几个部分: (1)初始化和清理函数:在 Linux 加载驱动模块时,会自动调用驱动程序中的初始化函数来完成设备的初始化工作。而在卸载模块时,会自动调用清理函数来完成设备的清理工作。 (2)设备注册注销函数:设备驱动程序需要通过设备注册函数将设备注册到系统中,并通过设备注销函数将设备从系统中注销。 (3)文件操作函数:文件操作函数包括 open、read、write、ioctl、release 等。这些函数是设备驱动程序的核心部分,负责处理用户空间发来的请求,并将它们转换为硬件操作。 (4)中断处理函数:在 Linux 中,驱动程序可以注册中断处理函数来处理硬件中断。当硬件发生中断时,内核会自动调用相应的中断处理函数。 3. 硬件 在硬件方面,设备驱动程序需要与硬件进行交互,包括对硬件进行初始化、读写寄存器等操作。这些操作通常通过 I/O 端口、内存映射等方式进行。在 Linux 中,访问硬件通常需要使用 I/O 端口映射或者内存映射技术。 ### 回答2: Linux下的字符设备驱动框架是由设备驱动程序和字符设备接口组成的。字符设备是一种面向流的数据传输,以字符为单位进行读写的设备,如串行端口、终端设备等。 在Linux中,字符设备驱动程序主要包括三个组件:设备文件操作函数、设备注册注销函数,以及字符设备驱动结构体。 设备文件操作函数是驱动程序中的核心部分,它包括对设备的打开、关闭、读取和写入等操作。这些函数在应用程序通过系统调用访问设备文件时被调用,并通过设备文件描述符和设备驱动结构体之间进行传递。 设备注册注销函数用于将驱动程序注册到系统中,并在不再使用时将其注销。这些函数通常在模块加载和卸载时调用,以便系统能够正确地识别和管理设备。 字符设备驱动结构体是驱动程序的核心数据结构,它包含了设备文件操作函数的指针以及其他驱动程序需要的信息。该结构体在驱动程序注册时被创建,并在使用过程中被驱动程序的其他组件所引用。 在Linux中,字符设备接口提供了一组函数,用于用户空间应用程序与字符设备驱动程序之间的通信。这些函数包括open()、close()、read()、write()等,通过这些函数,应用程序可以打开设备文件并对其进行读写操作。 总之,Linux下的字符设备驱动框架包括设备驱动程序和字符设备接口两个组成部分,其中设备驱动程序包括设备文件操作函数、设备注册注销函数和字符设备驱动结构体,字符设备接口提供了一组函数,用于应用程序与驱动程序之间的通信。这样的框架使得开发者能够轻松地编写和管理字符设备驱动程序,在Linux系统中实现更多种类的字符设备。 ### 回答3: Linux下字符设备的驱动框架主要包括设备描述结构体结构(struct cdev)、设备号分配和注册(dev_t、alloc_chrdev_region、cdev_init、cdev_add)、文件操作函数(open、read、write、release等)、设备文件的创建和删除(mkdev、mknod)以及设备的注册注销等几个关键步骤。 在字符设备驱动的框架中,首先需要定义一个设备描述结构体struct cdev,该结构体包含了设备操作函数指针、主设备号、次设备号等信息。接着通过alloc_chrdev_region函数进行设备号的分配和注册,或者使用register_chrdev_region函数进行设备号的注册。然后使用cdev_init函数对设备描述结构体进行初始化,并使用cdev_add函数将设备添加到系统中。 在文件操作函数上,驱动需要实现open、read、write、release等函数,用于处理用户空间对设备文件的打开、读取、写入和关闭操作。这些函数对应着相应的系统调用,通过在驱动中实现这些函数,可以与用户空间进行交互。 在设备文件的创建和删除上,可以使用mknod命令手动创建设备文件,也可以通过mkdev函数在驱动代码中自动创建设备文件。 最后,在设备注册注销的过程中,通过register_chrdev和unregister_chrdev函数将字符设备注册注销到系统中,系统会根据设备号调用相应的驱动进行操作,完成设备的初始化和卸载过程。 总之,Linux下字符设备的驱动框架主要包括设备描述结构体结构、设备号的分配和注册、文件操作函数的实现、设备文件的创建和删除,以及设备的注册注销等几个关键步骤,通过这些步骤可以实现字符设备的驱动和用户空间的交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值