当前位置: 首页 > news >正文

网站页面数量百度联盟怎么加入

网站页面数量,百度联盟怎么加入,西安最近爆发什么病毒,微信创建网站应用程序基本概念之什么是驱动程序()? 驱动程序本质上是代码逻辑的集合,通常用于管理、驱动多个设备实例。某个设备要想使用驱动程序,需要实例化相应的驱动程序的结构体,并在系统中注册,获得主设备号、次设备号,并…

基本概念之什么是驱动程序()?

驱动程序本质上是代码逻辑的集合,通常用于管理、驱动多个设备实例。某个设备要想使用驱动程序,需要实例化相应的驱动程序的结构体,并在系统中注册,获得主设备号、次设备号,并将相应的结构体、变量、函数等进行绑定。
这里重点要理解驱动程序只是代码逻辑的集体,并不等同于设备,驱动程序本身并没有主设备号、次设备号等,主设备号、次设备号是在注册设备实例时才有的概念。

Linux系统中常见的设备类型有哪些?

在 Linux 系统中,设备可以分为不同的类型,主要根据它们的工作方式、接口和功能进行分类。以下是 Linux 系统中常见的设备类型:


1. 字符设备 (Character Devices)

字符设备是按字符流方式进行数据传输的设备,每次读写都涉及一个字符或字节的数据。例如:

  • 终端设备 (tty): 用于与用户交互的设备,如串口终端、虚拟终端。
  • 串口设备 (ttyS): 串口通信设备,如 /dev/ttyS0
  • 键盘 (kbd): 连接的键盘设备。
  • 鼠标 (mouse): 连接的鼠标设备。
  • 伪设备:例如 /dev/null/dev/random/dev/zero 等,这些设备没有硬件实现,提供特殊的功能。

特点

  • 按字符流进行读写,每次读写一个字符(或字节)。
  • 通过字符设备文件(如 /dev/ttyS0)与应用程序交互。

2. 块设备 (Block Devices)

块设备是按块(通常是 512 字节或更大的单位)进行数据传输的设备。它们支持随机访问和缓存功能。例如:

  • 硬盘 (/dev/sda, /dev/sdb 等): 计算机的主要存储设备。
  • 固态硬盘 (SSD) (/dev/sda1, /dev/nvme0n1): 新型存储设备,提供更高的读写速度。
  • 光盘驱动器 (/dev/cdrom): 用于读取光盘数据的设备。
  • USB 存储设备 (/dev/sdb1, /dev/sdc): 连接到系统的 USB 存储设备。
  • 虚拟磁盘 (/dev/loop0): 用于挂载虚拟磁盘映像的设备。

特点

  • 支持随机读写访问,通常用于文件系统的挂载。
  • 设备文件通常位于 /dev/ 目录下。

3. 网络设备 (Network Devices)

网络设备是用于网络通信的设备。它们支持网络接口的连接和数据传输。例如:

  • 以太网卡 (eth0, eth1): 网络接口,用于连接有线网络。
  • 无线网卡 (wlan0, wlan1): 用于连接无线网络。
  • 虚拟网络设备 (lo): 回环接口,用于与本机进行网络通信。

特点

  • 用于实现计算机与外部网络的通信。
  • 可以是有线或无线设备,支持 TCP/IP 等协议。

4. 输入设备 (Input Devices)

输入设备是用于将用户输入传递给计算机的设备。它们通常使用字符设备接口。例如:

  • 鼠标 (/dev/input/mice): 用于提供用户的指针控制输入。
  • 键盘 (/dev/input/event0): 用于接收用户的键盘输入。
  • 触摸屏 (/dev/input/eventX): 用于接收触摸操作。

特点

  • 输入设备通常通过 /dev/input/ 目录进行管理,使用字符设备接口。
  • 输入事件通过设备文件传递给应用程序。

5. 虚拟设备 (Virtual Devices)

虚拟设备并不对应于物理硬件设备,而是通过软件实现的设备。例如:

  • 虚拟终端 (/dev/tty0, /dev/tty1): 提供与系统交互的虚拟控制台。
  • 内存设备 (/dev/mem): 用于访问物理内存的虚拟设备。
  • 随机数设备 (/dev/random, /dev/urandom): 用于生成随机数的设备。

