【问题标题】:Periodic task in a Linux kernel moduleLinux内核模块中的周期性任务
【发布时间】:2012-01-08 18:08:47
【问题描述】:

目前我正在为友好的 Linux 2.6.32.2 (mini2440) 开发 GPIO 内核模块。我来自电子背景,是 Linux 新手。

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

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

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

这里是代码-sn-p:

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

【问题讨论】:

  • 为什么您希望您的任务完全在内核中运行?普遍的看法是拥有一个用户级的助手进程......
  • 因为我希望频率高达 100kHz。我已经尝试了一个 shell 脚本,它给了我大约 750 Hz 的切换频率。还有一个 c 程序,它给我最大 900 Hz。两者都对“/sys/class/gpio/gpio192/value”设备文件执行写“1”和“0”操作。
  • 我不认为你会在不消耗大量资源的情况下达到如此高的频率。

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


【解决方案1】:

您正在内核线程中执行无限循环,没有其他空间 会发生,除了 IRQ 和其他内核线程。

你可以做的是要么

  • 在您的硬件上编写一个计时器并在中断中切换您的引脚

  • 将 udelay 替换为 usleep_range

我建议循序渐进,从 kHz 范围开始使用 usleep_range,最终转向 cust om timer + ISR

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

【讨论】:

  • 您可能还需要使用明显更高的CONFIG_HZ 值重新编译内核,以提高定时器中断的速率。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 2013-12-17
  • 2013-08-09
  • 1970-01-01
  • 2019-02-20
相关资源
最近更新 更多