LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer
User Name
Password
Linux - Embedded & Single-board computer This forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.

Notices


Reply
  Search this Thread
Old 04-27-2012, 09:40 AM   #1
bk.amol@gmail.com
LQ Newbie
 
Registered: Apr 2012
Posts: 3

Rep: Reputation: Disabled
sysfs class registration


I want to use the sysclass device module i have registered the class called Dev_Hello and have created the class attribute called enable and its been showing in /sys/class/Dev_Hello/enable but when i do
cat enable i am expecting "enabled" to be displayed on stdout, but i am not able to see anything on the std out and system crashes.

Please guide me...

below is my code:


1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4 #include <linux/fs.h>
5 #include <linux/device.h>
6 #include <linux/sysdev.h>
7 #include <linux/major.h>
8 #include <asm/uaccess.h>
9 #include <linux/slab.h>
10 #include <linux/cdev.h>
11 #include <linux/kdev_t.h>
12
13
14 #define MAJOR_NUM 200
15 #define DEVICE_NAME "cdev"
16
17 static ssize_t enable_store(struct class *cls, const char *buf, size_t count);
18 static ssize_t enable_show(struct class *cls, char *buf);
19
20 static struct file_operations fops;
21
22 static struct class_attribute class_attr[] = {
23 __ATTR(enable, 0644, enable_show, enable_store),
24 __ATTR_NULL
25 };
26
27 static struct class hello_drv = {
28 .name = "Dev_Hello",
29 .owner = THIS_MODULE,
30 .class_attrs =(struct class_attribute *) &class_attr,
31 };
32
33 static ssize_t enable_show(struct class *cls, char *buf)
34 {
35 char *x[] = {"Enabled", "Disabled"};
36 printk("In enable_show function\n");
37 return sprintf(buf, "%s\n", x[0]);
38 }
39
40 static ssize_t enable_store(struct class *cls, const char *buf, size_t count)
41 {
42 printk("In enable_store function\n");
43 return 1;
44 }
45
46
47 static int hello_init(void)
48 {
49 int status;
50 status = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
51 if(status < 0)
52 printk("Registering char driver failed with status = %d\n", status);
53 else
54 printk("Hello World\n");
55
56 status = class_register(&hello_drv);
57 if(status < 0)
58 printk("Registering Class Failed\n");
59
60 return 0;
61 }
62
63 static void hello_exit(void)
64 {
65 class_unregister(&hello_drv);
66 unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
67 printk(" GoodBye, world\n");
68 }
69
70 module_init(hello_init);
71 module_exit(hello_exit);
72 MODULE_LICENSE("GPL");
 
Old 05-03-2012, 04:15 PM   #2
engr04
LQ Newbie
 
Registered: Mar 2012
Posts: 21

Rep: Reputation: Disabled
Your code works for me. Can you post the output similiar to what I have done below?

Quote:
# insmod class_test.ko
Hello World
# cat /sys/class/Dev_Hello/enable
In enable_show function
Enabled
# rmmod class_test.ko
GoodBye, world
Code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/major.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>

#define MAJOR_NUM 200
#define DEVICE_NAME "cdev"
static ssize_t enable_store(struct class *cls, const char *buf, size_t count);
static ssize_t enable_show(struct class *cls, char *buf);

static struct file_operations fops;

static struct class_attribute class_attr[] =
{ __ATTR(enable, 0644, enable_show, enable_store), __ATTR_NULL };

static struct class hello_drv =
{ .name = "Dev_Hello", .owner = THIS_MODULE, .class_attrs =
		(struct class_attribute *) &class_attr, };

static ssize_t enable_show(struct class *cls, char *buf)
{
	char *x[] =
	{ "Enabled", "Disabled" };
	printk("In enable_show function\n");
	return sprintf(buf, "%s\n", x[0]);
}

static ssize_t enable_store(struct class *cls, const char *buf, size_t count)
{
	printk("In enable_store function\n");
	return 1;
}

