介绍相关概念和实现API
1:平台设备总线相关的概念
平台设备总线说白了就是将一个驱动分为了设备端和驱动端:
设备端:主要是用来向内核注册设备的资源;
驱动端:是利用设备端注册的资源来实现驱动程序;
设备端:仅仅是向内核注册驱动的资源
比如led灯,他的资源:
要使用哪一个寄存器;
灯对应的引脚;
灯的有效电平;
驱动端:取出设备端向内核注册的资源,根据拿到的资源来实现led灯的驱动,设备端跟驱动端的匹配是通过总线的方式来匹配,这个总线并不是真实存在的一条总线,而是linux虚拟出来的总线;
2:平台设备总线的意义
提高驱动端代码的复用率,一般仅仅需要写设备端的代码,代码量就少了,假如有了设备树 我们就可以实现不写代码就能完成驱动程序;
3:平台设备总线的分层
驱动代码分为两层:驱动层和设备层;
4:平台设备总线设备层的实现
设备层主要是用来跟总线提供相应的资源
led灯来说,提供的资源包括:
引脚号;
有效电平;
寄存器地址;
设备层只需要考虑如何向内核提供这些资源,这里只涉及一个函数:
函数的功能:向内核提供设备的资源的信息
函数的头文件:<linux/platform_device.h>
函数的原型:int platform_device_register(struct platform_device *);
函数的参数:struct platform_device *:资源的结构体
函数的返回值:
成功返回 0
失败返回 -1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
struct platform_device {
const char * name; //设备名用于匹配驱动端的名字
int id; //一般写 -1
struct device dev; //设备名用于匹配驱动端的名字
u32 num_resources; //资源的数目 ARRAY_SIZE()
struct resource * resource;//具体资源内容结构体
const struct platform_device_id *id_entry; //另外一种匹配驱动层的方法
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
具体资源内容结构体:
struct resource {
resource_size_t start; //资源的起始地址
resource_size_t end; //资源的结束的地址
const char *name; //资源的名字
unsigned long flags; //资源的类型
IORESOURCE_MEM:内存资源
struct resource *parent, *sibling, *child;
};
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5:平台设备总线的驱动层
需要跟设备层一样,驱动层也需要向内核注册驱动层的东西,只有在内核里有驱动层的信息并且也有设备层的信息,这样的话 驱动层才能跟设备层进行匹配;
函数的功能:向内核注册驱动层相关的信息
函数的头文件:<linux/platform_device.h>
函数的原型:int platform_driver_register(struct platform_driver *);
函数的参数:struct platform_driver *:驱动层核心结构体的指针
函数返回值:
成功返回 0
失败返回 非零
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
};
probe函数:如果驱动层匹配设备层成功则会调用此函数;
remove函数:当驱动端或者是设备端有任意一端卸载了,他就会调用这个函数
struct device_driver driver:这个结构体里有一个name,这个name是必填的;
这个name就是用来匹配设备层的关键字
id_table:另外一种的匹配的方式 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:获取设备层的资源
函数的头文件:<linux/platform_device.h>
函数的原型:
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
函数的参数:
struct platform_device *dev:设备资源的结构体
unsigned int type, :资源的类型
unsigned int num :资源的下标
函数的返回值:
成功返回:资源结构体的指针
失败返回:NULL
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:取消平台设备总线驱动层的注册
函数的头文件:<linux/platform_device.h>
函数的原型:void platform_driver_unregister(struct platform_driver *dev)
函数的参数:struct platform_driver *dev:驱动层结构体的指针
函数的返回值:无