1.0设备和驱动没有分离,设备的信息是硬编码在驱动代码中,这个驱动代码程序造成了极大地限制,如果硬件有所改动,那么必然要修改驱动代码,这样驱动的通用性就比较差
2.0没有类似于windows系统中的设备管理器
3.0不能自动创建设备节点
4.0驱动不能自动加载
5.0U盘和SD卡不能自动挂载`
要满足linux设备模型,就必须有总线,设备和驱动。但是有的设备并没有对应的物理总线,比如LED,RTC和蜂鸣1器
内核开发了一种虚拟的总线-----platform总线,用来连接这些没有物理总线的设备或者一些不支持热插拔的设备,DM9000网卡设备就是挂接在这条总线上
// pltdev.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
static void pdev_release(struct device *dev)
{
}
//资源信息
// 设备的名字, 在平台总线的match函数中可用于平台驱动的匹配
// 设备的ID号 用于区别同类型的不同平台设备
// num_resource 平台使用的的资源个数
// resource 平台设备的资源列表,指向资源数组中的元素
//平台设备结构体
/*
struct platform_device {
const char *name;
int id;
bool id_auto;
struct device dev;
u32 num_resource;
struct resource *resource;
const struct plat_from_device_id *id_entry;
struct mfd_cell *mfd_cell;
struct pdev_archdata archdata;
}
*/
//设备使用资源信息的描述
/*
struct resource {
resource_size_t start;
rssource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent,*sibling,*child
}
*/
//ex1 mach-qt2410.c
/*
static struct resource qt2410_cs89x0_resource[] = {
[0] = DEFINE_RES_MEM(0X19000000,17)
[1] = DEFINE_RES_IRQ(IRQ_EINT9),
};
static struct plat_form_device qt2410_cs89x0 ={
.name = "cirrus-cs89x0",
.num_resource = ARRY_SIZE(qt2410_csx0_resources),
.resource = qt2410_cs89x0_resources,
};
*/
/*
第一步
向平台总线注册和注销的平台设备的主要函数
int platform_add_devices(struct platform_device **devs,int num); //一次注册多个平台设备
int platfrom_register(struct platform_device *pdev);
int platfrom_unregister(struct platform_device *pdev);
第二步
当平台总线发现有和平台设备匹配的驱动时,就会调用平台驱动的一个函数,并传递匹配的平台的设备结构地址,平台驱动就可以获取设备的资源信息
struct resource *platform_get_resource(struct platform_device *dev,unsigned int type,unsigned int num);
resource_size_t resource_size(const struct resource *res);
*/
struct platform_device pdev0 = {
.name = "pdev";
.id = 0;
.num_resource = 0,
.resource = NULL,
.dev = {
.release = pdev_release,
}
};
static int __init pltdev_init(void)
{
platform_device_register(&pdev0);
return 0;
}
static void __init pltdev_exit(void)
{
platform_device_unregister(&pdev0);
}
module_exit(pltdev_init);
module_exit(pltdev_exit);
MODULE_LICENSE("GPL")
//pltdrv.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
//平台驱动
/*
struct plat_form_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_devie *);
void (*shutdown)(struct platform_device 8);
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;
bool prevent_deferred_prboe;
};
*/
static int pdrv_suspend(struct device *dev)
{
printk("pdev: suspend");
return 0;
}
static int pdrv_resume(struct device *dev)
{
printk("pdev: resume");
return 0;
}
//硬件操作函数
static const struct dev_pm_ops pdrv_pm_ops ={
.suspend = pdrv_suspend,
.resume = pdrv_resume,
};
static int pdrv_probe(struct platform_device *pdev)
{
return 0;
}
static int pdrv_remove(struct platform_device *pdev)
{
return 0;
}
struct platform_drvier pdrv ={
.driver ={
.name = "pdev",
.owner = THIS_MODULE,
.pm = &pdrv_pm_ops, //硬件操作函数注册
},
.probe = pdrv_probe,
.remove = pdrv_remove,
};
module_platform_driver(pdrv);
MODULE_LICENSE("GPL");