static int hello_init(void)
{
	int status;
	status = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
	if (status < 0)
		printk("Registering char driver failed with status = %d\n", status);
	else
		printk("Hello World\n");

	status = class_register(&hello_drv);
	if (status < 0)
		printk("Registering Class Failed\n");

	return 0;
}

static void hello_exit(void)
{
	class_unregister(&hello_drv);
	unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
	printk(" GoodBye, world\n");
}

module_init( hello_init);
module_exit( hello_exit);
MODULE_LICENSE("GPL");
 
Old 05-03-2012, 10:55 PM   #3
engr04
LQ Newbie
 
Registered: Mar 2012
Posts: 21

Rep: Reputation: Disabled
The parameters in enable_show and enable_store are incorrect. When compiling the module, you get the following warnings:

Quote:
workspace_linux/class_test/class_test.c:21:1: warning: initialization from incompatible pointer type [enabled by default]
workspace_linux/class_test/class_test.c:21:1: warning: (near initialization for ‘class_attr[0].show’) [enabled by default]
workspace_linux/class_test/class_test.c:21:1: warning: initialization from incompatible pointer type [enabled by default]
workspace_linux/class_test/class_test.c:21:1: warning: (near initialization for ‘class_attr[0].store’) [enabled by default]
Fix:

Code:
-static ssize_t enable_store(struct class *cls, const char *buf, size_t count);
+static ssize_t enable_store(struct class *cls, struct class_attribute *attr, const char *buf, size_t count);

-static ssize_t enable_show(struct class *cls, char *buf);
+static ssize_t enable_show(struct class *cls, struct class_attribute *attr, char *buf);

-static ssize_t enable_store(struct class *cls, const char *buf, size_t count)
+static ssize_t enable_store(struct class *cls, struct class_attribute *attr, const char *buf, size_t count)

-static ssize_t enable_show(struct class *cls, char *buf)
+static ssize_t enable_show(struct class *cls, struct class_attribute *attr, char *buf)
Complete Code:

Code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/major.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>

#define MAJOR_NUM 200
#define DEVICE_NAME "cdev"
static ssize_t enable_store(struct class *cls, struct class_attribute *attr, const char *buf, size_t count);
static ssize_t enable_show(struct class *cls, struct class_attribute *attr, char *buf);

static struct file_operations fops;

static struct class_attribute class_attr[] =
{ __ATTR(enable, 0644, enable_show, enable_store), __ATTR_NULL };

static struct class hello_drv =
{ .name = "Dev_Hello", .owner = THIS_MODULE, .class_attrs =
                (struct class_attribute *) &class_attr, };

static ssize_t enable_show(struct class *cls, struct class_attribute *attr, char *buf)
{
        char *x[] =
        { "Enabled", "Disabled" };
        printk("In enable_show function\n");
        return sprintf(buf, "%s\n", x[0]);
}

static ssize_t enable_store(struct class *cls, struct class_attribute *attr, const char *buf, size_t count)
{
        printk("In enable_store function\n");
        return 1;
}

static int hello_init(void)
{
        int status;
        status = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
        if (status < 0)
                printk("Registering char driver failed with status = %d\n", status);
        else
                printk("Hello World\n");

        status = class_register(&hello_drv);
        if (status < 0)
                printk("Registering Class Failed\n");

        return 0;
}

static void hello_exit(void)
{
        class_unregister(&hello_drv);
        unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
        printk(" GoodBye, world\n");
}

module_init( hello_init);
module_exit( hello_exit);
MODULE_LICENSE("GPL");
 
Old 05-06-2012, 09:42 PM   #4
bk.amol@gmail.com
LQ Newbie
 
Registered: Apr 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
engr04,
Thanks it worked for me after your changes
 
Old 05-08-2012, 09:00 AM   #5
bk.amol@gmail.com
LQ Newbie
 
Registered: Apr 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
Hi,
Further continuing my previous code i am registering a class in "static int hello_init(void)" function and adding to the linked list and in
"static void hello_exit(void)" function i am trying to find the device from the list in the class using "class_find_device(&hello_drv, NULL, tmp, match_entry)" and un-registering all the devices from the calss and finally unregistering the class.

