Linux中用platform_device结构体来描述

本文介绍了Linux系统中平台设备的概念及其结构体定义,并通过RTC平台设备为例详细讲解了平台设备如何被添加到系统中及其实现驱动的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二、相关概念

1、平台设备:
通常在Linux中,把SoC系统中集成的独立外设单元(如:I2C、IIS、RTC、看门狗等)都被当作平台设备来处理。在Linux中用platform_device结构体来描述一个平台设备,在2.6.30.4内核中定义在:include/linux/platform_device.h中,如下:

struct platform_device {
const char * name; //设备名称
int id;
struct device dev;
u32 num_resources; //设备使用各类资源的数量
struct resource * resource; //设备使用的资源

struct platform_device_id *id_entry;
};

现在你不必深入理解这个结构体,只要知道在Linux中是用这个结构体来定义一些平台设备的。比如在:arch/arm/plat-s3c24xx/devs.c中就定义了很多平台设备,下面我就只贴出RTC这一种的:

* RTC */
static struct resource s3c_rtc_resource[] = { //定义了RTC平台设备使用的资源,这些资源在驱动中都会用到
[0] = { //IO端口资源范围
.start = S3C24XX_PA_RTC,
.end = S3C24XX_PA_RTC + 0xff,
.flags = IORESOURCE_MEM,
},
[1] = { //RTC报警中断资源
.start = IRQ_RTC,
.end = IRQ_RTC,
.flags = IORESOURCE_IRQ,
},
[2] = { //TICK节拍时间中断资源
.start = IRQ_TICK,
.end = IRQ_TICK,
.flags = IORESOURCE_IRQ
}
};

struct platform_device s3c_device_rtc = { //定义了RTC平台设备
.name = "s3c2410-rtc", //设备名称
.id = -1,
.num_resources = ARRAY_SIZE(s3c_rtc_resource), //资源数量
.resource = s3c_rtc_resource, //引用上面定义的资源
};

EXPORT_SYMBOL(s3c_device_rtc);

好了,定义了平台设备,那系统是怎么来使用他的呢?我们打开:arch/arm/mach-s3c2440/mach-smdk2440.c这个ARM 2440平台的系统入口文件,可以看到在系统初始化函数smdk2440_machine_init中是使用platform_add_devices这个函数将一些平台设备添加到系统中的,如下:(至于系统是如何实现添加平台设备的,这里我们不必研究,这些Linux系统都已经做好了的,我们要研究的是后面平台设备的驱动是如何实现的)

static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
DE>

&s3c_device_rtc, //这里我们添加上RTC平台设备,默认是没添加的
}; //平台设备列表,也就是说我们要使用一个新的平台设备要先在上面定义,然后加到这个列表中,最后到驱动层去实现该设备的驱动

static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
//将上面列表中的平台设备添加到系统总线中
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}

2、平台设备驱动:
这里所讲的平台设备驱动是指具体的某种平台设备的驱动,比如上面讲的RTC平台设备,这里就是指RTC平台设备驱动。在Linux中,系统还为平台设备定义了平台驱动结构体platform_driver,就好比系统为字符设备定义了file_operations一样,但不要把平台设备跟字符设备、块设备、网络设备搞成了并列的概念,因平台设备也可以是字符设备等其他设备。注意:在被定义为平台设备的字符设备的驱动中,除了要实现字符设备驱动中file_operations的open、release、read、write等接口函数外,还要实现平台设备驱动中platform_driver的probe、remove、suspend、resume等接口函数。好了,在我们搞明白上面这些后,下面我们就来具体详细分析讲解RTC平台设备的驱动现实。

