Issue
I am trying to call a executable from Linux Kernel Module, which is a interrupt service routine.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
/* Meta Information */
MODULE_LICENSE("GPL");
/* Reference code is taken from here */
MODULE_AUTHOR("Johannes 4 GNU/Linux");
MODULE_DESCRIPTION("A simple LKM for a gpio interrupt");
/** variable contains pin number o interrupt controller to which GPIO 499 is mapped to */
unsigned int irq_number;
unsigned int toggle_value = 0;
/**
* Interrupt service routine is called, when interrupt is triggered
*/
static irq_handler_t gpio_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs) {
printk("gpio_irq: Interrupt was triggered and ISR was called!\n");
if (toggle_value == 0)
{
toggle_value = 1;
if(gpio_direction_output(498, 1)) {
printk("Error!\nCan not set GPIO 498 output value to 1!\n");
gpio_free(498);
}
}
if (toggle_value == 1)
{
toggle_value = 0;
if(gpio_direction_output(498, 0)) {
printk("Error!\nCan not set GPIO 498 output value to 0!\n");
gpio_free(498);
}
}
return (irq_handler_t) IRQ_HANDLED;
}
/**
* This function is called, when the module is loaded into the kernel
*/
static int __init ModuleInit(void) {
printk("qpio_irq: Loading module... ");
/* Setup the gpio */
if(gpio_request(499, "rpi-gpio-499")) {
printk("Error!\nCan not allocate GPIO 499\n");
return -1;
}
if(gpio_request(498, "rpi-gpio-498")) {
printk("Error!\nCan not allocate GPIO 498\n");
return -1;
}
/* Set GPIO direction */
if(gpio_direction_input(499)) {
printk("Error!\nCan not set GPIO 499 to input!\n");
gpio_free(499);
return -1;
}
/* Setup the interrupt */
irq_number = gpio_to_irq(499);
if(request_irq(irq_number, (irq_handler_t) gpio_irq_handler, IRQF_TRIGGER_RISING, "my_gpio_irq", NULL) != 0){
printk("Error!\nCan not request interrupt nr.: %d\n", irq_number);
gpio_free(499);
return -1;
}
printk("Done!\n");
printk("GPIO 499 is mapped to IRQ Nr.: %d\n", irq_number);
return 0;
}
/**
* This function is called, when the module is removed from the kernel
*/
static void __exit ModuleExit(void) {
printk("gpio_irq: Unloading module... ");
free_irq(irq_number, NULL);
gpio_free(499);
gpio_free(498);
}
module_init(ModuleInit);
module_exit(ModuleExit);
Loaded that .ko file to linux kernel using
sudo insmod gpio_irq.ko
With this, I am able to get interrupt and service the routine.
But,
I also want to call another executable from static irq_handler_t gpio_irq_handler(...)
which is located at /home/user_name/Documents/
I know that, this can be done using system()
call as explained in here
But, I am unable add <#include <stdlib.h>
in my Linux Kernel Module. Compiler is throwing error saying that "Fatal Error: stdlib : No such file or directory"
Can someone guide me on how to call executable from Linux Kernel Moudule?
Solution
The problem with your approach is that to load and run an executable requires many syscalls and interrupts. You can't do this from inside an interrupt routine since interrupts are disabled.
A second reason is that the C runtime, including everything in stdlib.h, is a user-space library. None of it is available in the kernel.
A third reason is that loading and running an executable is time-consuming, which is the problem that you want to solve.
Fortunately, there is a simple method developed years ago to solve your problem of minimizing latency between your interrupt and execution of the user-space task.
Start your user space process, which gets all of the startup overhead out of the way, then issue a read
call to your kernel module. This will block until your module responds. The read could return a single byte indicating status. The latency of the read response will be far less than starting an executable (if it were even possible).
Answered By - stark Answer Checked By - Marie Seifert (WPSolving Admin)