When i do insmod it works fine
But rmmod displays the message "killed" and the driver is not removed
messages are as below:

$>insmod hello.ko
$> rmmod hello.ko
killed
Please guide me i have copied my whole code.


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/major.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>

#define MAJOR_NUM 200
#define DEVICE_NAME "cdev"

static int enable = 0;

struct hello_dev {
struct list_head list;
int device_open;
dev_t tev;
char name[10];
char buff[50];
};

static struct hello_dev mylist;
static struct hello_dev ref[4];

static ssize_t export_store(struct class *cls,struct class_attribute *attr, const char *buf, size_t count);
static ssize_t export_show(struct class *cls, struct class_attribute *attr, char *buf);
static ssize_t dev_attr_show(struct device *dev, struct device_attribute *attr, char *buf) ;
static ssize_t dev_attr_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size);

static ssize_t hello_read(struct file *, char *, size_t, loff_t *);
static ssize_t hello_write(struct file *, const char *, size_t, loff_t *);
static long hello_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long ioctl_param);
static int hello_open(struct inode *, struct file *);
static int hello_release(struct inode *, struct file *);



static DEVICE_ATTR(Devattr, 0644, dev_attr_show, dev_attr_store);

static struct file_operations fops = {
.open = hello_open,
.read = hello_read,
.write = hello_write,
.release = hello_release,
.unlocked_ioctl = hello_ioctl
};

static struct class_attribute class_attr[] = {
__ATTR(export, 0644, export_show, export_store),
__ATTR_NULL,
};


static const struct attribute *Device_attrs[] = {
&dev_attr_Devattr.attr,
NULL,
};

static const struct attribute_group Device_attr_group = {
.attrs = (struct attribute **) Device_attrs,
};

static struct class hello_drv = {
.name = "Dev_Hello",
.owner = THIS_MODULE,
.class_attrs = (struct class_attribute *) &class_attr,
};

static ssize_t dev_attr_show(struct device *dev, struct device_attribute *attr, char *buf)
{
char *x[] = {"Disabled", "Enabled"};
return sprintf(buf, "%s\n", x[enable]);
return 0;
}

static ssize_t dev_attr_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
sscanf(buf, "%du", &enable);
return size;
}

static ssize_t export_show(struct class *cls, struct class_attribute *attr, char *buf)
{
char *x[] = {"Disabled", "Enabled"};
return sprintf(buf, "%s\n", x[enable]);
}

static ssize_t export_store(struct class *cls,struct class_attribute *attr, const char *buf, size_t count)
{
sscanf(buf, "%du", &enable);
return count;
}

static int hello_open(struct inode *inode, struct file *file)
{
struct hello_dev *hdev;
struct device *dev;
int status;
int count = 0;

hdev = &ref[iminor(inode)];
if((hdev->device_open) || (count >=3))
{
printk(KERN_INFO "Device Already Open\n Cannot open more devices");
return -EBUSY;
}
else if(count < 3)
{
count++;
hdev->device_open = 1;
file->private_data = hdev;

dev = device_create(&hello_drv, NULL, MKDEV(imajor(inode),iminor(inode)), NULL, "%s%d", "hdev", (int)count);
if(dev)
{
status = sysfs_create_group(&dev->kobj, &Device_attr_group);
if(status != 0)
printk("error creating sysfs_group\n");
return 0 ;
}
printk(KERN_INFO"Device opened\n");
try_module_get(THIS_MODULE);
}
return 0;
}

static int hello_release(struct inode *inode, struct file *file)
{
struct hello_dev *hdev;
hdev = (struct hello_dev *)file->private_data;
hdev->device_open = 0;
device_destroy(&hello_drv, MKDEV(imajor(inode), iminor(inode)));
// class_unregister(&hello_drv);
// unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
printk(" GoodBye, world\n");
module_put(THIS_MODULE);
return 0;
}

