¿Cuál es el punto de DMA en las CPU incorporadas?

16

Hace poco estuve haciendo un proyecto con el mbed (LPC1768), usando el DAC para generar varias ondas. Leí partes de la hoja de datos, y hablaba de cómo tenía DMA para muchos de los periféricos. Parecía que sería útil, pero al leer más, encontré que el DMA usaba el mismo bus de datos que la CPU (lo que creo que es normal). ¿Significa esto que la CPU no puede interactuar con ninguna de las memorias mientras el DAC obtiene datos? Además, dado que el DAC no tenía un búfer (por lo que pude ver) y por lo tanto tiene que usar DMA muy a menudo, ¿cuál es el punto de DMA? Si la CPU no puede hacer transacciones de memoria, ¿puede hacer algo?

    
pregunta BeB00

7 respuestas

17

La hoja de datos LPC1768 encontré con las siguientes citas (énfasis mío):

  

Controlador DMA de propósito general (GPDMA) de ocho canales en la multicapa AHB   matriz que se puede utilizar con SSP, I2S-bus, UART, analógico a digital y   Convertidores de digital a analógico, señales de coincidencia de temporizador y para   transferencias de memoria a memoria.

     

El bus dividido APB permite un alto rendimiento con pocas paradas entre la CPU y DMA

El diagrama de bloques en la página 6 muestra SRAM con múltiples canales entre la matriz AHB y la siguiente cita respalda esto:

  

El LPC17xx contiene un total de 64 kB de memoria RAM estática en el chip. Esto incluye el principal   SRAM de 32 kB, accesible por la CPU y el controlador DMA en un bus de mayor velocidad, y dos   16 kB adicionales cada bloque SRAM ubicado en un puerto esclavo separado en el AHB   Matriz multicapa.   Esta arquitectura permite que los accesos de CPU y DMA se distribuyan en tres RAM separadas   que se puede acceder simultáneamente

Y esto se ve reforzado por la siguiente cita:

  

El GPDMA habilita periférico a memoria, memoria a periférico,   periférico a periférico, y memoria a memoria.

Por lo tanto, puede transmitir datos a su DAC desde uno de los bloques SRAM separados o desde un periférico diferente, mientras usa la SRAM principal para otras funciones.

Este tipo de DMA periférico-periférico es común en partes más pequeñas donde la interfaz de memoria es bastante simple (en comparación con un procesador Intel moderno).

    
respondido por el David
29

Lo largo y lo corto es que DMA permite que la CPU se comporte efectivamente a su velocidad nativa, mientras que los periféricos pueden comportarse efectivamente a su velocidad nativa. La mayoría de los números en el ejemplo están compuestos.

Comparemos dos opciones para recopilar periódicamente datos de un ADC:

  1. Puede configurar el ADC como parte de una interrupción (periódica o no)
  2. Puede crear un búfer e indicar al DMA que transfiera las lecturas de ADC al búfer.

Transfamos 1000 muestras del ADC a la RAM.

Usando la opción 1: Para cada muestra hay

  • Se pasan 12 ciclos entrando en interrupción
  • leer adc (s)
  • tienda en ram
  • Se pasan 12 ciclos saliendo de la interrupción

Supongamos que esta función de interrupción es de 76 instrucciones, toda la rutina tiene una longitud de 100 instrucciones, asumiendo la ejecución de un solo ciclo (el mejor de los casos). Eso significa que la opción 1 gastará 100,000 ciclos de tiempo de CPU ejecutándose.

Opción 2: DMA está configurado para recopilar 1000 muestras de ADC. Supongamos que el ADC tiene un disparador de hardware de un contador de temporizador.

  • ADC y DMA transfieren datos de 1000 muestras a ram
  • DMA interrumpe su CPU después de 1000 muestras
  • Se pasan 12 ciclos entrando en interrupción
  • El código sucede (digamos que le dice al DMA que sobrescriba la RAM)
  • Se pasan 12 ciclos saliendo de la interrupción

Pretender toda la interrupción (con sobrecarga de entrada y salida) es de 100 instrucciones de un solo ciclo. Usando DMA, solo pasas 100 ciclos para guardar las mismas 1000 muestras.

Ahora, cada vez que el DMA accede al bus, sí, puede haber una disputa entre la CPU y el DMA. La CPU puede incluso verse obligada a esperar a que el DMA termine. Pero esperar que el DMA termine es mucho más corto que bloquear la CPU para dar servicio al ADC. Si el reloj central de la CPU es 2x Reloj de bus, entonces la CPU podría desperdiciar algunos ciclos de núcleo en espera de que el DMA termine. Esto significa que su tiempo de ejecución efectivo de la transferencia está entre 1000 (suponiendo que la CPU nunca espera) y 9000 ciclos. Aún así es mejor que los 100.000 ciclos.

    
respondido por el pgvoorhees
7

