본문 바로가기

Programming/Linux_Kernel

class 에 sysfs node 등록하여 사용하기

linux kernel 에서 kernel 단과 user 사이에 통신을 위한 방법중에 sysfs node 를 사용하는 방법이 있다.

지원하는 함수는 아래 3가지 함수들이 있다.


devclass_create_file

device_create_file


class_create_file


이중 devclass_create_file 은 삭제된 것으로 보인다.

class_create_file 의 예제를 첨부한다.



null_driver.c


Makefile


#include <linux/module.h> #include <linux/version.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/kdev_t.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/cdev.h> static dev_t first; // Global variable for the first device number static struct cdev c_dev; // Global variable for the character device structure static struct class *cl; // Global variable for the device class static int my_open(struct inode *i, struct file *f) { printk(KERN_INFO "Driver: open()\n"); return 0; } static int my_close(struct inode *i, struct file *f) { printk(KERN_INFO "Driver: close()\n"); return 0; } static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: read()\n"); return 0; } static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: write()\n"); return len; } static struct file_operations pugs_fops = { .owner = THIS_MODULE, .open = my_open, .release = my_close, .read = my_read, .write = my_write }; int g_data = 10; static ssize_t sysfs_show_func(struct class *cls, struct class_attribute *attr, char *buf) { printk("%s() g_data=%d\n", __func__, g_data); return sprintf(buf, "data : %d\n" ,g_data); } static ssize_t sysfs_store_func(struct class *cls, struct class_attribute *attr, const char *buf, size_t count) { int value; sscanf(buf, "%d", &value); printk("%s() value=%d\n", __func__, value); g_data = value; return count; } static CLASS_ATTR(onegun_sysfs, S_IWUSR | S_IRUGO, sysfs_show_func, sysfs_store_func); static int __init ofcd_init(void) /* Constructor */ { int ret = 0; printk(KERN_INFO "Namaskar: ofcd registered"); if (alloc_chrdev_region(&first, 0, 1, "Shweta") < 0) { return -1; } if ((cl = class_create(THIS_MODULE, "onegun_class_driver")) == NULL) { unregister_chrdev_region(first, 1); return -1; } if (device_create(cl, NULL, first, NULL, "mynull") == NULL) { class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } cdev_init(&c_dev, &pugs_fops); if (cdev_add(&c_dev, first, 1) == -1) { device_destroy(cl, first); class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } ret = class_create_file(cl, &class_attr_onegun_sysfs); if(ret) printk("%s() [Error] class_create_file\n", __func__); return 0; } static void __exit ofcd_exit(void) /* Destructor */ { cdev_del(&c_dev); device_destroy(cl, first); class_destroy(cl); unregister_chrdev_region(first, 1); printk(KERN_INFO "Alvida: ofcd unregistered"); } module_init(ofcd_init); module_exit(ofcd_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>"); MODULE_DESCRIPTION("Our First Character Driver");


'Programming > Linux_Kernel' 카테고리의 다른 글

사용가용한 physical memory block 을 얻어오는 방법  (0) 2014.04.07
poll, sysfs sample code  (0) 2014.04.07
demand paging  (0) 2014.04.01
리눅스커널의메모리관리  (0) 2014.03.31
slab allocator  (0) 2014.03.31