Jay*_*iya 10 linux task kernel-module linux-kernel gpio
目前我正在为friendlyarm Linux 2.6.32.2(mini2440)开发GPIO内核模块.我来自电子背景,是Linux新手.
启动时加载的内核模块和相关的设备文件位于/devas 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;
}
Run Code Online (Sandbox Code Playgroud)
这是设备写入代码,它使用写入设备文件的任何数据启动或停止.
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;
}
Run Code Online (Sandbox Code Playgroud)
你在内核线程中进行无限循环,除了IRQ和其他内核线程之外,没有其他任何事情可以发生.
你能做的也是
在硬件上编程定时器,并在中断时切换引脚
用usleep_range替换udelay
我建议逐步做事,并使用usleep_range从kHz范围开始,最后转到cust om timer + ISR
在任何一种情况下,你可能会有很多抖动,并且在DSP或PIC上进行这样的gpio切换可能是一个好主意,但是在ARM + Linux上浪费资源,除非你是硬件辅助的pwm功能gpio发动机.