Currently I am developing GPIO kernel module for friendlyarm Linux 2.6.32.2 (mini2440). I am from electronics background and new to Linux.
The kernel module loaded at start-up and the related device file is located in /dev
as gpiofreq
.
At first time writing to device file, GPIO pin toggles continuously at 50kHz. At second time writing it stop toggling. At third time, it starts again, and so on.
I have wrote separate kernel module to generate freq. but CPU freezes after writing device file at first time. The terminal prompt is shown but I can not run any command afterwards.
Here is the code-snippet:
//calling function which generates continuous freq at gpio static int send_freq(void *arg) { set_current_state(TASK_INTERRUPTIBLE); for(;;) { gpio_set_value(192,1); udelay(10); gpio_set_value(192,0); udelay(10); } return 0; }
Here is the device write code, which start or stop with any data written to device file.
if(toggle==0) { printk("Starting Freq.n"); task=kthread_run(&send_freq,(void *)freq,"START"); toggle=1; } else { printk("Operation Terminated.n"); i = kthread_stop(task); toggle=0; }
Advertisement
Answer
You are doing an infinite loop in a kernel thread, there is no room for anything else to happen, except IRQ and maybe other kernel thread.
What you could do is either
program a timer on your hardware and do your pin toggling in an interrupt
replace udelay with usleep_range
I suggest doing thing progressively, and starting in the kHz range with usleep_range, and eventually moving to cust om timer + ISR
in either case, you will probably have a lot of jitter, and doing such gpio toggling may be a good idea on a DSP or a PIC, but is a waste of resources on ARM + Linux, unless you are hardware assisted with pwm capable gpio engine.