1. 程式人生 > >linux驅動platform_set_drvdata 和 platform_get_drvdata這兩個函式

linux驅動platform_set_drvdata 和 platform_get_drvdata這兩個函式

驅動中常用到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;