6 votos

Detección de desbordamiento DMA en generación de forma de onda arbitraria

Estoy generando una compleja serie de pulsos en un STM32F103, esencialmente, como se describe en el ST de la aplicación nota AN4776 Generales-temporizador de propósito el libro de cocina dela sección 5.3. Como un resumen rápido, eso significa que estoy usando el temporizador de la DMA modo de ráfaga para la transferencia de nuevos valores para el ARR, RCR y CCR1 después de cada evento de actualización del temporizador. Una descripción más detallada se proporciona en la final de la pregunta, en caso de que usted no está familiarizado con la aplicación de la nota.

Mi problema está relacionado con la DMA ancho de banda: los pulsos de generar, en principio, puede ser arbitrariamente estrechamente espaciados, incluyendo a sólo 1 ciclo de reloj (el temporizador tiene un prescaler de 1). Por supuesto, en este caso, la DMA no es posible llegar a tiempo a la transferencia de los datos para el siguiente pulso, y no habrá problema en la salida. Desde mi aplicación se puede tolerar pequeñas poco frecuentes errores de temporización, me preprocesar mi pulsos que el más pequeño intervalo del pulso es algunos mínimo fijo (estoy usando 96 impulsos de reloj en el momento) para dar la DMA una oportunidad. Sin embargo, todavía estoy recibiendo fallos que creo que son debido a la DMA, y aumentar el mínimo de tiempo, incluso para números muy grandes no parecen ayudar.

La parte clave de la frase anterior es "...yo creo que...". Así que me gustaría encontrar una manera segura de saber si la DMA ha perdido es la transferencia o no, de preferencia algo que me puede dejar en el código que se ejecuta siempre, así que me voy a encontrar muy poco frecuentes errores.

Lo he pesar de/probado este momento es:

  1. Mirando el DMA de error se registra. Sin embargo, no parece ser una "transferencia perdidas" bandera o algo similar, lo cual tiene sentido ya que la mayoría del tiempo no es un error si la transferencia está pendiente por un tiempo. También, aunque en mi caso no es necesariamente un error si la transferencia está pendiente por un tiempo, así que supongo que esto no va a ayudar a mí.
  2. Me estoy quedando este en dos diferentes temporizadores, TIM8 y TIM1, la salida de pulsos en dos diferentes pines. Las secuencias de pulsos estoy preparando son siempre 0.5 ms de largo en total (para que yo pueda reaccionar a los eventos externos dentro de 1.5 ms), es decir, hay una inactividad de pulso si es necesario, de tal manera que uno de los temporizador de actualizaciones que sucede exactamente en el 0,5 ms límite. El TIM8 es el maestro, y que en realidad el tiempo de mi bucle principal por la espera de la cola de DMA para estar en el 0,5 ms límite, que es, a la espera para un valor específico de la DMA CNDTR registro (lo he comprobado por el osciloscopio, alternando un pin en el bucle principal, que esto funciona y es preciso). Ahora, cuando he llegado al momento correcto, de acuerdo a TIM8, sé exactamente donde la TIM1 cola debe ser, por lo que puedo comprobar su CNDTR. La razón por la que creo que hay problemas es que esta comprobación falla algunas veces (una vez cada pocos minutos, por lo que a menudo humanos de las escalas de tiempo, muy rara vez, en términos de número de pulsos).
  3. Lo que estoy trabajando ahora: puedo configurar otro temporizador como referencia, y el uso de su captura canal para obtener el valor de la referencia de temporizador cuando TIM8 de actualización de la señal es afirmada. La captura de valor siempre debe ser exactamente uno de los pulsos de los instantes, y sobre todo que puede comprobar la última capturado valor en el bucle principal en el 0,5 ms límites. El uso de otro temporizador, puedo hacer la misma comprobación en TIM1. La desventaja aquí es que no hay todavía bastante garantía de que las transferencias se han completado, ya que los registros en los principales temporizador se actualizan en el fin de ARR, RCR, CCR1. Así que si ARR ha sido actualizado, pero CCR1 se perdió, el pulso de los instantes de ellos sería correcto, incluso a pesar de la salida de pulso longitudes de no ser.

Por supuesto, los problemas que estoy viendo podría ser debido a un error en el código que se está generando la buffers de la DMA es la de enviar a los temporizadores. Pero eso es exactamente por lo que me gustaría saber para seguro de si es o no la DMA es que faltan algunas transferencias, así que me gustaría saber si estoy a la caza de un error en mi código o no. El código en sí no pase de un razonablemente amplio conjunto de pruebas unitarias, por lo que el error sería un sutil si es que hay.

Así, todas las ideas sobre la comprobación de si mi problema es debido a la DMA se pierde o no?

Los detalles de lo que estoy haciendo exactamente:

Estoy generando una serie de pulsos, cada uno determinado por la longitud de la "en" fase (anchura de impulso) y el tiempo (en impulsos de reloj) hasta el siguiente pulso. En términos de estructuras de datos

struct pulse {


     /*
     * These are an image of the timer registers.
     * We don't use repeats but it must be there
     * since the DMA transfers it anyway
     *
     * TODO: support other capture/compare channels than 1
     */


    uint32_t length; //ARR
    uint32_t repeats; //RCR, we don't use this
    uint32_t pulsewidth; //CCR1
};

//Check that pulse is of the correct type for the DMA stream
static_assert(std::is_pod<pulse>::value, "pulse must be POD");
static_assert(sizeof(pulse) == 12, "pulse must not be packed");

pulse pulseArray[MAX_PULSES];

Entonces, el modo de ráfaga de TIM8 (y en consecuencia, TIM1) nos permite establecer el siguiente esquema:

  1. El canal DMA de que el temporizador está programado para moverse de pulseArray a la TIM8_DMAR "DMA dirección para la transferencia completa" registro, en la circular de modo (así que por supuesto, tienen que seguir llenando con nuevos datos en una forma similar circular de la moda)
  2. el TIM8_DCR "DMA registro de control" está programado con la longitud de la ráfaga 3, y la dirección de la base TIM8_ARR (ver hoja de datos RM0008 página 360-361 para obtener una descripción detallada de estos registros), y la DMA solicitud de actualización se activa a través del TIM8_DIER de 8 bits
  3. Ahora, en cada actualización del contador de tiempo, debido a la ráfaga de modo programado anteriormente, el temporizador se activa la DMA solicitud de 3 veces la transferencia, en este orden, los campos length, repeatsy pulsewidth, y el modo de ráfaga dirige estas a TIM8_ARR, TIM8_RCR y TIM8_CCR1 registros. Ya hemos habilitado la precarga en tanto el temporizador de sí mismo (TIM8_CR1 bit 7) y la compare canal (TIM8_CCMR1 bit 3), los datos se transfieren a la precarga del registro, y participar activamente en la próxima actualización (es decir, cuando el pulso de la corriente completa)

La figura 30 y 33 en la aplicación de la nota son muy iluminadoras en la comprensión de la anterior.

Y ahora puedo afirmar que el problema en un poco más de detalle: suponga length es, por ejemplo, 1. A continuación, la cantidad de ciclos de reloj disponibles para la DMA para transferir el siguiente pulso (que en realidad es de 2 posiciones por delante en el búfer debido a la precarga de los registros, pero no es lo importante aquí) es un (suponiendo temporizador prescaler es 1, el cual es en este caso). Obviamente es imposible que la DMA para la transferencia de 3 palabras de 16 bits en un solo ciclo de reloj, y por lo tanto los valores de la anterior ciclo se repetirá. Permite llamar un "DMA miss", a falta de un término mejor.

Por otro lado, debe haber un mínimo length tal que durante cualquier pulso más que eso, la DMA tendrá tiempo para transferir todos los datos. Por desgracia, este mínimo length depende de la exacta autobús tiempos, otros DMA de tráfico y sus prioridades, por lo que es muy difícil determinar que la longitud de la pluma y el papel.

Así que me gustaría encontrar una manera de detectar, con la mayor certeza posible, que un "DMA miss" no ha sucedido, así que puedo afinar mi mínimo length, y al mismo tiempo estar seguro de que algunos otros artefactos estoy viendo no son debido a una "DMA se pierda".

0voto

user21359 Puntos 133

Cuando usted tiene un conjunto complejo de traslapan cuestiones de tiempo, su mejor apuesta es establecer un hipervisor, un 'jefe de jefes'. Se está creando un 4 en la fase maestro de semáforo que se repite el conteo de 0 a 3 años sin cesar.

Yo los llamo a la Fase a, B, C, D. actúan como facilitadores para subprocesos específicos a ejecutar. Linux y Android tienen este integrado. Lo he utilizado en LabView y el MPLAB. Cualquier proyecto complejo tiene un 4 en la fase del reloj de tiempo de eventos. Un facto de la RTC.

En el peor, de algún fragmento de código tiene que esperar su turno, pero no tiene ningún conflicto cuando se ejecuta.

Fases:

A. Lectura de registro de la ejecución anterior, a continuación, configurar condicional comprueba y preset/reset crucial valores. Ventana abierta para ISR a ejecutar durante la fase de Un solo.

B. Ejecutar crucial determinista código siguiente. Leer los resultados de la ISR. Esto determina que algunos de lo que corre siguiente, dependiendo de los ciclos de reloj consumido y prioridad. Los controladores de Error se ejecutan primero.

C. Ejecutar código principal, basado en los resultados de la fase a y B. Esto incluye la reanudación o a partir de DMA ráfaga modos, ahora que tiene ranuras de tiempo basado en la fase C en tiempo de ejecución. Escribir código, así que comprueba DMA banderas antes de la fase C de tiempo de espera.

D. Detener las transferencias de DMA. De comprobación de errores. Comprobar la 'sombra' de los temporizadores. Cheque por más de carreras o si el tiempo para un corto DMA ráfaga para completar un paquete. Hacer CRC y cualquier error banderas, ahora que usted tiene una ranura de tiempo para ellos. Esto es donde usted encuentra un error de miss pareados DMA frente a una sombra contador, etc.

Dejar un registro o código numérico como para pasar/fallar estado y que está bien para la fase B para ejecutar ruta normal o un controlador de errores.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X