特点

  • 不依赖于硬件,而是由内核或驱动程序模拟。
  • 提供系统管理或特殊功能。

6. 特殊设备 (Special Devices)

这些设备通常与硬件密切相关,但它们的作用和用法比较特殊。例如:

  • 时钟设备 (/dev/rtc): 实时钟设备,用于管理系统时间。
  • 伪设备 (/dev/null, /dev/zero): 不涉及实际硬件,而是提供特殊功能,通常用于丢弃或生成数据。

7. USB 设备 (USB Devices)

USB 设备通过 USB 总线连接到计算机,涵盖了各种设备类型。例如:

  • USB 存储设备 (/dev/sda1, /dev/sdb1): 连接的 USB 存储。
  • USB 摄像头 (/dev/video0): 通过 USB 接口连接的摄像头。
  • USB 键盘和鼠标 (/dev/input/eventX): 连接的 USB 键盘和鼠标。

特点

  • 支持即插即用(plug-and-play),可以动态连接和断开。

8. 串口设备 (Serial Devices)

串口设备通过串行接口进行通信,通常用于较为传统的设备。例如:

  • 串口终端 (/dev/ttyS0, /dev/ttyS1): 传统的串口设备。
  • 调制解调器 (/dev/ttyUSB0): 通过串口连接的调制解调器。

特点

  • 通过串行接口传输数据,通常用于低速数据通信。

9. SCSI 设备 (SCSI Devices)

SCSI 是一种广泛用于硬盘、光驱等设备的标准接口。例如:

  • SCSI 硬盘 (/dev/sda, /dev/sdb): SCSI 接口的硬盘设备。
  • SCSI 光驱 (/dev/sr0): SCSI 接口的光驱设备。

特点

  • 高性能和扩展性,常用于服务器或工作站中。
  • 支持多个设备共享同一总线。

10. PCI 设备 (PCI Devices)

PCI 总线上的设备用于高性能数据交换。例如:

  • 显卡 (/dev/video0): 通过 PCI 接口连接的显卡设备。
  • 网卡 (/dev/eth0): 通过 PCI 接口连接的网卡设备。
  • 音频设备 (/dev/snd/pcmC0D0p): 通过 PCI 接口连接的音频设备。

特点

  • 高速数据传输,支持多种设备接口。
  • 通过 PCI 总线连接多个设备。

11. I2C 和 SPI 设备 (I2C/SPI Devices)

I2C 和 SPI 是常用于嵌入式设备的通信协议,用于连接传感器、显示器等设备。例如:

  • I2C 设备:通过 I2C 总线连接的设备,通常位于 /dev/i2c-X
  • SPI 设备:通过 SPI 总线连接的设备,通常位于 /dev/spidevX.Y

特点

  • 用于短距离、高速的设备间通信。
  • 主要用于嵌入式系统中的外围设备。

小结

在 Linux 系统中,设备类型非常丰富,主要包括字符设备、块设备、网络设备、输入设备、虚拟设备、USB 设备、串口设备等。每种设备都有不同的特点和用途,Linux 系统通过设备文件(通常位于 /dev/ 目录下)来对这些设备进行管理和访问。

什么叫主设备号、次设备号?

主设备号、次设备号是Linux系统管理设备的一种结构,通常如果有多个设备,其驱动程序如果一样,那我们为其分配相同的主设备号,内核通过主设备号找到负责处理该设备的驱动程序。但它们的次设备号不同,通过不同的次设备号来区别它们。
当然如果设备类型相同,驱动程序也相同,你也可以为它们分配不同的主设备号,不过不建议这样做,这不符号Linux的基本设计原则。
不过也有特例,比如不同类型的设备有时会使用相同的驱动程序,但此时我们也会为它们分配不同的主设备号,以便在系统中区分。例如:块设备和字符设备通常使用不同的主设备号,即使它们底层可能由同一个驱动程序管理。

