一. 简介
通过前面文章的学习,我们知道,设备驱动的分离,并且引出了总线 (bus) 、驱动 (driver) 和设备 (device) 模型。
而对于soc中(芯片)没有总线的概念,Linux 提出了 platform 总线,platform_driver 和 platform_device 。
前面两篇文章简单学习了Linux内核的 platform总线与platform驱动的代码实现。
二. 设备(struct device 设备)的注册
向内核注册 device (struct device 设备)过程如下:
驱动与设备匹配以后,驱动的probe函数就会执行,probe函数就是驱动编写人员去编写的!!!!
三 . Linux内核中platform设备简介
1. platform设备结构体
platform
驱动已经准备好了,我们还需要
platform
设备,否则的话单单一个驱动也做不了什么。
platform_device
这个结构体表示
platform
设备。platform_device结构体的成员中包含了 struct device结构体,也就是说 platform_device结构体对 struct device结构体进行了一层封装。
这里我们要注意,如果内核支持设备树的话,就不要再使用 platform_device 来描述设备了,因为改用设备树去描述了。
当然了,你如果一定要用
platform_device
来描述设备信息的话也是可以的。
platform_device
结构体定义在文件
include/linux/platform_device.h
中,结构体内容如下:
struct platform_device {
const char *name;
int id;
bool id_auto;
struct device dev;
u32 num_resources;
struct resource *resource;
const struct platform_device_id *id_entry;
char *driver_override; /* Driver name to force a match */
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
第 23 行,name 表示设备名字,要和所使用的 platform 驱动的 name 字段相同,否则的话,设
备就无法匹配到对应的驱动。比如,对应的
platform
驱动的
name
字段为“
xxx-gpio
”,那么此
name
字段也要设置为“
xxx-gpio
”。
第
27
行,
num_resources
表示资源数量,一般为第
28
行
resource
资源的大小。
第
28
行,
resource
表示资源,也就是设备信息,比如,外设寄存器等。
Linux
内核使用
resource
结构体表示资源,
resource
结构体内容如下:
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
start
和
end
分别表示资源的起始和终止信息,对于内存类的资源,就表示内存起始和终止地址,
name
表示资源名字,
flags
表示资源类型,可选的资源类型都定义在了文件
include/linux/ioport.h
里面,如下所示:
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
#define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
#define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */
#define IORESOURCE_MEM 0x00000200
#define IORESOURCE_REG 0x00000300 /* Register offsets */
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
#define IORESOURCE_BUS 0x00001000
................
#define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */
2. 注册设备与卸载platform设备(在以前不支持设备树的旧 Linux版本中 )
在以前不支持设备树的Linux版本中,用户需要编写 platform_device
变量来描述设备信息,然后,使用
platform_device_register 函数将设备信息注册到 Linux
内核中,此函数原型如下所示:
int platform_device_register(struct platform_device *pdev)
函数参数和返回值含义如下:
pdev
:要注册的
platform
设备。
返回值:
负数,失败;
0
,成功。
如果不再使用
platform
的话,可以通过
platform_device_unregister
函数注销掉相应的
platform
设备,
platform_device_unregister
函数原型如下:
void platform_device_unregister(struct platform_device *pdev)
函数参数和返回值含义如下:
pdev
:要注销的
platform
设备。
返回值:
无。
总结:
1. 无设备树的时候,此时需要驱动开发人员编写设备注册文件,使用platform_device_register函数注册设备。
2. 有设备树,修改设备树的设备节点即可。
当设备与platform的驱动匹配以后,就会执行platform_driver->probe函数。
Linux内核中platform驱动代码简单学习到这里。接下来学习如何编写 platform设备信息框架。