본문 바로가기
device driver

charter device driver - 4. platform driver module 만들기

by jsh91 2023. 5. 21.

device tree를 사용하며 platform driver module을 만들어보자

 

 

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/of_device.h>

static int open(struct inode *inode, struct file *file)
{
	pr_info("open() called.\n");
	return 0;
}

static int close(struct inode *inode, struct file *file)
{
	pr_info("close() called.\n");
	return 0;
}

static long ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	pr_info("ioctl() is called. cmd = %d, arg = %ld\n", cmd, arg);
	return 0;
}

static const struct file_operations mydev_fops = {
	.owner = THIS_MODULE,
	.open = open,
	.release = close,
	.unlocked_ioctl = ioctl,
};

static struct miscdevice miscdevice = {
		.minor = MISC_DYNAMIC_MINOR,
		.name = "mydev",
		.fops = &mydev_fops,
};

/* module 적재시 probe 실행 */
static int probe(struct platform_device *pdev)
{
	int ret;
	pr_info("probe() called.\n");
	ret = misc_register(&miscdevice);

	if (ret != 0) {
		pr_err("fail register misc device mydev");
		return ret;
	}

	pr_info("mydev got minor %i\n",miscdevice.minor);
	return 0;
}

/* module remove시 실행 */
static int remove(struct platform_device *pdev)
{
	pr_info("remove() called.\n");
	misc_deregister(&miscdevice);
	return 0;
}

/* 
device tree에서 "arrow,my_platform_driver" 과 매칭되며 드라이버기 지원하는 하드웨어를 식별 
    my_platform_driver {
        compatible = "arrow,my_platform_driver";
    };
*/
static const struct of_device_id my_of_ids[] = {
	{ .compatible = "arrow,platform_driver"},
	{},
};

/*
	MODULE_DEVICE_TABLE(type, id)
	type에 따라 module이 어떠한 것인지 나타내며 is의 struct 를 결정한다
	
	example
	pci: PCI 버스를 사용하는 장치를 지정합니다. id는 pci_device_id 구조체의 배열입니다.
	usb: USB 버스를 사용하는 장치를 지정합니다. id는 usb_device_id 구조체의 배열입니다.
	i2c: I2C 버스를 사용하는 장치를 지정합니다. id는 i2c_device_id 구조체의 배열입니다.
	spi: SPI 버스를 사용하는 장치를 지정합니다. id는 spi_device_id 구조체의 배열입니다.
	platform: 플랫폼 장치를 지정합니다. id는 platform_device_id 구조체의 배열입니다.
	of: Device Tree를 사용하는 장치를 지정합니다. id는 of_device_id 구조체의 배열입니다.
*/

MODULE_DEVICE_TABLE(of, my_of_ids);

/* Define platform driver structure */
static struct platform_driver platform_driver = {
	.probe = probe,
	.remove = remove,
	.driver = {
		//.name = "my_platform_driver",
		.name = "platform_driver_name",
		.of_match_table = my_of_ids,
		.owner = THIS_MODULE,
	}
};

/* platform driver 등록 */
module_platform_driver(platform_driver);

MODULE_LICENSE("GPL");

 

insmod 시 

root@raspberrypi:/home/board# dmesg
[  342.561853] probe() called.
[  342.562104] mydev got minor 60

 

static struct platform_driver platform_driver = {
	.probe = probe,
	.remove = remove,
	.driver = {
		//.name = "my_platform_driver",
		.name = "platform_driver_name",
		.of_match_table = my_of_ids,
		.owner = THIS_MODULE,
	}
};

platform_driver -> driver -> name으로 작성하면 아래 경로에 생성

root@raspberrypi:/# find /sys/ -name "platform_driver_name"
/sys/bus/platform/drivers/platform_driver_name

 

root@raspberrypi:/# ls -l /sys/bus/platform/drivers/platform_driver_name/
total 0
--w------- 1 root root 4096 May 21 13:45 bind
lrwxrwxrwx 1 root root    0 May 21 13:45 module -> ../../../../module/platform_driver
lrwxrwxrwx 1 root root    0 May 21 13:45 soc:my_platform_driver -> ../../../../devices/platform/soc/soc:my_platform_driver
--w------- 1 root root 4096 May 21 13:32 uevent
--w------- 1 root root 4096 May 21 13:45 unbind

 

    my_platform_driver {
        compatible = "arrow,platform_driver";
    };

device tree에서 node(my_platform_driver)는 아래 경로에 파일이 생성 

root@raspberrypi:/# find /sys/ -name "*my_platform_driver*"
/sys/devices/platform/soc/soc:my_platform_driver
/sys/firmware/devicetree/base/soc/my_platform_driver
/sys/bus/platform/devices/soc:my_platform_driver
/sys/bus/platform/drivers/platform_driver_name/soc:my_platform_driver

 

 

device tree
    my_platform_driver {
        compatible = "arrow,platform_driver";
    };

module
static const struct of_device_id my_of_ids[] = {
	{ .compatible = "arrow,platform_driver"},
	{},
};

device tree 및 module 작성한 platform_driver는 아래 경로에 파일이 생성

root@raspberrypi:/# ls -l /sys/module/platform_driver/drivers/
total 0
lrwxrwxrwx 1 root root 0 May 21 13:47 platform:platform_driver_name -> ../../../bus/platform/drivers/platform_driver_name

 

 

static struct miscdevice miscdevice = {
		.minor = MISC_DYNAMIC_MINOR,
		.name = "mydev",
		.fops = &mydev_fops,
};

miscdevi -> name(mydev)으로 작성하면 아래 경로에 파일 생성

root@raspberrypi:/# ls /sys/class/misc/mydev
dev  power  subsystem  uevent

 

root@raspberrypi:/# cat /sys/class/misc/mydev/dev
10:60

댓글