2011-11-29 74 views
10

目前我正在为friendlyarm Linux 2.6.32.2(mini2440)开发GPIO内核模块。我来自电子背景和Linux新手。Linux内核模块中的定期任务

在启动时加载的内核模块和相关设备文件位于/dev,作为gpiofreq

第一次写入器件文件时,GPIO引脚在50kHz连续切换。在第二次写它停止切换。第三次,它重新开始,依此类推。

我写了独立的内核模块来生成频率。但是第一次写入设备文件后CPU会冻结。显示终端提示符,但之后我无法运行任何命令。

以下是代码-片段:

//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; 
} 

这里是设备写入代码,其中 开头或写入设备文件中的任何数据停止。

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; 
} 
+2

*为什么*你想让你的任务完全运行*内核*?常见的智慧是有一个用户级的帮手过程.... –

+0

,因为我想freq高达100kHz。我已经尝试了一个shell脚本,它使我的切换频率在750赫兹左右。也是一个c程序,它给了我最大900赫兹。都在“/ sys/class/gpio/gpio192/value”设备文件上执行写入'1'和'0'操作。 –

+0

我不认为如果不消耗大量资源,您将无法达到如此高的频率。 – shodanex

回答

9

你正在做一个内核线程无限循环,没有足够的空间为别的 发生,除了IRQ也许其他的内核线程。

你可以做的要么是

  • 程序您的硬件定时器,做你的引脚切换在中断

  • 与usleep_range取代udelay的

我建议做逐渐地,并且从usleep_range开始在kHz范围内,并最终移动到客户定时器+ ISR

无论哪种情况,您都可能会产生很多抖动,在DSP或PIC上执行这种gpio切换可能是一个好主意,但是这会浪费ARM + Linux上的资源,除非您有硬件协助pwm能力的gpio引擎。

+0

您可能还需要使用明显更高的CONFIG_HZ值重新编译内核以提高定时器中断的速率。 – caf