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
{
return dev_get_drvdata(&pdev->dev);
}
{
dev_set_drvdata(&pdev->dev, data);
}
dev_set_drvdata (struct device *dev, void *data)
{
dev->driver_data = 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;
更多推荐
所有评论(0)