LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-16-2011, 05:13 PM   #1
bfyviolin
LQ Newbie
 
Registered: Feb 2010
Posts: 15

Rep: Reputation: 0
how to run user program from a kernel device driver


Hi.
I have a ARM dev board. It provides several buttons and sample driver codes. When i press one button, it call "printk" to print messages like "xx button is pressed" on the console.

The question is how can i notice my program running in the user mode? can i send a signal in the button driver to user processes? or can i start a user mode process intead of print a message on the console?

As all known, many C lib funcs and linux sys calls not available in kernel mode, such as, we must use printk rather than printf which is in C lib. What can I do to finish my job ?

Thanks.
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 08-16-2011, 06:21 PM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
It depends on what you want the buttons to do.

You need an input driver for your device. If your device is not too rare, it most probably has such a driver written for it already; otherwise you can create or modify an existing one that is close enough to your device. You (the programmer) can choose which event or events (keyboard key, mouse button, or other human interface thingy) the buttons produce, quite freely. This way all existing applications will support the buttons (assuming you pick input events the applications recognize). You can also choose rare or custom events, so that applications will ignore the event, but your own applications can detect it very easily, using the normal input event system.

There are other routes you could take, but the above is the easiest, and will yield the best results in most situations. After all, the buttons are an input device, right?
 
Old 08-16-2011, 08:09 PM   #3
bfyviolin
LQ Newbie
 
Registered: Feb 2010
Posts: 15

Original Poster
Rep: Reputation: 0
We already have the gpio driver for the button, it need a handler func to be registered to handle the event:
Quote:
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/irq.h>
#include <linux/gpio.h>

#define GPIO_BTN 38
static irqreturn_t gpio_btn_handler(int irq, void *dev_id);
static void __init gpio_btn(void)
{
int error; int irq;
orion_gpio_set_valid(GPIO_BTN, GPIO_INPUT_OK);

error = gpio_request(GPIO_BTN, "gpio_btn");
if ( error<0 ) { pr_err("gpio_btn: failed to request GPIO %d, error %d \n",GPIO_BTN, error); }

error = gpio_direction_input(GPIO_BTN);
if ( error<0 )
{ pr_err("gpio_btn: failed to configure input for GPIO %d, error %d \n",GPIO_BTN, error); }

irq = gpio_to_irq(GPIO_BTN);
if ( irq < 0)
{ pr_err("gpio_btn: Unable to get irq number for GPIO %d, error %d \n",GPIO_BTN, irq); }

error = request_irq(irq, gpio_btn_handler, IRQF_TRIGGER_RISING, "gpio_btn", NULL);
if ( error )
{ pr_err("gpio_btn: failed to request_irq for GPIO/irq %d %d, error %d \n",GPIO_BTN,irq, error); }

printk("gpio_btn is called sucessfully! \n");
}

// we want to start our own program here.
// it seems that we cannot use system() function to start a new process in kernel mode.
// many C functions like printf are not available in kernel mode
// any other way to solve the problem ???
static irqreturn_t gpio_btn_handler(int irq, void *dev_id)
{
printk(" the gpio is triggered, the irq is %d !\n",irq);
return 1;
}

void __exit gpio_exit(void)
{
//we can leave it empty;
}
module_init(gpio_btn);
module_exit(gpio_exit);
//first copy this file into kernel souce tree "drivers/char"; then add the statements "obj-y +=gpio_btn.o" into the file "drivers/char/Makefile"
//after building the kernel, the source code can be built into the kernel.
 
Old 08-16-2011, 08:12 PM   #4
bfyviolin
LQ Newbie
 
Registered: Feb 2010
Posts: 15

Original Poster
Rep: Reputation: 0
source code

Code:
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/irq.h>
#include <linux/gpio.h>

#define GPIO_BTN 38
static irqreturn_t gpio_btn_handler(int irq, void *dev_id);
static void __init gpio_btn(void)
{
	int error;  int irq;
	orion_gpio_set_valid(GPIO_BTN, GPIO_INPUT_OK);

	error = gpio_request(GPIO_BTN, "gpio_btn");
	if ( error<0 ) { pr_err("gpio_btn: failed to request GPIO %d, error %d \n",GPIO_BTN, error); }

	error = gpio_direction_input(GPIO_BTN);
	if ( error<0 ) 
	{ pr_err("gpio_btn: failed to configure input for GPIO %d, error %d \n",GPIO_BTN, error); }

	irq = gpio_to_irq(GPIO_BTN);
	if ( irq < 0) 
	{ pr_err("gpio_btn: Unable to get irq number for GPIO %d, error %d \n",GPIO_BTN, irq); }

        error = request_irq(irq, gpio_btn_handler, IRQF_TRIGGER_RISING, "gpio_btn", NULL);
	if ( error ) 
	{ pr_err("gpio_btn: failed to request_irq for GPIO/irq %d %d, error %d \n",GPIO_BTN,irq, error); }

	printk("gpio_btn is called sucessfully! \n");
}

// we want to start our own program here.
// it seems that we cannot use system() function to start a new process in kernel mode.
// many C functions like printf are not available in kernel mode
// any other way to solve the problem ???
static irqreturn_t gpio_btn_handler(int irq, void *dev_id)
{
	printk("  the gpio is triggered, the irq is %d !\n",irq);
	return 1;
}

void __exit gpio_exit(void)
{
	//we can leave it empty; 
}
module_init(gpio_btn);
module_exit(gpio_exit);
//first copy this file into kernel souce tree "drivers/char"; then add the statements "obj-y +=gpio_btn.o" into the file "drivers/char/Makefile"
//after building the kernel, the source code can be built into the kernel.
 
Old 08-16-2011, 10:59 PM   #5
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
The comments state that you want the kernel to run a userspace application whenever the button is pressed.

Normally this is solved the other way around. You have a small userspace daemon, which listens to the kernel, and when a button event occurs, the userspace daemon starts the application. You can communicate via the input system, a procfs (/proc/) or sysfs (/sys/) file, or via a character device. A character device is likely the best option here.

If you use a character device, then you can use a blocking read in the userspace daemon. Basically, there will be no data coming from the device, until the button is pressed (or released). I recommend you use a fixed-size record, with the value completely describing the button event -- this lets you expand the functionality later if needed. Having the event record be e.g. 8 bytes is probably a good idea. This way, the daemon will block at reading from the input device, not consuming any CPU time, unless something interesting happens. Such a daemon can be written to be very, very small, so it'll consume very little RAM too.

Depending on the userspace application, you might wish to merge it with the daemon, so that it is always present, just not consuming CPU time unless a button is pressed.

For example character device driver code, I recommend the Linux Kernel Module Programming Guide, especially chapters 4.1 Character device drivers and 9.1 Blocking Processes. For maximum compatibility, I recommend you let the kernel decide the device major when registering the character device in your kernel module.
 
2 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Device driver program vivignesh Linux - Embedded & Single-board computer 8 07-19-2010 02:12 AM
Problem in compiling a device driver program p.arun Linux - Kernel 4 01-23-2008 01:14 AM
device driver program swamy suresh Programming 1 06-08-2007 09:39 AM
Run program as another user st00 Linux - Software 4 03-19-2007 06:10 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:28 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration