Linux内核模块中的定期任务

时间:2011-11-29 11:43:36

标签: linux linux-kernel task kernel-module gpio

目前我正在为friendlyarm Linux 2.6.32.2(mini2440)开发GPIO内核模块。我来自电子背景,不熟悉Linux。

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

首次写入器件文件时,GPIO引脚在50kHz时连续切换。在第二次写它停止翻转。第三次,它再次启动,依此类推。

我编写了单独的内核模块来生成freq。但是在第一次写入设备文件后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;
}

1 个答案:

答案 0 :(得分:9)

你在内核线程中进行无限循环,没有其他任何空间 发生,除了IRQ和其他内核线程。

你可以做的是

  • 在硬件上编程定时器并在中断时切换引脚

  • 用usleep_range替换udelay

我建议逐步做事,并使用usleep_range从kHz范围开始,最后转到cust om timer + ISR

在任何一种情况下,你可能会有很多抖动,并且在DSP或PIC上进行这样的gpio切换可能是一个好主意,但是在ARM + Linux上浪费资源,除非你是硬件辅助的支持pwm的gpio引擎。