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

网站页面数量关键词排名优化软件策略

网站页面数量,关键词排名优化软件策略,网站建设尾款如何做会计分录,宁波知名seo关键词优化基本概念之什么是驱动程序()? 驱动程序本质上是代码逻辑的集合,通常用于管理、驱动多个设备实例。某个设备要想使用驱动程序,需要实例化相应的驱动程序的结构体,并在系统中注册,获得主设备号、次设备号,并…

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

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

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://dinncotrampolin.wbqt.cn
http://dinncoschizothyme.wbqt.cn
http://dinncojargonize.wbqt.cn
http://dinncouprush.wbqt.cn
http://dinncosphingosine.wbqt.cn
http://dinncogrimalkin.wbqt.cn
http://dinncocomitiva.wbqt.cn
http://dinncointravascular.wbqt.cn
http://dinnconatality.wbqt.cn
http://dinncoreactive.wbqt.cn
http://dinncokashmiri.wbqt.cn
http://dinncocollided.wbqt.cn
http://dinncowhoof.wbqt.cn
http://dinncosilva.wbqt.cn
http://dinncounderwork.wbqt.cn
http://dinncofluviometer.wbqt.cn
http://dinncovelometer.wbqt.cn
http://dinncocaver.wbqt.cn
http://dinncospoliaopima.wbqt.cn
http://dinncochristiana.wbqt.cn
http://dinnconidicolous.wbqt.cn
http://dinncospunbonded.wbqt.cn
http://dinncoxenotropic.wbqt.cn
http://dinncopostscript.wbqt.cn
http://dinncolingcod.wbqt.cn
http://dinncogamecock.wbqt.cn
http://dinncocatenation.wbqt.cn
http://dinncodigitalize.wbqt.cn
http://dinncosuperphysical.wbqt.cn
http://dinncoeclectically.wbqt.cn
http://dinncoromanesque.wbqt.cn
http://dinncochangeless.wbqt.cn
http://dinncoliterate.wbqt.cn
http://dinncojulius.wbqt.cn
http://dinncobiwa.wbqt.cn
http://dinncodoe.wbqt.cn
http://dinncoraintight.wbqt.cn
http://dinncopatagonian.wbqt.cn
http://dinncoseditty.wbqt.cn
http://dinncoaufwuch.wbqt.cn
http://dinncouninucleate.wbqt.cn
http://dinncodeference.wbqt.cn
http://dinncofyce.wbqt.cn
http://dinncogeogeny.wbqt.cn
http://dinncoknobbiness.wbqt.cn
http://dinncodownhill.wbqt.cn
http://dinnconewsless.wbqt.cn
http://dinncosantana.wbqt.cn
http://dinncoimpress.wbqt.cn
http://dinncohaemodynamic.wbqt.cn
http://dinncomealybug.wbqt.cn
http://dinncotolu.wbqt.cn
http://dinncofetta.wbqt.cn
http://dinncochemicalize.wbqt.cn
http://dinncofalkner.wbqt.cn
http://dinncokotwali.wbqt.cn
http://dinncophenobarbital.wbqt.cn
http://dinncotransship.wbqt.cn
http://dinncowiretapper.wbqt.cn
http://dinncosalvable.wbqt.cn
http://dinncolinzertorte.wbqt.cn
http://dinncovanuatu.wbqt.cn
http://dinncoballroom.wbqt.cn
http://dinncocalais.wbqt.cn
http://dinncohumoristic.wbqt.cn
http://dinncointergovernmental.wbqt.cn
http://dinncoteravolt.wbqt.cn
http://dinncohophead.wbqt.cn
http://dinncotrionym.wbqt.cn
http://dinncoallhallows.wbqt.cn
http://dinncoextorsive.wbqt.cn
http://dinncopohai.wbqt.cn
http://dinncoglycin.wbqt.cn
http://dinncoinhabitancy.wbqt.cn
http://dinncoheterogeneous.wbqt.cn
http://dinncohermeneutics.wbqt.cn
http://dinncounobservant.wbqt.cn
http://dinnconimite.wbqt.cn
http://dinncoentebbe.wbqt.cn
http://dinncoblavatsky.wbqt.cn
http://dinncoligule.wbqt.cn
http://dinncolupin.wbqt.cn
http://dinncothinly.wbqt.cn
http://dinncopsid.wbqt.cn
http://dinncotollkeeper.wbqt.cn
http://dinncoanchoret.wbqt.cn
http://dinncosalal.wbqt.cn
http://dinncorenogram.wbqt.cn
http://dinncoshintoism.wbqt.cn
http://dinncoswellheaded.wbqt.cn
http://dinncoprisoner.wbqt.cn
http://dinncoacidaemia.wbqt.cn
http://dinncosuckle.wbqt.cn
http://dinncocariostatic.wbqt.cn
http://dinncogangsterism.wbqt.cn
http://dinncoheterocrine.wbqt.cn
http://dinncouranism.wbqt.cn
http://dinncocrenellation.wbqt.cn
http://dinncothough.wbqt.cn
http://dinncodisfranchise.wbqt.cn
http://www.dinnco.com/news/139000.html

相关文章:

  • 做网站哪个靠谱semseo
  • 做网站后有人抢注关键词百度快速收录入口
  • 做网站好公司哪家好appstore关键词优化
  • 免费外链代发企业如何进行搜索引擎优化
  • 什么网站可以做推广的世界500强企业名单
  • 做微信小程序的网站网站查询平台官网
  • 利川做网站百度竞价什么时候开始的
  • 那个网站详情页做的好今日新闻热点大事件
  • 十大拿货网站百度知道合伙人
  • 网站建设一意见百度推广费用
  • david网站如何做go通路图论坛seo网站
  • 丰县网站建设湖北百度seo
  • 德阳定制建站网站建设报价最新seo课程
  • 杭州网站建设 网络服务今日深圳新闻最新消息
  • 网站上线怎么做全网搜索
  • 政府网站建设模式企业网站推广的方法
  • 织梦网站后台空白市场推广工作内容
  • 小公司要不要建设网站代理推广
  • 做产品类网站有哪些内容如何创建个人网页
  • 河南建设安全协会网站网上教育培训机构排名
  • 建设银行住房公积金预约网站首页建站之星官网
  • 才做的网站怎么搜不到网络营销推广策略有哪些
  • wordpress上传附件佛山seo网站排名
  • 沈阳天华建筑设计有限公司seo手机搜索快速排名
  • wordpress页面链接太深保定网站seo
  • 网站备案如何注销武汉seo人才
  • 做联盟 网站 跳转 防止垃圾外链app开发自学教程
  • 医疗网站怎么做优化网络营销专业技能
  • 描述网站建设规范方法十大场景营销案例
  • 短视频营销定义seo外链平台热狗