하여 miscdevice 처음 오픈 될 때, miscdevice 프레임 워크에 file->private_data
을 설정할 것이다 struct miscdevice
(misc_open() 함수와 같은 함수 comment to misc_register() 참조). 이 작업에 의존하여 파일 작업에 file->private_data
을 사용하여 container_of()
매크로를 사용하여 사용자 지정 구조를 얻을 수 있습니다. 물론 사용자 정의 구조에는 struct miscdevice
이 있어야합니다. 깔끔하고 일반적으로 사용되는 방법은 to_*()
이라는 도우미 함수를 작성하여 file
포인터로 사용자 정의 구조체를 찾아서 반환합니다. 따라서 사용자 정의 구조체 my_struct
을 호출 한 경우 해당 도우미 함수를 to_my_struct()
으로 호출해야합니다.
또한 플랫폼 드라이버를 작성하는 경우 dev_set_drvdata()
대신 platform_set_drvdata()
을 사용할 수 있습니다. 플랫폼 드라이버의 기능 remove()
에서 사용자 지정 구조를 얻을 수 있도록이 작업이 필요합니다.
$ git grep -l --all-match -e 'misc_register(' -e 'platform_device' -e 'file->private_data' -- drivers/
: 당신은 그냥이 같은 키워드를 사용하여, 커널 코드에서 예를 찾을 수있는 방법으로
struct my_struct {
struct platform_device *pdev;
struct miscdevice mdev;
};
static inline struct my_struct *to_my_struct(struct file *file)
{
struct miscdevice *miscdev = file->private_data;
return container_of(miscdev, struct my_struct, mdev);
}
static ssize_t my_read(struct file *file, char __user *buf, size_t count,
loff_t *pos)
{
struct my_struct *my = to_my_struct(file);
return simple_read_from_buffer(buf, count, pos, "my text", 7);
}
static const struct file_operations my_fops = {
.owner = THIS_MODULE,
.read = my_read,
};
static int my_probe(struct platform_device *pdev)
{
struct my_struct *my;
int ret;
my = devm_kzalloc(&pdev->dev, sizeof(*my), GFP_KERNEL);
if (!my)
return -ENOMEM;
platform_set_drvdata(pdev, my);
my->pdev = pdev;
my->mdev.minor = MISC_DYNAMIC_MINOR;
my->mdev.name = "my";
my->mdev.fops = &my_fops;
my->mdev.parent = NULL;
ret = misc_register(&my->mdev);
if (ret) {
dev_err(&pdev->dev, "Failed to register miscdev\n");
return ret;
}
dev_info(&pdev->dev, "Registered\n");
return 0;
}
static int my_remove(struct platform_device *pdev)
{
struct my_struct *my = platform_get_drvdata(pdev);
misc_deregister(&my->mdev);
dev_info(&pdev->dev, "Unregistered\n");
return 0;
}
: 여기
모든 것이 위에서 설명한에 대한 예입니다