1、 resource_size_t end; /* 资源在CPU上的物理结束地址 */ const char *name; /* 资源名称 */ unsigned long flags; /* 资源的标志 */ struct resource *parent, *sibling, *child; /* 资源的父亲、兄弟和子资源 */; flags通常被用来表示资源的类型,可用的资源类型有IO、MEM、IRQ等,在中定义,各资源类型和定义如下:#define IORESOURCE_TYPE_BITS 0x00001f00 /*资源类型 */#define IORESOURCE_IO 0x00000
2、100#define IORESOURCE_MEM 0x00000200#define IORESOURCE_IRQ 0x00000400#define IORESOURCE_DMA 0x00000800#define IORESOURCE_BUS 0x000010002 资源定义 一个设备的资源定义可以同时包含所占用的多种资源。例如,对于一个既占用内存资源,又占用IRQ中断资源的设备,其资源定义可以如程序清单2.36所示。程序清单2.36资源定义实例#define EMC_CS2_BASE 0x11000000 /* 总线片选地址 */static struct resource ecm_a
3、x88796b_resource = 0 = /* 内存资源 */ .start = EMC_CS2_BASE, /* 起始地址 */ .end = EMC_CS2_BASE + 0xFFF, /* 结束地址 */ .flags = IORESOURCE_MEM, /* 资源类型:IORESOURCE_MEM */ , 1 = /* IRQ资源 */ .start = IRQ_GPIO_04, .end = IRQ_GPIO_04, .flags = IORESOURCE_IRQ, /* 资源类型:IORESOURCE_IRQ */ 3 资源获取 定义了一个设备的资源后,需通过特定函数获取才能
4、使用,这些函数在文件中定义,一共有3个函数,分别是:platform_get_resource()、platform_get_resource_byname()、platform_get_irq()和platform_get_irq_byname()。 platform_get_resource()函数用于获取指定类型的资源,函数原型如下:extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); dev指向包含资源定义的platform_device结
5、构;type表示将要获取的资源类型;num表示获取资源的数量。返回值为0表示获取失败,成功返回申请的资源地址。 platform_get_resource_byname()则是根据平台设备的设备名称获取指定类型的资源,函数原型如下:extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); 另外,内核还单独提供了获取IRQ的接口函数platform_get_irq(),实际上就是platform_get_resource()获取IORESO
6、URCE_IRQ的封装,方便用户使用。原型如下:int platform_get_irq(struct platform_device *dev, unsigned int num); 获取设备的私有数据,可通过宏platform_get_drvdata实现:#define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)-dev)实际上是获取_dev-dev-p-driver_data,可参考程序清单2.29 device结构的定义。 platform_get_irq_byname()则可根据平台设备名称获取设备的IRQ资源,函数原型如下:
7、extern int platform_get_irq_byname(struct platform_device *, const char *); 在驱动编写中如何实际使用这些函数,下面给出一个代码片段,如程序清单2.37所示。程序清单2.37平台资源获取和使用范例 if (!mem) res = platform_get_resource (pdev, IORESOURCE_MEM, 0); /* 获取内存资源 */res) printk(%s: get no resource !n, DRV_NAME); return -ENODEV; mem = res-start; if(!irq
8、) irq = platform_get_irq(pdev, 0); /* 获取IRQ资源 */request_mem_region (mem, AX88796B_IO_EXTENT, ax88796b) /* 申请IO内存 */ PRINTK (ERROR_MSG, PFX request_mem_region fail !); return -EBUSY; addr = ioremap_nocache(mem, AX88796B_IO_EXTENT); /* 内存映射ioremap */addr) ret = -EBUSY; goto release_region; 该范例演示了内存资源和
9、IRQ资源的获取和使用。特别说明一下内存资源,在定义内存资源的时候,通常使用内存的物理地址,而在驱动中须转换为虚拟地址使用,所以需要进行ioremap操作,而在ioremap之前又需要先申请IO内存,所以在代码中看到的是先使用request_mem_region()函数申请IO内存,然后再通过ioremap_nocache()函数完成内存映射。1.1.2 平台设备 并不是任何设备都可以抽象成为platform_device。platform_device是在系统中以独立实体出现的设备,包括传统的基于端口的设备、主机到外设的总线以及大部分片内集成的控制器等。这些设备的一个共同点是CPU都可以通过
10、总线直接对它们进行访问。在极少数情况下,一个platform_device可能会经过一小段其它总线,但是它的寄存器依然可以被CPU直接访问。1 platform_device 用于描述平台设备的数据结构是platform_device,在文件中定义,如程序清单2.38所示。程序清单2.38 platform_device数据结构struct platform_device const char * name; /* 设备名称 */ int id; /* 设备ID */ struct device dev; /* 设备的device数据结构 */ u32 num_resources; /* 资源
11、的个数 */ struct resource * resource; /* 设备的资源 */ const struct platform_device_id *id_entry; /* 设备ID入口 */ /*体系结构相关的附加项*/ struct pdev_archdata archdata; /* 体系结构相关的数据 */ name是设备的名称,用于与platform_driver进行匹配绑定,resourse用于描述设备的资源如地址、IRQ等。2 分配platform_device结构 注册一个platform_device之前,必须先定义或者通过platform_device_allo
12、c()函数为设备分配一个platform_device结构,platform_device_alloc()函数原型如下:struct platform_device *platform_device_alloc(const char *name, int id);3 添加资源 通过platform_device_alloc()申请得到的platform_device结构,必须添加相关资源和私有数据才能进行注册。添加资源的函数是platform_device_add_resources:int platform_device_add_resources(struct platform_devic
13、e *pdev, const struct resource *res, unsigned int num); 添加私有数据的函数是platform_device_add_data:int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size);4 注册和注销platform_device 申请到platform_device结构后,可以通过platform_device_register()往系统注册,platform_device_register()函数原型如下:int platform_device_register(struct platform_device *pdev); platform_device_register()只能往系统注册一个platform_device,如果有多个platform_device,可以用platform_add_devices()一次性完成注册,platform_add_devices()函数原型如下:int platform_add_devices(struct platform_device *de
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1