以字符设备为例,有了驱动程序后,为设备提供驱动程序并注册进系统的通常流程是怎么样的?

这里以字符设备为例。
这里以字符设备为例。
这里以字符设备为例。

注意:不同的设备类型有不同的对应下面各步骤的函数,但流程基本上是一样的。
注意:不同的设备类型有不同的对应下面各步骤的函数,但流程基本上是一样的。
注意:不同的设备类型有不同的对应下面各步骤的函数,但流程基本上是一样的。

第一步是调用函数alloc_chrdev_region()获得可用的主设备号、次设备号。

示例代码如下:

dev_t dev;
ret = alloc_chrdev_region(&dev, 0, 3, "my_device");

函数alloc_chrdev_region()的原型如下:

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, const char *name);

参数解释

  1. dev
    指向一个 dev_t 类型的变量,用于保存分配的设备号(包含主设备号和次设备号)。成功分配后,可以通过 MAJOR(dev)MINOR(dev) 宏提取主设备号和次设备的起始号

  2. firstminor
    表示从哪个次设备号开始分配,一般设置为 0

  3. count
    表示需要分配的连续次设备号的数量。如果你需要多个次设备号,可以指定这个值(通常为 1 表示只分配一个设备号)。

  4. name
    为设备指定一个名字,这个名字主要用于调试时显示(比如 /proc/devices 中会看到)。

alloc_chrdev_region 运行后,系统为我们将要注册的设备分配了:

  1. 一个主设备号
    主设备号是系统在字符设备表中分配的唯一标识,用于将设备与驱动程序关联。

  2. 一个连续的次设备号范围
    根据调用时指定的 count 参数,系统分配了一段连续的次设备号范围。

这意味着,分配完成后:

  • 我们的设备对应的设备号范围是:
    (主设备号, 起始次设备号)(主设备号, 起始次设备号 + count - 1)
  • 每个次设备号可以用来表示不同的设备实例,但它们共享相同的主设备号。

这里要特别注意:变量dev中保存的是系统为我们分享的主设备号和次设备的超始号,而不是所有的次设备号哈。

第二步是调用函数cdev_init()将描述字符设备的核心结构体cdev的实例和核心结构体file_operations的实例绑定起来

示例代码如下:

static struct cdev my_cdev; // 定义字符设备结构体
static struct file_operations my_fops = {.owner = THIS_MODULE,.open = my_open,.read = my_read,.write = my_write,.release = my_close,
};/* 核心结构体cdev和结构体file_operations的绑定 */
cdev_init(&my_cdev, &my_fops);}

这里面涉及到两个重要的结构体,第一个是struct cdev 、另一个是 struct file_operations,下面进行介绍:

struct cdev 是 Linux 内核中的一个核心结构,用于表示字符设备的相关信息。

定义(简化版)

struct cdev {struct kobject kobj;                // 内核对象,用于 sysfs 集成const struct file_operations *ops; // 设备支持的操作集struct list_head list;             // 用于链接到内核的 cdev 列表dev_t dev;                         // 设备号unsigned int count;                // 管理的次设备号范围
};

从其简化版的定义中可以看出,结构体struct cdev的一个实例就把设备需要的最重要的信息描述完了:
cdev结构体的成员kobj这里暂时不展开叙述。

cdev结构体的成员ops实际上就是上面说到的两个重要结构体中的另一个 struct file_operations,它里面实际上就是设备能进行的具体行为的函数的集合,比如下面是一个 struct file_operations简化版的定义:
PS:完整定义请参考我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/144905840

struct file_operations {struct module *owner;              // 指向模块的指针,防止模块卸载时被调用loff_t (*llseek)(struct file *, loff_t, int);ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);int (*open)(struct inode *, struct file *);int (*release)(struct inode *, struct file *);long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);...
};

从中我们可以看出它里面就集合了read、write、open、release这些真正涉及对设备底层操作的成员函数,这些函数其实才是某个设备驱动程序的核心。

cdev结构体的成员list_head list是用于链接到内核的 cdev 列表,这里不展开叙述。

