2011-11-29 17 views
10

Actualmente estoy desarrollando el módulo de kernel de GPIO para friendlyarm Linux 2.6.32.2 (mini2440). Soy de origen en electrónica y nuevo en Linux.Tarea periódica en un módulo de kernel de Linux

El módulo kernel cargado al inicio y el archivo del dispositivo relacionado se encuentra en /dev como gpiofreq.

Al escribir por primera vez en el archivo del dispositivo, el pin GPIO alterna continuamente a 50 kHz. En la segunda vez que lo escribes, deja de alternar. En tercer lugar, comienza de nuevo, y así sucesivamente.

He escrito un módulo kernel por separado para generar freq. pero la CPU se congela después de escribir el archivo del dispositivo por primera vez. Se muestra el mensaje de la terminal pero no puedo ejecutar ningún comando después.

Aquí es el código de fragmento:

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

Aquí está el código de escritura del dispositivo, el cual iniciar o detener con datos grabados en el archivo de dispositivo.

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

* ¿Por qué * quieres que tu tarea se ejecute por completo * dentro del kernel *? La sabiduría común es tener un proceso de ayudante de nivel de usuario ... –

+0

porque quiero la frecuencia de hasta 100kHz. Ya probé un script de shell que me da una frecuencia de conmutación de alrededor de 750 Hz. y también un programa c que me da un máximo de 900 Hz. ambos realizan la operación de escritura '1' y '0' en el archivo del dispositivo "/ sys/class/gpio/gpio192/value". –

+0

No creo que puedas alcanzar una frecuencia tan alta sin consumir muchos recursos. – shodanex

Respuesta

9

Usted está haciendo un bucle infinito en un hilo del núcleo, no hay espacio para nada más a suceder, excepto IRQ y tal vez otro hilo del núcleo.

Lo que podría hacer es cualquiera de los programas

  • un temporizador en su hardware y hacer su alternancia alfiler en una interrupción

  • reemplazar udelay con usleep_range

Sugiero hacer cosa progresivamente, y comenzando en el rango de kHz con usleep_range, y eventualmente moviéndose a cust om timer + ISR

en cualquier caso, es probable que tenga mucha inestabilidad, y hacer tal gpio alternar puede ser una buena idea en un DSP o un PIC, pero es un desperdicio de recursos en ARM + Linux, a menos que sea asistido por hardware con pwm capaz gpio motor.

+0

También puede ser necesario recompilar el núcleo con un valor 'CONFIG_HZ' significativamente mayor para aumentar la velocidad de la interrupción del temporizador. – caf

Cuestiones relacionadas