Si en un ciclo dado, el procesador y un controlador DMA necesitarían acceder al mismo bus, uno u otro tendrían que esperar. Sin embargo, muchos sistemas contienen múltiples áreas de memoria con buses separados junto con un "puente" de bus que permitirá a la CPU acceder a una memoria mientras que el controlador DMA accede a otra.

Además, es posible que muchas CPU no necesiten acceder a un dispositivo de memoria en cada ciclo. Si una CPU normalmente solo necesitaría acceder a la memoria en dos de cada tres ciclos, un dispositivo DMA de baja prioridad puede ser capaz de explotar ciclos cuando el bus de memoria estaría inactivo de otra manera.

Sin embargo, incluso en los casos en que cada ciclo DMA causaría que la CPU se detenga durante un ciclo, DMA puede ser muy útil si los datos llegan a una velocidad que sea lo suficientemente lenta como para que la CPU pueda hacer otras cosas entre elementos de datos entrantes, pero lo suficientemente rápido como para minimizar la sobrecarga por artículo. Si un puerto SPI estaba suministrando datos a un dispositivo a una velocidad de un byte cada 16 ciclos de CPU, por ejemplo, interrumpir la CPU para cada transferencia probablemente causaría que pasara casi todo el tiempo entrando y regresando de la rutina de servicio de interrupción y ninguno haciendo cualquier trabajo real. Sin embargo, al usar DMA, la sobrecarga podría reducirse a un 13%, incluso si cada transferencia DMA causara que la CPU se atasque durante dos ciclos.

Finalmente, algunas CPU permiten realizar DMA mientras la CPU está en reposo. Utilizando una transferencia basada en interrupciones requeriría que el sistema se active completamente Por cada unidad de datos transferida. Usando DMA, sin embargo, puede ser posible para el controlador de suspensión para alimentar el controlador de memoria un par de relojes cada el tiempo que entra un byte, pero deja que todo lo demás permanezca dormido, reduciendo así consumo de energía.

    
respondido por el supercat
4

Como programador, DMA es una opción para transferir datos hacia y desde los periféricos que lo admiten. Para el ejemplo clásico de cambiar un búfer grande a través de un periférico en serie como SPI o UART, o recopilar varias muestras de un ADC, tiene tres métodos para mover esos datos:

  1. Método de sondeo. Aquí es donde espera las marcas de registro para permitirle cambiar de entrada / salida al siguiente byte. El problema es que está retrasando toda la ejecución de la CPU mientras espera esto. O, si tiene que compartir el tiempo de CPU en un sistema operativo, entonces su transferencia se reducirá drásticamente.

  2. Método de interrupción. Aquí es donde se escribe una rutina de servicio de interrupción (ISR) que se ejecuta con cada transferencia de bytes y se escribe el código en el ISR que administra la transferencia. Esto es más eficiente para la CPU porque la CPU le dará servicio a su ISR solo cuando sea necesario. Es de uso gratuito en cualquier otro momento, excepto en el ISR. ISR también es una de las opciones más rápidas para realizar la transferencia en términos de velocidad de transferencia.

  3. DMA. Usted configura el DMA con los punteros de origen / destino, la cantidad de transferencias y se apaga. Robará ciclos de bus y tiempo de CPU para realizar la transferencia, y la CPU tiene la libertad de hacer otras cosas mientras tanto. Puede configurar un indicador o una interrupción para indicar cuándo se realiza la transferencia. Por lo general, es un toque más rápido que ISR y generalmente es la opción de transferencia más rápida.

Como programador, prefiero DMA porque es el más fácil de codificar y es esencialmente la técnica más rápida para realizar la transferencia. Por lo general, solo necesita configurar un par de registros para los punteros de origen / destino y la cantidad de transferencias que se deben realizar y apagar. Paso más horas trabajando en el código ISR que en el código acelerado por DMA porque el código ISR requiere habilidades de diseño críticas y tiene que ser codificado, probado, verificado, etc. El código DMA es mucho más pequeño y el código que tengo que escribir yo mismo es relativamente trivial, y estoy obteniendo la máxima velocidad de transferencia en la negociación.

En mi experiencia, últimamente con los procesadores Atmel SAM3 / 4, DMA se ejecuta un poco más rápido que un ISR eficiente de mi propia creación. Tenía una aplicación que leía en una pila de bytes de SPI cada 5 ms. En las tareas en segundo plano ocurrían muchas matemáticas de punto flotante, por lo que quería que la CPU fuera lo más libre posible para esas tareas. La implementación inicial fue ISR, y luego me moví a DMA para comparar e intentar comprar un poco más de tiempo de CPU entre las muestras. La ganancia de velocidad de transferencia se mejoró ligeramente, pero solo un poco. Apenas fue medible en el o-scope.