cdev结构体的成员dev中存储了它的一个实例管理的设备号,包括主设备号和次设备号的起始号。

cdev结构体的成员count存储了次设备号的个数,通过dev中记录的次设备号的起始号和个数值,便知道了次设备号的范围。

从上面的描述可以看出,cdev结构体的一个实例确实是把设备需要的最重要的信息描述完了。而调用函数就是将其实例与结构体 struct file_operations的实例绑定起来,结构体 struct file_operations的实例中存储了设备能进行的具体行为的函数,比如了read、write、open这些函数。

第三步是调用函数cdev_add()将描述字符设备的核心结构体cdev的实例和设备号绑定起来

第一步中已经获取到了可用的主设备号和次设备号,这里就需要将描述字符设备的核心结构体cdev的实例与第一步中获取到的主设备号和次设备号信息填充上。
示例代码如下:

static dev_t dev;static struct cdev my_cdev; // 定义字符设备结构体static struct file_operations my_fops = {.owner = THIS_MODULE,.open = my_open,.read = my_read,.write = my_write,.release = my_close,
};// 向系统申请可用的主设备号和次设备号
ret = alloc_chrdev_region(&dev, 0, 3, "my_device");/* 核心结构体cdev和结构体file_operations的绑定 */
cdev_init(&my_cdev, &my_fops);/* 核心结构体cdev中写入设备号以及次设备号的个数 */
cdev_add(&my_cdev, dev, 3);....

在第二步中已经给出了核心结构体cdev的简化版:

struct cdev {struct kobject kobj;                // 内核对象,用于 sysfs 集成const struct file_operations *ops; // 设备支持的操作集struct list_head list;             // 用于链接到内核的 cdev 列表dev_t dev;                         // 设备号unsigned int count;                // 管理的次设备号范围
};

可见,这里面的第4个成员dev和第5个成员count便是设备号信息。所以这里需要调用函数cdev_add()向这个设备核心结构体写入设备号信息。

第四步调用函数class_create()创建设备类

设备类是内核设备模型中的一个抽象,用于将功能相似的设备分组,以便统一管理这些设备的属性和行为。通过设备类,我们可以轻松地在 /sys/class/ 下创建一个目录,并将设备文件与该类关联。
…这里未完待续…

第五步是调用函数device_create()创建设备文件

一个设备实例对就一个具体的设备文件,所以如果同一个驱动程序实例对应多个设备,便需要调用多次函数device_create()。

示例代码如下:


dev_t dev;
int ret = alloc_chrdev_region(&dev, 0, 3, "my_device"); // 分配3个次设备号
if (ret < 0) {printk(KERN_ERR "Failed to allocate device number\n");return ret;
}// 创建 cdev 并注册
cdev_init(&my_cdev, &my_fops);
ret = cdev_add(&my_cdev, dev, 3);
if (ret < 0) {printk(KERN_ERR "Failed to add cdev\n");unregister_chrdev_region(dev, 3);return ret;
}// 创建设备文件(多个次设备号,调用多次 device_create)
for (int i = 0; i < 3; i++) {// 为每个次设备号创建设备文件device_create(my_class, NULL, MKDEV(MAJOR(dev), MINOR(dev) + i), NULL, "my_device%d", i);
}

函数device_create()的介绍如下:

函数原型

struct device *device_create(struct class *cls, struct device *parent, dev_t devt,const struct attribute_group **groups, const char *devname);

