/*
* ID: mygpio.c
*/
#include
#include
#include
#include
#include
#define MYGPIO_MAJOR 62
#define MYGPIO_MINOR 0
#define MYGPIO_CHS 8
#define MAXLEN 512
static struct cdev MyGpioDev;
struct file_operations mygpio_Fops;
static int devno;
const unsigned int gpio_len = 8;
struct gpioPort{
unsigned int num;
enum direnu { in, out } dir;
const char label[10]; // Very important to specify a size. Just [] causes havoc to gpio indexing
} gpio[] = {
{130, in, "gpio0_0"},
{131, in, "gpio0_1"},
{132, in, "gpio0_2"},
{133, in, "gpio0_3"},
{134, out, "gpio0_4"},
{135, out, "gpio0_5"},
{136, out, "gpio0_6"},
{137, out, "gpio0_7"},
{139, out, "gpio0_9"}
};
static int mygpio_init(void)
{
int err, i;
printk(KERN_ALERT "Mygpio Module Inserted\n");
/*
* Allocate Major/Minor Numbers
*/
devno = MKDEV(MYGPIO_MAJOR, MYGPIO_MINOR);
if((err=register_chrdev_region(devno, gpio_len, "myGpio"))<0){
printk(KERN_ALERT "Can't Register Major no: %i\n", MYGPIO_MAJOR);
return err;
}
/*
* Create cdev
*/
cdev_init(&MyGpioDev, &mygpio_Fops);
MyGpioDev.owner = THIS_MODULE;
MyGpioDev.ops = &mygpio_Fops;
err = cdev_add(&MyGpioDev, devno, gpio_len);
if (err) {
printk (KERN_ALERT "Error %d adding MyGpio device\n", err);
return -1;
}
/*
* Request GPIO Ressources
*/
/*** YOUR CODE HERE ****/
//gpio_request(139, gpio);
gpio_request(130, "GPIO0_0");
/*
* Set GPIO Direction
*/
/*** YOUR CODE HERE ****/
//gpio_direction_output(139, 1);
gpio_direction_input(130);
return 0;
}
static void mygpio_exit(void)
{
int i;
printk(KERN_NOTICE "Removing Mygpio Module\n");
/*
* Set GPIOs to Inputs
* (leave things as when we entered)
*/
/*** YOUR CODE HERE ****/
gpio_direction_input(139);
/*
* Free GPIO Ressources
*/
/*** YOUR CODE HERE ****/
//gpio_free(139);
gpio_free(130);
/*
* Delete cdev
*/
unregister_chrdev_region(devno, gpio_len);
cdev_del(&MyGpioDev);
}
Implementer ”open” og ”release”
int mygpio_open(struct inode *inode, struct file *filep)
{
int major, minor;
major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);
printk("Opening MyGpio Device [major], [minor]: %i, %i\n", major, minor);
/*
* Check if major/minor is valid
*/
/*** YOUR CODE HERE ****/
/*
* Try to get the module sem
*/
if (!try_module_get(mygpio_Fops.owner)) // Get Module
return -ENODEV;
return 0;
}
int mygpio_release(struct inode *inode, struct file *filep)
{
int minor, major;
major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);
printk("Closing MyGpio Device [major], [minor]: %i, %i\n", major, minor);
/*
* Check if major/minor is valid
*/
/*** YOUR CODE HERE ****/
/*
* Put the module semaphore
* to release it
*/
module_put(mygpio_Fops.owner);
return 0;
}
Implementer ”write”
ssize_t mygpio_write(struct file *filep, const char __user *ubuf,
size_t count, loff_t *f_pos)
{
int minor, len, value;
char kbuf[MAXLEN];
/*
* retrieve minor from file ptr
*/
minor = MINOR(filep->f_dentry->d_inode->i_rdev);
printk(KERN_ALERT "Writing to MyGpio [Minor] %i \n", minor);
/*
* Check if minor is valid
*/
/*** YOUR CODE HERE ****/
/*
* Copy data from user space
* to kernel space
*/
len = count < MAXLEN ? count : MAXLEN; // set len < MAXLEN
/**** Use copy_from_user to get data ****/
/*** YOUR CODE HERE ****/
copy_from_user(kbuf, ubuf, count);
kbuf[len] = '\0'; // Pad null termination to string
printk("string from user: %s\n", kbuf);
/*
* Convert string to int
*/
/**** Use sscanf to convert string to int ****/
/*** YOUR CODE HERE ****/
sscanf(kbuf,"%i", &value);
printk("value %i\n", value);
value = value > 0 ? 1 : 0;
/*
* Set GPIO port
* (if an output port)
*/
/**** Use gpio_set_value on appropriate port ****/
/*** YOUR CODE HERE ****/
gpio_set_value(139, value);
*f_pos += count;
return count;
}
Implementer ”read”
ssize_t mygpio_read(struct file *filep, char __user *buf,
size_t count, loff_t *f_pos)
{
char readBuf[MAXLEN];
int len, result=-1, minor;
/*
* retrieve minor from file ptr
*/
minor = MINOR(filep->f_dentry->d_inode->i_rdev);
printk(KERN_ALERT "Reading from MyGpio [Minor] %i \n", minor);
/*
* Check if minor is valid
*/
/*** YOUR CODE HERE ****/
/*
* Read GPIO port
* (if an input port)
*/
/*** YOUR CODE HERE ****/
result = gpio_get_value(130);
/*
* Convert int to string
* using sprintf
*/
len=sprintf(readBuf,"%i", result);
len++; // To include null-termination
/*
* Copy string result
* to User Space
*/
/*** YOUR CODE HERE ****/
copy_to_user(buf, readBuf, len);
*f_pos += len;
return len;
}
struct file_operations mygpio_Fops =
{
.owner = THIS_MODULE,
.open = mygpio_open,
.release = mygpio_release,
.write = mygpio_write,
.read = mygpio_read,
};
module_init(mygpio_init);
module_exit(mygpio_exit);
MODULE_DESCRIPTION("My GPIO Module");
MODULE_AUTHOR("IHA
MODULE_LICENSE("GPL");
Indsæt modul, node, kørsel af læsningsprogram
insmod mygpio.ko
mknod /dev/wepee c 62
./rd /dev/wepee
Ingen kommentarer:
Send en kommentar