驱动中常用到platform_set_drvdata 和 platform_get_drvdata这两个函数, 用于保存局部变量
include/linux/platform_device.h中:
static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
        return dev_get_drvdata(&pdev->dev);
}
static inline void platform_set_drvdata(struct platform_device *pdev, void *data)
{
        dev_set_drvdata(&pdev->dev, data);
}
 
static inline void
dev_set_drvdata (struct device *dev, void *data)
{
    dev->driver_data = data;
}
就是吧data赋值给dev->driver_data,pdev是平台总线设备,对于整个驱动是可见的,所以可以通过platform_get_drvdata来获取data。

内核模块一般在probe()函数中动态申请内存来使用,这种情况下,这个指针就得有个位置存储防止丢失,

所以内核设计得在platform_device结构体中,保留了一个指针,就是为了这样的驱动编写方式。

所以我们一般在probe()函数中

动态申请设备结构体,并初始化它,然后使用platform_set_drvdata()将其保存到platform_device中,

//准备platform_driver
static int
plat_probe(struct platform_device *pdev)
{
    struct plat_priv *priv;

    priv = (struct plat_priv *)kzalloc(sizeof(*priv), GFP_KERNEL);
    if (!priv)
        return -ENOMEM;

      ......

    //将分配的私有结构体指针存入pdev中
    platform_set_drvdata(pdev, priv);


在需要使用的时候再使用platform_get_drvdata()来获取它。

但是这个指针肯定是需要我们自己释放内存的。

static int
plat_remove(struct platform_device *pdev)
{
    //从pdev中获得私有结构体的指针
    struct plat_priv *priv = platform_get_drvdata(pdev);
    kfree(priv);


在open函数中要找到和打开设备对应的私有结构体
static int
plat_open(struct inode *inode, struct file *filp)
{
    struct plat_priv *priv = container_of(inode->i_cdev, struct plat_priv, plat_cdev);
    filp->private_data = priv;

然后在/read/write/ioctl函数中才能使用该私有结构体

static long
plat_ioctl(struct file *filp, unsigned int req, unsigned long arg)
{
    struct plat_priv *dev = filp->private_data;


Logo

更多推荐