本节用于介绍平台总线模型——注册platform设备
1、什么是平台总线模型?
平台总线模型也叫platform总线模型。是Linux内核虚拟出来的一条总线,不是真实的导线。
平台总线模型就是把原来的驱动C文件给分成了俩个C文件,一个是device.c,一个是driver.c
把稳定不变的放在driver.c里面,需要变得就放在了device.c里面。
2、为什么会有平台总线模型?
- 可以提高代码的重用性
- 减少重复性代码。
| 设备 |
总线 |
驱动 |
| device.c |
|
driver.c |
3、平台总线模型的优点。
4、怎么编写以平台总线模型设计的驱动?
一个是device.c,一个是driver.c,然后分别注册 device.c和 driver.c
平台总线是以名字来匹配的,实际上就是字符串比较。
1、平台总线注册一个platform_device
设备文件device.c里面写的是硬件资源,这里的硬件资源是指寄存器的地址,中断号,时钟等硬件资源。
在Linux内核里面,我们是用一个结构体来描述硬件资源的。
文件位置路径:include/linux/platform_device.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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;
struct mfd_cell *mfd_cell;
struct pdev_archdata archdata; };
|
2、填写platform_device里面的resource硬件资源结构体数组
文件位置路径:include/linux/ioport.h
1 2 3 4 5 6 7 8
| struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; unsigned long desc; struct resource *parent, *sibling, *child; };
|
这里面的资源的类型有哪些呢?下面是几个常用的类型
1 2 3 4 5
| #define IORESOURCE_IO #define IORESOURCE_MEM #define IORESOURCE_IRQ #define IORESOURCE_DMA #define IORESOURCE_BUS
|
注意:platform_device结构体内的内嵌的device结构体中如果void (*release)(struct device *dev);函数没有实现的话,可能会有内核报警。
1
| [ 2901.445771] Device 'beep_test' does not have a release() function, it is broken and must be fixed.
|
3、填写platform_device里面的device结构体
文件位置路径:include/linux/device.h
1 2 3 4 5
| struct device { ... void (*release)(struct device *dev); ... }
|
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| void beep_release(struct device *dev) { printk("beep_release\n"); }
struct resource beep_res[] = { [0] = { .start = 0x02310008, .end = 0x0231000b, .name = "GPDAT_1", .flags = IORESOURCE_MEM } };
struct platform_device beep_device = { .name = "beep_test", .id = -1, .dev = { .release = beep_release }, .num_resources = ARRAY_SIZE(beep_res), .resource = beep_res };
|
4、注册和注销平台设备函数
当使用上节的函数创建完成一个platform_device后,使用platform_device_register函数进行平台设备的注册
文件位置路径:include/linux/platform_device.h
实际函数位置路径:drivers/base/platform.c
1 2 3 4 5 6 7 8 9 10
| extern int platform_device_register(struct platform_device *); int platform_device_register(struct platform_device *pdev) { device_initialize(&pdev->dev); arch_setup_pdev_archdata(pdev); return platform_device_add(pdev); } EXPORT_SYMBOL_GPL(platform_device_register);
|
1 2 3 4 5 6 7 8 9
| extern void platform_device_unregister(struct platform_device *); void platform_device_unregister(struct platform_device *pdev) { platform_device_del(pdev); platform_device_put(pdev); } EXPORT_SYMBOL_GPL(platform_device_unregister);
|