Skip to content

Instantly share code, notes, and snippets.

@khaledsaied
Created December 6, 2012 18:38
Show Gist options
  • Select an option

  • Save khaledsaied/4226913 to your computer and use it in GitHub Desktop.

Select an option

Save khaledsaied/4226913 to your computer and use it in GitHub Desktop.
sysLed Linux Device Model
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#define GPIO 164 //GPIO port-nr
#define myMAJOR 64
#define myMINOR 0
#define ch 1
#define MAXLEN 512
static struct class *led_class;
//static struct cdev My
struct file_operations my_fops;
static int devno;
int err;
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("NKB");
MODULE_DESCRIPTION("Reads the user_key");
MODULE_LICENSE("Dual BSD/GPL");
ssize_t mygpio_write(struct file *filep, const char __user *ubuf, size_t count, loff_t *f_pos);
int mygpio_open (struct inode *inode, struct file *file);
int mygpio_release (struct inode *inode, struct file *file);
struct file_operations my_fops = {
.owner = THIS_MODULE,
.write = mygpio_write,
.open = mygpio_open,
.release = mygpio_release,
};
static struct cdev my_cdev;
static int mygpio_init(void)
{
printk(KERN_ALERT "Hello, world\n");
err = gpio_request_one(GPIO, GPIOF_DIR_OUT, "Init User-key"); //Request GPIO, set GPIO direction (in)
if (err != 0)
goto requestError;
devno = MKDEV(myMAJOR,myMINOR); //make device number
cdev_init(&my_cdev, &my_fops);
err = cdev_add(&my_cdev, devno, ch);
if (err != 0)
goto cdevAddError;
err = register_chrdev_region(devno,ch,"User-key");
if (err != 0)
goto registerChrdevError;
// alloc_chrdev_region() kunne bruges for dynamisk allkoering
/* Create a class, ie a folder in sysfs */
led_class = class_create(THIS_MODULE, "ledKlasse");
/* Create an object (device), ie a file under the class just created */
/* (New version of class_device_create) */
device_create(led_class, NULL, devno, NULL, "ledDevice");
return 0;
requestError:
{
printk(KERN_ALERT "Request FAILED!\n");
gpio_free(GPIO);
return 0;
}
cdevAddError:
{
printk(KERN_ALERT "cdev add FAILED!\n");
cdev_del(&my_cdev);
return 0;
}
registerChrdevError:
{
printk(KERN_ALERT "registering FAILED!\n");
unregister_chrdev_region(devno,ch);
return 0;
}
}
static void mygpio_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
/* Destroy device from Device Model / Sysfs */
device_destroy(led_class, devno);
/* Remove class from Device Model / Sysfs */
class_destroy(led_class);
unregister_chrdev_region(devno,ch); // skal den ikke være i cleanup func?
cdev_del(&my_cdev);
gpio_free(GPIO);
}
int mygpio_open(struct inode *inode, struct file *file)
{
int major, minor;
major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);
printk("Opening MyGpio Device [major], [minor]: %i, %i\n", major, minor);
return 0;
}
int mygpio_release(struct inode *inode, struct file *file)
{
int minor, major;
major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);
return 0;
}
ssize_t mygpio_write(struct file *filep, const char __user *ubuf, size_t count, loff_t *f_pos)
{
int minor, len, scanValue;
char kbuf[MAXLEN];
minor = MINOR(filep->f_dentry->d_inode->i_rdev);
if(count < MAXLEN)
len = count;
else
len = MAXLEN;
copy_from_user(kbuf, ubuf, len);
kbuf[len]= '\0';
sscanf(kbuf, "%d",&scanValue);
gpio_set_value(GPIO, scanValue);
// Hvilke trin er det der skal udføres?
// Hint konvertering fra string til int kan gøres via sscanf() - antagelsen er at det er strenge der sendes til og fra user space. Det debugging lettere.
*f_pos += count;
return count;
}
module_init(mygpio_init);
module_exit(mygpio_exit);
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#define GPIO 164 //GPIO port-nr
//#define myMAJOR 64
#define MINOR_START 0 // minor nummer starter ved 0
#define ch 10 // Antal minor numre
#define MAXLEN 512
static struct class *led_class;
//static struct cdev My
struct file_operations my_fops;
static dev_t devno;
int err;
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("NKB");
MODULE_DESCRIPTION("Reads the user_key");
MODULE_LICENSE("Dual BSD/GPL");
/* Sysfs "read" method prototype */
static ssize_t show_ledAttrs(struct device *dev, struct device_attribute *attr)
{
printk("SHOW !!! \n");
}
/* Sysfs "write" method prototype */
static ssize_t store_ledAttrs(struct device *dev, struct device_attribute *attr )
{
/* //OPGAVE h
int *num = dev_get_drvdata(dev);
ssize_t ret = -EINVAL;
char *after;
unsigned long value = simple_strtoul(buf, &after, 10);
size_t count = after - buf;
if (isspace(*after))
count++;
printk("using Store to set gpio #%i to %i\n", *num, (int)value);
gpio_set_value(*num, value);
return count;
*/
}
ssize_t mygpio_write(struct file *filep, const char __user *ubuf, size_t count, loff_t *f_pos);
int mygpio_open (struct inode *inode, struct file *file);
int mygpio_release (struct inode *inode, struct file *file);
struct file_operations my_fops = {
.owner = THIS_MODULE,
.write = mygpio_write,
.open = mygpio_open,
.release = mygpio_release,
};
static struct cdev my_cdev;
static int mygpio_init(void)
{
int gpio_sysLed4_no = 164;
printk(KERN_ALERT "Hello, world\n");
err = gpio_request_one(GPIO, GPIOF_DIR_OUT, "Init User-key"); //Request GPIO, set GPIO direction (in)
if (err != 0)
goto requestError;
cdev_init(&my_cdev, &my_fops);
err = cdev_add(&my_cdev, devno, ch);
if (err != 0)
goto cdevAddError;
err = alloc_chrdev_region(&devno,MINOR_START,ch,"User-key");
if (err != 0)
goto registerChrdevError;
// alloc_chrdev_region() kunne bruges for dynamisk allkoering
/* Create a class, ie a folder in sysfs */
led_class = class_create(THIS_MODULE, "ledKlasse");
/* Macro to create attributes */
static struct device_attribute led_class_attrs[] = {__ATTR(ledAttrs, S_IWUSR|S_IRUGO, show_ledAttrs, store_ledAttrs), __ATTR_NULL,};
/* ATTRIBUTER ??? */
led_class->dev_attrs = led_class_attrs;
/* Create an object (device), ie a file under the class just created */
/* (New version of class_device_create) */
device_create(led_class, NULL, devno, NULL, "ledDevice", drvdata(&gpio_sysLed4_no));
return 0;
requestError:
{
printk(KERN_ALERT "Request FAILED!\n");
gpio_free(GPIO);
return 0;
}
cdevAddError:
{
printk(KERN_ALERT "cdev add FAILED!\n");
cdev_del(&my_cdev);
return 0;
}
registerChrdevError:
{
printk(KERN_ALERT "registering FAILED!\n");
unregister_chrdev_region(devno,ch);
return 0;
}
}
static void mygpio_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
/* Destroy device from Device Model / Sysfs */
device_destroy(led_class, devno);
/* Remove class from Device Model / Sysfs */
class_destroy(led_class);
unregister_chrdev_region(devno,ch); // skal den ikke være i cleanup func?
cdev_del(&my_cdev);
gpio_free(GPIO);
}
int mygpio_open(struct inode *inode, struct file *file)
{
int major, minor;
major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);
printk("Opening MyGpio Device [major], [minor]: %i, %i\n", major, minor);
return 0;
}
int mygpio_release(struct inode *inode, struct file *file)
{
int minor, major;
major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);
return 0;
}
ssize_t mygpio_write(struct file *filep, const char __user *ubuf, size_t count, loff_t *f_pos)
{
int minor, len, scanValue;
char kbuf[MAXLEN];
minor = MINOR(filep->f_dentry->d_inode->i_rdev);
if(count < MAXLEN)
len = count;
else
len = MAXLEN;
copy_from_user(kbuf, ubuf, len);
kbuf[len]= '\0';
sscanf(kbuf, "%d",&scanValue);
gpio_set_value(GPIO, scanValue);
// Hvilke trin er det der skal udføres?
// Hint konvertering fra string til int kan gøres via sscanf() - antagelsen er at det er strenge der sendes til og fra user space. Det debugging lettere.
*f_pos += count;
return count;
}
module_init(mygpio_init);
module_exit(mygpio_exit);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment