¿Cómo generar una señal de reloj de ~ 100 kHz en el módulo del kernel Liunx con bit-banging?

Estoy tratando de generar una señal de reloj en el pin GPIO (plataforma ARM, mach-davinci, kernel 2.6.27) que tendrá algo arrojado a 100kHz. Usando tasklet con alta prioridad para hacer eso. La teoría es simple, configure gpio alto, udelay para 5us, configure gpio bajo, espere otros 5us, pero aparecen problemas extraños. En primer lugar, no puedo obtener este 5us de dalay, pero está bien, parece un problema de rendimiento de hw, así que cambié a period = 40us (da ~ 25kHz). El segundo problema es el peor. Una vez cada ~ 10 ms, udelay espera 3 veces más de lo habitual. Estoy pensando que esta vez se está tomando un tiempo, pero esto es inaceptable desde el punto de vista del protocolo (que se implementará además de esto). ¿Hay alguna forma de desactivar temporalmente el procedimiento de latido del corazón, digamos, durante 500 ms? ¿O quizás lo estoy haciendo mal desde el principio? ¿Algún comentario?

preguntado el 08 de enero de 11 a las 17:01

No estoy seguro de que lo entiendo. ¿Estás escribiendo un tasklet que estaría ocupado esperando en un bucle infinito? -

Básicamente sí, pero no infinito, necesito ese reloj para, digamos, 500 ms, debería estar aún más cerca de 300 ms. Sí, soy consciente de que bloqueará todo, pero ¿qué opción tengo? ;) -

3 Respuestas

No puede utilizar tasklet para este tipo de trabajo. Los Tasklets pueden ser reemplazados por interrupciones. En algunos casos, su tasklet puede incluso ejecutarse en el contexto del proceso.

Si es absolutamente necesario que lo haga de esta manera, use un controlador de interrupciones: entre, deshabilite las interrupciones, haga lo que tenga que hacer y salga lo más rápido que pueda.

Respondido el 08 de enero de 11 a las 20:01

Oh ... Tu descripción es muy diferente a lo que he leído, pero todo dice que tienes derecho, ¡gracias por la ayuda! - Encuesta

Generar el reloj de forma asíncrona en el software no es lo correcto. Puedo pensar en dos alternativas que funcionarán mejor:

  1. Es posible que su procesador tenga un periférico generador de reloj integrado que el kernel u otro controlador aún no esté utilizando. Cuando configura uno de estos, le dice qué tan rápido debe ejecutar su reloj, y simplemente comienza a agotarse los pulsos.

    Obtén la hoja de datos de tu procesador y estúdiala.

    Es posible que no encuentre un periférico llamado "reloj" per se, pero puede encontrar algo similar que pueda poner en servicio, como un periférico PWM.

  2. Es posible que el otro dispositivo con el que está hablando no requiera un reloj regular. Algunos chips que necesitan una línea de "reloj" simplemente necesitan una línea que sube cuando hay un bit para leer, que luego baja mientras las líneas de datos cambian. Si este es el caso, el valor de 100 kHz que está leyendo no es un requisito estricto para un reloj de exactamente esa frecuencia, es solo un límite superior en la velocidad de la línea del reloj (y por lo tanto, la (s) línea (s) de datos) se les permite hacer la transición.

    Con una CPU mucho más rápida que el reloj, debes dividir esto en dos mitades:

    • La "mitad superior" establece el estado de la (s) línea (s) de datos correctamente, luego trae la línea del reloj. Luego, programa la mitad inferior para que se ejecute 5 μs más tarde, utilizando una interrupción o un temporizador de kernel.

    • En la "mitad inferior", llamada por la interrupción o el temporizador, baje la línea del reloj y luego programe la mitad superior para que se ejecute de nuevo 5 μs más tarde.

Respondido el 12 de enero de 11 a las 01:01

A menos que pueda ejecutar su tasklet del temporizador con mayor prioridad que el temporizador del kernel, siempre será susceptible a este tipo de jitter. ¿Realmente tienes que hacer esto mediante la agrupación de bits? Sería mucho más fácil utilizar un temporizador de hardware o un generador PWM. Configure el temporizador para que funcione a la velocidad deseada, configure el pin en salida y listo.

Si necesita control de software en cada período de bit, puede intentar solucionar las otras tareas configurando su tasklet para que se ejecute en un período corto, digamos tres cuartos de su retraso de 40 us. En el tasklet, deshabilite las interrupciones y sondee el reloj hasta que llegue al intervalo de tiempo correcto de 40 us, configure el estado de E / S, vuelva a habilitar las interrupciones y salga. Pero esto efectivamente tipifica el 25% de su sistema al mirar un reloj.

Respondido el 08 de enero de 11 a las 20:01

La forma más fácil de hacerlo será tomar alguna interfaz de hardware para hacer el trabajo, como USART o algo, desafortunadamente, todo está tomado :( - Encuesta

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.