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
'device driver' 카테고리의 다른 글
| charter device driver - 6. led_class_platform 만들기 (0) | 2023.05.26 |
|---|---|
| charter device driver - 5. platform_driver로 led control 해보자 (0) | 2023.05.22 |
| charter device driver - 3. misc driver 만들기 (0) | 2023.05.21 |
| charter device driver - 2. char device drier 만들기 (0) | 2023.05.21 |
| charter device driver - 1. 간단한 module 만들기 (0) | 2023.05.21 |
댓글