프로그래밍/리눅스 시스템
[Linux Kernel] Device Driver : Timer
KimuGamJa
2024. 4. 29. 05:33
- 동작 확인
- 모듈을 insmod 한 뒤, 로그를 확인한다.
- HZ 값이 출력되고 있다.
- HZ 값은 커널 소스에 정의된 값이다.
=> 커널 컴파일 시 설정파일 .config 에 CONFIG_HZ 로 설정되어 있다.
[Makefile]
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build
obj-m += devicedriver.o
PWD := $(CURDIR)
driver:
make -C $(KERNEL_HEADERS) M=$(PWD) modules
clean:
make -C $(KERNEL_HEADERS) M=$(PWD) cleancopy
[ devicedriver.c ]
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/timer.h>
#define NOD_NAME "deviceFile"
MODULE_LICENSE("GPL");
static int NOD_MAJOR;
static struct class *cls;
static dev_t dev;
static struct timer_list timer;
static void timer_func(struct timer_list *nextTimer){
pr_info("OH! (%d)\n", HZ);
mod_timer(nextTimer, get_jiffies_64() + (5*HZ / 10));
}
static int deviceFile_open(struct inode *inode, struct file *filp){
pr_info("Open Device\n");
return 0;
}
static int deviceFile_release(struct inode *inode, struct file *filp){
pr_info("Close Device\n");
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = deviceFile_open,
.release = deviceFile_release,
};
static int __init deviceFile_init(void)
{
NOD_MAJOR = register_chrdev(NOD_MAJOR, NOD_NAME, &fops);
if( NOD_MAJOR < 0 ){
pr_alert("Register File\n");
return NOD_MAJOR;
}
pr_info("Insmod Module\n");
dev = MKDEV(NOD_MAJOR, 0);
cls = class_create(NOD_NAME);
device_create(cls, NULL, dev, NULL, NOD_NAME);
pr_info("Major number %d\n", NOD_MAJOR);
pr_info("Device file : /dev/%s\n", NOD_NAME);
timer_setup(&timer, timer_func, 0);
timer.expires = get_jiffies_64() + (1*HZ);
add_timer(&timer);
return 0;
}
static void __exit deviceFile_exit(void)
{
del_timer_sync(&timer);
device_destroy(cls, dev);
class_destroy(cls);
unregister_chrdev(NOD_MAJOR, NOD_NAME);
pr_info("Unload Module\n");
}
module_init(deviceFile_init);
module_exit(deviceFile_exit);copy