static int hello_read(struct file *flip, char __user *buffer, size_t length, loff_t *offset)
{
int status;
struct hello_dev *hdev;

hdev = (struct hello_dev *)flip->private_data;
status = copy_to_user(buffer, hdev->buff, length);
if(status)
{
printk("Copy to user unsuccessful\n No: of bytes not copied = %d\n", status);
status = length - status;
}
else
{
printk("Device read\n");
}
return status;
}

static int hello_write(struct file *flip, const char * buffer, size_t length, loff_t * offset)
{
int count;
struct hello_dev *hdev;
hdev = (struct hello_dev *)flip->private_data;
memset(hdev->buff, '\0', length);
count = copy_from_user(hdev->buff, buffer, length);
printk("Device Write Done\n");
count = length - count;
return count;
}

long hello_ioctl(struct file *flip,unsigned int ioctl_num,unsigned long ioctl_param)
{
switch(ioctl_num)
{
case 0:
printk("IOCTL : CASE 0:");
break;

case 1:
printk("IOCTL : CASE 1:");
break;

default:
printk(KERN_ALERT"Unknown IOCTL number\n");
break;
}
return 0;
}


static int hello_init(void)
{
int status;
struct device *dev;
int count = 0;
int i;
struct list_head *pos, *q;
struct hello_dev *tmp;
// struct hello_dev mylist;
INIT_LIST_HEAD(&mylist.list);

for(i=0; i<4;i++)
{
ref[i].device_open = 0;
}

status = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
if(status < 0)
printk("Registering char driver failed with status = %d\n", status);
else
printk("Hello World\n");

status = class_register(&hello_drv);
if(status < 0)
printk("Registering Class Failed\n");

tmp = (struct hello_dev *)kmalloc(sizeof(struct hello_dev), GFP_KERNEL);

tmp->device_open = 1;
tmp->tev = MKDEV(MAJOR_NUM, count);

list_add(&(tmp->list), &(mylist.list));

dev = device_create(&hello_drv, NULL, MKDEV(MAJOR_NUM,count), NULL, "%s%d", "hdev", (int) count);
count++;
if(dev)
{
status = sysfs_create_group(&dev->kobj, &Device_attr_group);
if(status != 0)
printk("error creating sysfs_group\n");
}

list_for_each(pos, &mylist.list)
{
tmp = list_entry(pos, struct hello_dev, list);
printk("device_open = %d dev_t = 0x%X \n ", tmp->device_open, tmp->tev);
}
return 0;
}

static int match_entry(struct device *dev, void *data)
{
dev_t *devt = data;
return dev->devt == *devt;

// return dev_get_drvdata(dev) == data;
}

static void hello_exit(void)
{
struct hello_dev *tmp;
struct device *dev;
struct list_head *pos, *q;

list_for_each(pos, &mylist.list)
{
tmp = list_entry(pos, struct hello_dev, list);
dev = class_find_device(&hello_drv, NULL, tmp, match_entry);
if(dev)
device_unregister(dev);
else
printk("Den Is NULL");
list_del(pos);
kfree(tmp);
}
class_unregister(&hello_drv);
unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
printk(" GoodBye, world\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
 
Old 05-10-2012, 09:06 PM   #6
engr04
LQ Newbie
 
Registered: Mar 2012
Posts: 21

Rep: Reputation: Disabled
I didn't try to compile your code, but it looks like you are missing the sysfs_remove_group to unregister your sysfs_create_group.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Why can't we access a protected member in a derived class by a base class's object? Aquarius_Girl Programming 5 02-04-2012 10:35 PM
Does making a class a 'friend' make the class' member classes 'friends'? Jusctsch Programming 7 11-17-2011 07:58 PM
[SOLVED] Python n00b: promoting a derived class to base class? CoderMan Programming 2 03-11-2010 01:46 PM
Does derivated class inherit base class destructor (constructor)? kornerr Programming 2 08-23-2006 08:05 AM
Which C++ editor in Linux has the class view/class browser feature imaginationworks Programming 7 05-21-2006 11:09 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer

All times are GMT -5. The time now is 06:54 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration