platform 平台总线

一、 在/sys某个目录下创建一个文件:

struct bus_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct bus_type *bus, char *buf);
    ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
#define BUS_ATTR(_name, _mode, _show, _store)   \
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)

使用:
    BUS_ATTR(bus_version,0666,bus_version_show, bus_version_store);
    ==》展开:
    struct bus_attribute  bus_attr_bus_version  = { 
        .attr = {
            .name = "bus_version",
            .mode = 0666 
        },  
        .show   = bus_version_show,                 
        .store  = bus_version_store,                    
    }
    这种模型是所有驱动模型根本,比如platform总线, i2c总线,spi总线,sdio总线,内部都是这种模型

二、 几个重要的结果体

1 所有总线相关:
    device: 描述设备的静态的信息,比如中断号,gpio号码,地址,等等
    driver: 驱动设备的逻辑代码,比如ioremap, writel/readl, request_irq()等

    struct device{
        struct kobject kobj; // 继承父类
        const char  *init_name; //用于匹配的名字, 在运行的时候,会将该变量赋值给kobj.name
        struct bus_type *bus;    // 该device应该注册到哪个总线中
        void        *platform_data; //可以定义数据
    }

    struct device_driver {
        const char      *name;//用于匹配的名字
        struct bus_type     *bus;// 该driver应该注册到哪个总线中
        int (*probe) (struct device *dev);
        int (*remove) (struct device *dev);
    }

2 平台总线相关:
    struct platform_driver ---通用的多平台下的驱动代码
    struct platform_device ---不同平台下的地址,中断资源

    //资源--表示内存地址,也表示中断
    struct resource {
        resource_size_t start; // 地址起始
        resource_size_t end; //地址结束
        const char *name; //自定义
        unsigned long flags; //区分是内存地址还是中断IORESOURCE_MEM,IORESOURCE_IRQ
        struct resource *parent, *sibling, *child;
    };

    struct platform_device {
        const char  * name; //用于匹配
        int     id;
        struct device   dev; //继承父类
        u32     num_resources;
        struct resource * resource; //资源,存放设备的信息, 统一的格式
    }

    struct platform_driver {
        int (*probe)(struct platform_device *);
        int (*remove)(struct platform_device *);
        struct device_driver driver;//继承父类
        const struct platform_device_id *id_table; //可兼容多个platform device 的name
    }

3 匹配方法:
    1,优先将pdev的名字和pdrv中id_table的名字进行比较
    2,如果pdrv没有id_table,就直接比较pdev->name 和 pdrv->driver.name
获取资源:
    1 struct resource *platform_get_resource(struct platform_device *dev,
                        unsigned int type, unsigned int num)
     参数1:资源所在 pdev
     参数2:取哪种资源(irq or mem)
     参数3:同种资源的第几个

    2 pdrv_probe()做什么事情--1,为应用程序提供操作接口 2, 从pdev中获取资源,并通过资源对硬件进行初始化
        a,申请设备号
        b,创建文件
        c,硬件初始化--从pdev中获取资源,并通过资源对硬件进行初始化
        d,实现fops

    3 pdev中自定义数据
        设置自定义数据
        struct led_pdata {
            char *name;
            int shift_num;
        };
        struct led_pdata pdata = {
            .name = "gpc0_3/4",
            .shift_num = 3,
        };

        struct platform_device led_pdev = {
            .name = "s5pv210_led",
                .id = -1,
                .num_resources = ARRAY_SIZE(led_res),
                .resource = led_res,
                .dev = {                 // 父类
                    .platform_data = &pdata,
                },
        };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值