字符设备驱动第十八课---platform2

概述

从platform中提取设备信息

函数接口

include/linux/platform_device.h

1.提取IO资源

/*
* 功能:提取资源
* 输入参数:struct platform_device:platform设备句柄
*          unsigned int:资源类型,是中断还是iomem (IORESOURCE_MEM 或IORESOURCE_IRQ)
*          unsigned int:起始索引   
* 返回值:成功:资源结构体首地址   失败:NULL
*/
 struct resource *platform_get_resource(struct platform_device *,
                          unsigned int, unsigned int);

2.提取中断资源

/*
* 功能:提取中断资源
* 输入参数:struct platform_device:platform设备句柄
*          unsigned int:中断资源序号
* 返回值:成功:中断号 失败;负数          
*/
int platform_get_irq(struct platform_device *, unsigned int);

3.提取私有数据:

/*
* 功能:提取私有数据
* 输入参数:struct platform_device:platform设备句柄
* 返回值:成功:私有数据首地址 失败;NULL          
*/
void *platform_get_drvdata(const struct platform_device *pdev)

范例

驱动端

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

#include <asm/current.h>
#include <linux/sched.h>

#include <linux/ioport.h>
#include <linux/platform_device.h>

#include "../private.h"

static int demo_probe(struct platform_device *pdev)
{
    int irq;
    struct resource *addr;
    struct privatedata *priv;

    printk(KERN_INFO "%s : %s : %d - entry.\n", __FILE__, __func__, __LINE__);

    priv = dev_get_platdata(&pdev->dev);//从设备树中提取私有数据
    if(priv){
        printk(KERN_INFO "%x : %s \n", priv->val, priv->str);       
    }
    /*从设备树中提取IO资源*/
    addr = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if(addr){
        printk(KERN_INFO "0: %x : %d \n", addr->start, resource_size(addr));        
    }
    addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
    if(addr){
        printk(KERN_INFO "1: %x : %d \n", addr->start, resource_size(addr));        
    }
    addr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
    if(!addr){
        printk(KERN_INFO "No 2 resource\n");        
    }
    /*从设备树中提取中断资源*/
    irq = platform_get_irq(pdev, 0);
    if(0 > irq){
        return irq;
    }else{
        printk(KERN_INFO "irq 0: %d \n", irq);      
    }
    irq = platform_get_irq(pdev, 1);
    if(0 > irq){
        return irq;
    }else{
        printk(KERN_INFO "irq 0: %d \n", irq);      
    }

    irq = platform_get_irq(pdev, 2);
    if(0 > irq){
            printk(KERN_INFO "No 2 irq\n");     
    }

    return 0;
}

static int demo_remove(struct platform_device *pdev)
{
    printk(KERN_INFO "%s : %s : %d - leave.\n", __FILE__, __func__, __LINE__);
    return 0;
}

static struct platform_device_id tbl[] = {
    {"demo0"},
    {"demo1"},
    {},
};
MODULE_DEVICE_TABLE(platform, tbl);

//1. alloc obj
static struct platform_driver drv = {
    .probe  = demo_probe,
    .remove = demo_remove,

    .driver = {
        .name = "demo",
    },

    .id_table = tbl,
};

#if 0
static int __init drv_init(void)
{
    //get command and pid
    printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - entry.\n",
        current->comm, current->pid, __FILE__, __func__, __LINE__);
    return platform_driver_register(&drv);
}
static void __exit drv_exit(void)
{
    //get command and pid
    printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
        current->comm, current->pid, __FILE__, __func__, __LINE__);

    platform_driver_unregister(&drv);
}
module_init(drv_init);
module_exit(drv_exit);
#else
//3. register obj
module_platform_driver(drv);
#endif

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Farsight");
MODULE_DESCRIPTION("Demo for kernel module");

设备端

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

#include <asm/current.h>
#include <linux/sched.h>

#include <linux/ioport.h>
#include <linux/platform_device.h>

#include "../private.h"

static struct privatedata priv = {
    .val = 0x12345678,
    .str = "hello world",
};

struct resource res[] = {
    [0] = {
        .start  = 0x10000000,
        .end    = 0x20000000-1,
        .flags  = IORESOURCE_MEM
    },
    [1] = {
        .start  = 10,
        .flags  = IORESOURCE_IRQ
    },
    [2] = DEFINE_RES_MEM(0x20000000, 1024),
    [3] = DEFINE_RES_IRQ(11),   
};

static void dev_release(struct device *dev)
{
    //get command and pid
    printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
        current->comm, current->pid, __FILE__, __func__, __LINE__);
}

//1. alloc obj
static struct platform_device demoobj = {
    //2. init obj
    .name   = "demo1",
    .id = 0,
    .dev    = {
        .platform_data = &priv, //私有数据
        .release = dev_release,
    },
    .num_resources  = ARRAY_SIZE(res),
    .resource   = res,
};

#if 0
static int __init device_init(void)
{
    //get command and pid
    printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
        current->comm, current->pid, __FILE__, __func__, __LINE__);
    return platform_device_register(&demoobj);
}

static void __exit device_exit(void)
{
    //get command and pid
    printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
        current->comm, current->pid, __FILE__, __func__, __LINE__);
    platform_device_unregister(&demoobj);
}

module_init(device_init);
module_exit(device_exit);
#else
//3. register obj
module_platform_device(demoobj);
#endif

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Farsight");
MODULE_DESCRIPTION("Demo for kernel module");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xxgui1992

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值