Linux内核模块中的定期任务

目前我正在为friendlyarm Linux 2.6.32.2(mini2440)开发GPIO内核模块。 我从电子背景和新的Linux。

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

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

我已经写了独立的内核模块来生成频率。 但是第一次写入设备文件后CPU会冻结。 terminal提示显示,但我不能运行任何命令后。

这里是代码片段:

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

在内核线程中,你正在做一个无限循环,除了IRQ和其他内核线程之外,没有其他可以发生的地方了。

你能做什么也是

  • 在您的硬件上编程一个定时器,并在中断时切换您的引脚

  • 用usleep_range替换udelay

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

无论哪种情况,您都可能会产生很多抖动,在DSP或PIC上执行gpio切换可能是一个好主意,但在ARM + Linux上会浪费资源,除非您使用具有pwm功能的gpio发动机。