<think>我们正在讨论Linux内核中的设备模型。用户询问的是`device_type`的含义。根据引用[1]:内核中用结构体`device`来表示一个设备,而`platform_device`等结构体中包含了`device`。在`device`结构体中有一个成员`type`,其类型为`structdevice_type*`。引用[3]提到:`dev_name`与`device`结构中的`init_name`有关,如果设备没有提供名字,内核会用"bus->dev_name+deviceID"的形式生成一个名称。这里暗示了`device_type`可能与设备命名有关,但并未直接说明。然而,引用[1]中明确列出了`device`结构体的部分成员,其中包含:structdevice_type*type;因此,`device_type`是设备类型结构体,用于表示设备的类型。在内核中,`device_type`结构体通常包含该类型设备的一些共同属性和操作。另外,引用[4]提到了一个错误信息:'User provideddevice_typeof 'cuda',but CUDA isnot available'。这里是在使用yolov5训练时出现的,但注意这个device_type可能不是Linux内核中的概念,而是深度学习框架中指定设备(如GPU)的类型。不过用户的问题明确是关于内核中的`device_type`,所以我们应聚焦于内核。在Linux内核中,`device_type`是一个结构体,定义在`include/linux/device.h`中。它通常包含以下字段:- name:设备类型的名称-groups:该类型设备的默认属性组-release:释放设备的函数-等等设备类型用于对设备进行分类,比如所有的网络设备可能有相同的设备类型,所有的块设备有另一种类型。这样,内核可以基于设备类型来执行一些共同的操作。例如,在设备模型中,当我们注册一个设备时,如果该设备属于某个特定的设备类型,那么该设备类型中定义的属性组(groups)就会自动添加到设备中,这样在sysfs中就会显示相应的属性文件。总结:`device_type`在内核中用于表示一类设备的共同特性,它定义了这类设备的共享行为和属性。根据引用[2],设备驱动中有一个`probe`函数,当设备与驱动匹配时会被调用。而设备与驱动的匹配方式有多种,其中之一就是通过设备类型。不过通常匹配是通过总线类型(bus)来完成的,设备类型也可以作为匹配的辅助条件。因此,我们可以这样回答:`device_type`是Linux内核设备模型中的一个结构体,用于表示设备的类型。它定义了同一类型设备的共同属性和操作。例如,当多个设备属于同一类型时,它们可以共享相同的设备类型结构体,从而在sysfs中呈现相同的属性文件,或者共享相同的释放函数等。为了更清晰地说明,我们可以参考内核代码中的例子。例如,在`drivers/base/platform.c`中,平台设备(platform_device)通常没有指定设备类型,但其他设备类型(如PCI设备)可能会使用。注意:在设备驱动开发中,我们通常不会直接使用`device_type`,除非我们定义了一种新的设备类型。大多数情况下,设备类型由内核子系统定义,驱动程序只需要使用现有的设备类型即可。相关问题:1. `device_type`在内核设备匹配过程中起什么作用?2.如何在内核驱动中定义一个自定义的设备类型?3.`device_type`与`bus_type`有什么区别和联系?4.在sysfs中,设备类型如何影响设备属性的展示?</think>### device_type 的含义 在 Linux 内核设备模型中,**`device_type`** 是一个关键概念,其本质是 `struct device_type*` 类型的指针(引用自[^1])。它用于描述**同一类别设备的通用属性和行为**,类似于面向对象编程中的“基类”。以下是核心要点: #### 1. **核心作用** - **设备分类**:标识设备的功能类别(如网络设备、存储设备、传感器等)。 - **共享属性**:定义同类设备的公共属性和默认操作(如电源管理、释放资源等)。 - **命名规则**:当设备未显式设置名称时,内核可能结合 `bus->dev_name` 和 `device ID` 自动生成设备名(引用自[^3])。 #### 2. **数据结构关联** ```c struct device { struct device_type *type; // 指向设备类型的指针 // 其他成员:init_name, bus, driver, devt 等... }; ``` - 每个设备(`struct device`)通过 `type` 成员关联到其设备类型(引用自[^1])。 - 例如:所有 NVMe 固态硬盘可能共享同一个 `device_type`,定义其共同的电源管理接口。 #### 3. **实际应用场景** - **自动匹配驱动**:当设备注册时,内核可通过 `device_type` 快速筛选匹配的驱动(引用自[^2])。 - **统一行为管理**:如系统休眠时,调用 `device_type` 中定义的 `.suspend()` 函数统一挂起同类设备(引用自[^2])。 - **扩展设备功能**:通过 `device_type->groups` 为同类设备添加默认的 sysfs 属性文件。 #### 4. **常见误区** - **与 `bus_type` 的区别**:`bus_type` 描述设备连接的总线(如 PCI、USB),而 `device_type` 描述设备的功能类别(如 GPU、摄像头)。 - **与 CUDA 错误的关联**:引用[^4]中的 `device_type='cuda'` 是深度学习框架(如 PyTorch)的硬件加速类型,**与内核的 `device_type` 无关**。 > 简单总结:`device_type` 是内核中标识设备“功能类别”的元数据,用于实现同类设备的统一管理和行为抽象。 --- ### 相关问题 1. **`device_type` 如何影响设备与驱动的匹配过程?** (提示:参考 `probe` 机制[^2]) 2. **在内核中自定义一个 `device_type` 需要哪些步骤?** (提示:结构体定义、注册接口、属性组关联) 3. **`device_type` 与 `class`(设备类)有何区别?** (提示:`class` 更侧重用户层接口,如 sysfs 层级) 4. **为什么某些设备(如 platform_device)不显式设置 `device_type`?** (提示:总线类型 `bus_type` 的默认行为) [^1]: 设备核心结构 `device` 包含 `device_type` 成员 [^2]: 驱动通过 `probe` 等接口与设备交互 [^3]: 设备命名规则与 `init_name` 的关联 [^4]: CUDA 错误与内核 `device_type` 无关
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值