2011-11-29 29 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