Esto se debe a que en los microprocesadores recientes que he visto, ISR y DMA funcionan casi de la misma manera: toman los ciclos de la CPU según lo requerido y la DMA está haciendo esencialmente las mismas operaciones con la CPU que yo habría codificado un ISR eficiente.

En casos raros, he visto periféricos que tienen su propia área de RAM a la que SÓLO se puede acceder mediante DMA. Esto fue en Ethernet MAC o USB.

    
respondido por el Smith
3

Lo más probable es que se use DMA aquí para que el DAC pueda tener un tiempo regular, genere una forma de onda cambiando la salida analógica en algún intervalo conocido.

Sí, si es un bus compartido, entonces ... tienes que compartir.

La CPU no siempre está utilizando el bus, por lo que a veces es una buena idea compartir con un motor DMA. Y, por supuesto, eso significa que las prioridades se involucran, a veces es solo quién llegó primero (por ejemplo, tiene un comando fifo frente al recurso, y el número máximo de solicitudes, en el orden en que llegan, sí, eso no sería necesariamente determinista ). En un caso como este, es posible que desee que la dma tenga prioridad sobre la CPU, de modo que las cosas sensibles al tiempo, como los DAC o los ADC, tengan un tiempo determinista. Depende de cómo decidieron implementarlo.

La gente a veces tiene esta suposición a menudo incorrecta de que dma es libre. Todavía no consume tiempo de bus, si se comparte con la CPU (que finalmente es como se comunica con un recurso con el que la CPU puede hablar), entonces la CPU y / o la dma se mantienen apagadas, por lo que la CPU todavía tiene que esperar un poco. En algunas implementaciones (es probable que no sea su microcontrolador), la CPU se retiene completamente hasta que se completa la dma, la CPU se detiene durante el tiempo. Solo depende de la implementación. La parte gratuita es que la CPU no tiene que estar constantemente interrumpida o sondeando o conteniendo la respiración para que algún evento alimente datos. Puede tomarse su tiempo crear el siguiente búfer para dma over. Tiene que estar atento a que se complete la transferencia de dma y lidiar con eso, pero en lugar de decir que cada byte ahora tiene varios bytes, algunos bloques de datos.

No hay una respuesta universal. "Depende" ... del diseño específico de lo que está utilizando. Incluso dentro de un diseño de chip / placa / sistema puede haber múltiples motores de dma y no hay razón para suponer que todos funcionan de la misma manera. Para cada caso tienes que resolverlo, y desafortunadamente, a menudo no lo documentan o lo documentan lo suficientemente bien. Por lo tanto, es posible que tenga que crear algunos experimentos si es una preocupación.

    
respondido por el old_timer
1

Las respuestas hasta ahora hablan acerca de la "velocidad" en la que la CPU puede funcionar y cómo DMA se beneficia de eso. Sin embargo, hay otra consideración, poder .

Si la CPU deseaba enviar un paquete de datos en un enlace lento, tendría que estar despierto la mayor parte del tiempo si usa el sondeo o las interrupciones, sin embargo, la CPU principal puede estar en estado de suspensión mientras DMA se está haciendo.

    
respondido por el Ian Ringrose
0

Algunos procesadores como la serie STM32H7 tienen muchas opciones de memoria RAM y montones de memoria RAM de acoplamiento cerrado. Tener bancos de RAM separados le permite a DMA acumular una gran cantidad de RAM mientras el procesador procesa datos en el ram de acoplamiento cerrado que no requiere almacenamiento en caché y no es golpeado por DMA. Para mover datos alrededor de usted puede usar MDMA. Construí un conjunto de radar FMCW usando uno de estos. Los ADC obtienen datos IQ de dos entradas en una SRAM. Luego, escala los datos y realizo el punto flotante de 256 bbts fft en dtcm ram. Luego FIFO el resultado en una matriz 2d en AXI ram utilizando MDMA.

Tomo un segundo fft 64 bin a través del fifo para el vector de velocidad. Luego hago la magnitud de los datos complejos y envío los datos resultantes 128 & 64 valores de punto flotante a otro H7 usando SPI a 12.5 MHz para la detección. Hago todo esto en 4 ms.

La frecuencia de muestreo de los ADC es de 84 kHz y al utilizar el muestreo excesivo obtengo una resolución de aproximadamente 18 bits.

No está mal para un procesador de propósitos generales que solo se ejecuta en el rango de MHz y sin RAM externa.

También las grandes cachés de este dispositivo han mejorado el rendimiento de cálculos fuera del dtcm también.

    
respondido por el Rob Garnett

Lea otras preguntas en las etiquetas