参数解析:

  1. my_class (struct class *):

    • 这是一个指向 class 结构体的指针,表示设备所属的类。类是 Linux 设备模型中的一个概念,用来将一组具有相似功能的设备分组在一起。设备类管理着设备对象的生命周期、sysfs 属性、设备文件的创建等。
    • 在例子中,my_class 是事先通过 class_create() 创建的类,可能类似于:
      my_class = class_create(THIS_MODULE, "my_class");
      
    • class_create() 用来创建设备类,它是 Linux 驱动程序中组织设备的基础。
  2. NULL (struct device *):

    • 这个参数指定父设备。如果设备没有父设备,可以传递 NULL。大多数设备驱动程序的设备对象不需要父设备,所以这里通常会传递 NULL
    • 父设备用于设备层次结构的管理,例如树形结构的设备关联。如果不需要设备层次结构,可以将其设为 NULL
  3. dev (dev_t):

    • 这是设备的主设备号和次设备号组成的 dev_t 类型值,表示具体的设备。
    • dev_t 是一个 32 位的值,其中低 20 位是次设备号,高 12 位是主设备号。例如,如果你用 alloc_chrdev_region() 分配了一个设备号,dev 就是该设备号。
  4. **NULL (const struct attribute_group groups):

    • 这个参数是一个指向 attribute_group 结构体指针的指针,代表了设备的 sysfs 属性。如果不需要额外的 sysfs 属性,可以传递 NULL
    • 在许多情况下,你可能不需要为设备创建额外的 sysfs 属性,尤其是简单的字符设备。因此,可以把它设为 NULL
  5. "my_device" (const char *):

    • 这是设备文件的名称,即最终会出现在 /dev/ 目录下的设备文件名。在这个例子中,设备文件的名称是 "my_device%d",因此设备文件名为 /dev/my_device0/dev/my_device1/dev/my_device2

返回值:

  • device_create() 返回一个指向创建的 device 结构体的指针,该结构体表示内核中创建设备对象的元数据。
  • 如果函数调用失败,它返回 NULL

驱动程序编译好后通常是以模块的形式存在的,那么怎么加载这个模块?这个模块加载时从哪里执行?

请参看博文:
以一个实际例子来学习Linux驱动程序开发之“设备类”的相关知识 【搜索关键字“驱动模块加载代码”】

为什么驱动程序模块的C文件末尾要加上MODULE_LICENSE("GPL");

关于这个问题详细的介绍见我的另一篇博文
https://blog.csdn.net/wenhao_ir/article/details/144902881

驱动程序模块加载完成,完成设备实例化注册并创建了设备文件后,怎么调用设备?

这个最简单的例子例是之前的:
“IMX6ULL开发板基础实验:Framebuffer驱动程序的简单应用实例代码详细分析”
关键代码为:

 int fb_fd = open("/dev/fb0", O_RDWR);

这句代码就是把设备打开了,然后利用获得的文件描述符就可以操作设备了。

http://www.yidumall.com/news/40832.html

相关文章:

  • 一个网站好不好百度排行榜风云榜小说
  • 关于网站制作报价百度seo
  • 舟山市建设工程质量监督站网站成都达洱狐网络科技有限公司
  • 用服务器做网站需要购买域名吗正规的培训机构有哪些
  • 建设网站小常识网页seo搜索引擎优化
  • 微软网站做u盘启动教程青岛爱城市网app官方网站
  • 贵阳做网站kuhugzsteam交易链接在哪里
  • 合肥市网站优化广告联盟接广告
  • 建购物网站需要多少钱今日国际新闻热点
  • 深圳百度网站优化百度站内搜索提升关键词排名
  • 网站建设方案书阿里云模板东莞seo技术培训
  • 溧阳网站建设价格seo模拟点击工具
  • 网站模板自建站北京seoqq群
  • 连云港网络公司排名seo优化教程下载
  • 建设第二个北京在哪里哈尔滨企业网站seo
  • 做网站的设计文档怎么做引擎网站推广法
  • 中型网站开发语言农产品营销策划方案
  • 点网站建设seo优化服务公司
  • 做网站精英新东方雅思培训机构官网
  • 网站开发用什么服务器重庆seo网站推广费用
  • 如何建设软件下载网站企业网络营销策划方案
  • ppt素材网站建设流程图北京建站工作室
  • 网站建设需要写语句吗登封网络推广
  • 网站设计需要在哪方面提升推广平台有哪些
  • 广州电子商城网站建设爱链接购买链接
  • 嘉兴网站公司哪家好福清seo
  • 泰国如何做网站推广手机百度关键词优化
  • 做某个网站接口违法威海百度seo
  • 网站tag页面如何做域名注册哪个平台比较好
  • 有哪些学校的网站做的好处线下课程seo