Linux驱动开发 | platform总线

使用的内核版本为3.4.39,开发工具为Ubuntu的vim编辑器。

一、platform简介

        是操作系统的一个通用型总线,操作系统中需要把设备和驱动挂接到总线当中供顶层应用使用,platform是所有类型的设备和驱动都可以挂接的一条通用型总线。操作系统中也有专用型总线,例如USB、I2C,一般如果有对应的专用型总线会优先考虑挂接到专用型总线上,通用型总线通常是退而求其次的选择。

二、供用户使用的派生类及方法

#include  <linux/platform_device.h>

// 描述挂接到platform总线设备的结构体

struct platform_device {
    const char    * name;  // 总线名称
    int        id;   // 设备编号
    struct device    dev;  // 基类
    u32        num_resources;  // 资料数目
    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;
};

// 设备注册到总线中

extern int platform_device_register(struct platform_device *);

// 设备在总线中注销
extern void platform_device_unregister(struct platform_device *);

// 描述挂接到platform总线驱动的结构体

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;   // 配对的设备名
};

// 驱动注册到总线中
extern int platform_driver_register(struct platform_driver *);

// 驱动在总线中注销

extern void platform_driver_unregister(struct platform_driver *);

// 获取设备通过resource传递的值

extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);

// 获取指定设备的中断号
extern int platform_get_irq(struct platform_device *, unsigned int);

// 将一个或多个平台设备添加到系统中,以便其驱动程序可以对它们进行初始化和管理

extern int platform_add_devices(struct platform_device **, int);

三、代码实现流程

        操作系统已经存在一条platform总线,所以只需要使用platform的派生类和方法,注册设备和驱动即可,两个可以通过名称相同进行匹配,匹配成功后会执行驱动代码,也就是prob指向的部分代码。挂接到platform总线的设备和驱动分别可以在/sys/bus/platform/devices和/sys/bus/platform/drivers查看。

四、示例代码

Makefile

KERNEL_DIR = /opt/wkspace/kernel-build/kernel-3.4.39/

obj-m += mydev.o mydrv.o

all:
        make modules M=`pwd` -C $(KERNEL_DIR) CROSS_COMPILE=/usr/local/arm/arm-eabi-4.8/bin/arm-eabi-
clean:
        make modules clean M=`pwd` -C  $(KERNEL_DIR) CROSS_COMPILE=/usr/local/arm/arm-eabi-4.8/bin/arm-eabi-
        rm -rf app 

mydev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/platform_device.h>

void platform_release(struct device *dev){
        printk(KERN_INFO "platform release!\n");

        return ;
}

struct platform_device mydev = {
        .name = "platform_dev",
        .id = 188,
        .dev = {
                .release = platform_release,
        }
};

static int __init platform_dev_init(void){
        printk(KERN_INFO "platform dev init!\n");

        platform_device_register(&mydev);
        return 0;
}

static void __exit platform_dev_exit(void){
        printk(KERN_INFO "platform dev exit!\n");


        platform_device_unregister(&mydev);
        return ;
}

module_init(platform_dev_init);
module_exit(platform_dev_exit);

MODULE_LICENSE("GPL");

mydrv.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/platform_device.h>

int platform_probe(struct platform_device *dev){
        printk(KERN_INFO "platform probe!\n");

        return 0;
}

int platform_remove(struct platform_device *dev){
        printk(KERN_INFO "platform remove!\n");

        return 0;
}

struct platform_driver mydrv = {
        .driver = {
                .name = "platform_dev",
        },
        .probe = platform_probe,
        .remove = platform_remove,
};

static int __init platform_drv_init(void){
        printk(KERN_INFO "platform drv init!\n");

        platform_driver_register(&mydrv);
        return 0;
}

static void __exit platform_drv_exit(void){
        printk(KERN_INFO "platform drv exit!\n");

        platform_driver_unregister(&mydrv);
        return ;
}

module_init(platform_drv_init);
module_exit(platform_drv_exit);

MODULE_LICENSE("GPL");

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值