Linux - Embedded & Single-board computerThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have recently gotten started with device drivers programming on my raspberry pi 5. While writing a program to access GPIO pins I encountered an error during gpio_request. The gpio.h header has been included and the pin numbers have been reffered to. Cant seen to figure out where the error is. The part which confuses me is that a test code i wrote to access the gpio pins in python works perfectly fine. Can someone please help me out with this. The pins i tried to access were 4 and 17
Code:
Code:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
/* Meta Information */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Johannes 4 GNU/Linux");
MODULE_DESCRIPTION("A simple gpio driver for setting a LED and reading a button");
/* Variables for device and device class */
static dev_t my_device_nr;
static struct class *my_class;
static struct cdev my_device;
#define DRIVER_NAME "my_gpio_driver"
#define DRIVER_CLASS "MyModuleClass"
/**
* @brief Read data out of the buffer
*/
static ssize_t driver_read(struct file *File, char *user_buffer, size_t count, loff_t *offs) {
int to_copy, not_copied, delta;
char tmp[3] = " \n";
/* Get amount of data to copy */
to_copy = min(count, sizeof(tmp));
/* Read value of button */
printk("Value of button: %d\n", gpio_get_value(17));
tmp[0] = gpio_get_value(17) + '0';
/* Copy data to user */
not_copied = copy_to_user(user_buffer, &tmp, to_copy);
/* Calculate data */
delta = to_copy - not_copied;
return delta;
}
/**
* @brief Write data to buffer
*/
static ssize_t driver_write(struct file *File, const char *user_buffer, size_t count, loff_t *offs) {
int to_copy, not_copied, delta;
char value;
/* Get amount of data to copy */
to_copy = min(count, sizeof(value));
/* Copy data to user */
not_copied = copy_from_user(&value, user_buffer, to_copy);
/* Setting the LED */
switch(value) {
case '0':
gpio_set_value(4, 0);
break;
case '1':
gpio_set_value(4, 1);
break;
default:
printk("Invalid Input!\n");
break;
}
/* Calculate data */
delta = to_copy - not_copied;
return delta;
}
/**
* @brief This function is called, when the device file is opened
*/
static int driver_open(struct inode *device_file, struct file *instance) {
printk("dev_nr - open was called!\n");
return 0;
}
/**
* @brief This function is called, when the device file is opened
*/
static int driver_close(struct inode *device_file, struct file *instance) {
printk("dev_nr - close was called!\n");
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = driver_open,
.release = driver_close,
.read = driver_read,
.write = driver_write
};
/**
* @brief This function is called, when the module is loaded into the kernel
*/
static int __init ModuleInit(void) {
printk("Hello, Kernel!\n");
/* Allocate a device nr */
if( alloc_chrdev_region(&my_device_nr, 0, 1, DRIVER_NAME) < 0) {
printk("Device Nr. could not be allocated!\n");
return -1;
}
printk("read_write - Device Nr. Major: %d, Minor: %d was registered!\n", my_device_nr >> 20, my_device_nr && 0xfffff);
/* Create device class */
if((my_class = class_create(THIS_MODULE, DRIVER_CLASS)) == NULL) {
printk("Device class can not be created!\n");
goto ClassError;
}
/* create device file */
if(device_create(my_class, NULL, my_device_nr, NULL, DRIVER_NAME) == NULL) {
printk("Can not create device file!\n");
goto FileError;
}
/* Initialize device file */
cdev_init(&my_device, &fops);
/* Regisering device to kernel */
if(cdev_add(&my_device, my_device_nr, 1) == -1) {
printk("Registering of device to kernel failed!\n");
goto AddError;
}
/* GPIO 4 init */
if(gpio_request(4, "rpi-gpio-4")) {
printk("Can not allocate GPIO 4\n");
goto AddError;
}
/* Set GPIO 4 direction */
if(gpio_direction_output(4, 0)) {
printk("Can not set GPIO 4 to output!\n");
goto Gpio4Error;
}
/* GPIO 17 init */
if(gpio_request(17, "rpi-gpio-17")) {
printk("Can not allocate GPIO 17\n");
goto Gpio4Error;
}
/* Set GPIO 17 direction */
if(gpio_direction_input(17)) {
printk("Can not set GPIO 17 to input!\n");
goto Gpio17Error;
}
return 0;
Gpio17Error:
gpio_free(17);
Gpio4Error:
gpio_free(4);
AddError:
device_destroy(my_class, my_device_nr);
FileError:
class_destroy(my_class);
ClassError:
unregister_chrdev_region(my_device_nr, 1);
return -1;
}
/**
* @brief This function is called, when the module is removed from the kernel
*/
static void __exit ModuleExit(void) {
gpio_set_value(4, 0);
gpio_free(17);
gpio_free(4);
cdev_del(&my_device);
device_destroy(my_class, my_device_nr);
class_destroy(my_class);
unregister_chrdev_region(my_device_nr, 1);
printk("Goodbye, Kernel\n");
}
module_init(ModuleInit);
module_exit(ModuleExit);
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.