-
Notifications
You must be signed in to change notification settings - Fork 9
Kernel Module 3 GPIO
We use SoC pin 18 (which is pin 14 on the expansion header) as an example and connect a LED to it as in GPIO.
Note, that this pin must be in GPIO mode, not in alternate mode. See device tree and expansion header how to test or set this.
Now, we want to switch the LED on and off from a kernel module. Kernel Module 2 - Char Device is used as a starting point.
Add the following lines to my_module.c
at global scope:
#include <linux/gpio.h>
const int my_gpio = 18;
int my_value = 0;
Extend my_init
function:
int rc;
rc = gpio_request( my_gpio, "my_gpio" );
if(rc < 0)
{
printk(KERN_ERR "gpio_request failed, error %d\n", rc );
return rc;
}
rc = gpio_direction_output( my_gpio, 0 );
if(rc < 0)
{
printk(KERN_ERR "gpio_direction_output failed, error %d\n", rc );
return rc;
}
Extend the my_write
function such that the LED is switched:
...
case '1':
gpio_set_value( my_gpio, 1 );
...
case '0':
gpio_set_value( my_gpio, 0 );
...
Extend the my_exit
function such that the kernel resources are freed and the module can be loaded again:
static void __exit my_exit(void)
{
gpio_free( my_gpio );
...
}
Cross-compile the kernel module, copy it to the target and load the module on the target:
root@raspberrypi:~$ insmod my_module.ko
Now, you can set and clear the LED using the device /dev/my_dev
exposed by the module:
root@raspberrypi:~$ echo 1 > /dev/my_dev
root@raspberrypi:~$ echo 0 > /dev/my_dev
You may also read the response from your module:
root@raspberrypi:~$ cat /dev/my_dev
The response should start with OK when you issued a valid command and with ERROR else. Each response is only given once per command.
Use the device /dev/my_dev
exposed by your loaded module my_module.ko
with the usual Posix IO functions:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int i;
int f = open( "/dev/my_dev", O_RDWR );
for(i=0;i<100;++i) {
write( f, "1", 1 );
sleep(1);
write( f, "0", 1 );
sleep(1);
}
close(f);
}
Checking of return codes of all IO functions is omitted here for simplicity but should be present in your code! You might also read the response produced by the module and print it out for debugging.
Note, the the printk
output from your module does not appear here. It is usually added to the kernel log and printed on the Linux console. The kernel log can be retrieved and configured in a shell by using the dmesg
command.
You may only use the IO functions that you have implemented. In advanced scenarios you might want to implement ioctl to communicate to your module via customized C data structures (struct) instead of the simple char based IO.
Kernel Module 4 - Timer shows how to add a timer to the kernel module and execute periodic tasks.