17 votos

¿Para qué sirve el DMA en las CPUs integradas?

Hace poco estuve haciendo un proyecto con el mbed (LPC1768), usando el DAC para dar salida a varias ondas. Leí partes de la hoja de datos, y hablaba de que tenía DMA para muchos de los periféricos. Esto parecía ser útil, pero al leer más, encontré que el DMA usaba el mismo bus de datos que la cpu (lo cual supongo que es normal). ¿Significa esto que la CPU no puede interactuar con ninguna de las memorias mientras el DAC está recibiendo datos? Además, ya que el DAC no tiene un buffer (por lo que pude ver) y por lo tanto tiene que hacer DMA muy a menudo, ¿qué sentido tiene el DMA? Si la CPU no puede hacer transacciones de memoria, ¿puede hacer algo?

9 votos

Te sugiero que mires las características de tu CPU y si puede hacer algo más que acceder a la memoria. He oído hablar de algunas CPUs que pueden hacer cosas como decisiones o cálculos, no estoy seguro de si esto es común en absoluto..

0 votos

¿Debe la CPU dedicar su tiempo a transferir datos a un puerto de E/S o delegar la tarea en un dispositivo dedicado?

0 votos

Sí, la CPU puede hacer otras cosas, pero en un sistema embebido probablemente pasa mucho tiempo interactuando con periféricos, especialmente puertos de E/S. ¿No tendría más sentido tener un bus de datos extra sólo para DMA? ¿No tendría más sentido tener un bus de datos extra sólo para DMA? ¿O normalmente no es necesario? La situación en la que querrías un bus extra es cuando estás tratando de empujar los límites de tu hardware, que asumo es cuando querrías usar DMA de todas formas.

32voto

dchanson Puntos 29

El resumen 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 del ejemplo son inventados.

Vamos a comparar dos opciones para recoger periódicamente los datos de un ADC:

  1. Se puede configurar el ADC como parte de una interrupción (periódica o no)
  2. Puedes crear un buffer y decirle al DMA que transfiera las lecturas del ADC al buffer.

Vamos a transferir 1000 muestras del ADC a la RAM.

Utilizando la opción 1: Para cada muestra hay

  • Se gastan 12 ciclos para entrar en la interrupción
  • leer adc(s)
  • almacenar en ram
  • Se gastan 12 ciclos al salir de la interrupción

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

Opción 3: El DMA está configurado para recoger 1000 muestras del ADC. Supongamos que el ADC tiene un disparador de hardware de un contador de tiempo.

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

Suponiendo que toda la interrupción (con la sobrecarga de entrada y salida) son 100 instrucciones de un ciclo. Usando DMA, sólo se gastan 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 a que el DMA termine es mucho más corto que bloquear a la CPU para dar servicio al ADC. Si el reloj del núcleo de la CPU es 2 veces el reloj del Bus, entonces la CPU podría desperdiciar algunos ciclos del núcleo esperando que el DMA termine. Esto significa que el tiempo efectivo de ejecución de la transferencia está entre 1000 (asumiendo que la CPU nunca espera) y 9000 ciclos. Aún así, es mucho mejor que los 100.000 ciclos.

2 votos

Es importante tener en cuenta que la RAM no es el único lugar en el que la CPU puede almacenar datos. En general, la CPU carga los datos de la RAM en registros antes de trabajar con ellos.

0 votos

Yah, absolutamente correcto. Mi ejemplo no es más que un esbozo.

0 votos

Muchos microcontroladores disponen también de un bus multicapa que permite realizar operaciones simultáneas. Por ejemplo: adc->ram y flash->register al mismo tiempo. Además, muchas instrucciones duran más de 1 reloj, por lo que hay tiempo de sobra para el DMA.

17voto

Salem Koja Puntos 21

El Hoja de datos del LPC1768 He encontrado las siguientes citas (el énfasis es mío):

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

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

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

El LPC17xx contiene un total de 64 kB de memoria RAM estática en el chip. Esto incluye la memoria principal SRAM de 32 kB, accesible por la CPU y el controlador DMA en un bus de mayor velocidad, y dos bloques SRAM adicionales de 16 kB cada uno situado en un puerto esclavo separado en el AHB matriz multicapa. Esta arquitectura permite que los accesos a la CPU y a la DMA se repartan en tres memorias RAM distintas a las que se puede acceder simultáneamente

Y esto se refuerza con la siguiente cita:

El GPDMA permite la conexión de periférico a memoria, de memoria a periférico, periférico a periférico y memoria a memoria.

Por lo tanto, podrías transmitir datos a tu DAC desde uno de los bloques SRAM separados o desde un periférico diferente, mientras utilizas la SRAM principal para otras funciones.

Este tipo de DMA periférico-periférico es común en piezas pequeñas donde la interfaz de memoria es bastante simple (comparada con, por ejemplo, un procesador Intel moderno).

0 votos

Ahh, gracias, no me di cuenta de que era posible, soy un poco nuevo en DMA. ¿Eso implica que la CPU puede acceder a los periféricos, mientras que el DAC está accediendo a la SRAM separada?

1 votos

Sí, para eso sirve exactamente la matriz AHB. Permite a diferentes controladores (CPU, DMA, ciertos periféricos como ethernet y USB) acceder a diferentes cosas al mismo tiempo. Por eso hay múltiples "puertos" a la SRAM.

0 votos

Sí, el AHB en estas pequeñas criaturas baratas ofrece anchos de banda de memoria demenciales debido a los bancos de memoria paralelos: puedes tener ethernet, USB2 y todo funcionando al máximo rendimiento y la cpu ni siquiera se da cuenta...

10voto

Alex Andronov Puntos 178

Si en un ciclo determinado el procesador y un controlador DMA necesitaran acceder al mismo bus, uno u otro tendría que esperar. Muchos sistemas, sin embargo, 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 el controlador DMA accede a otra.

Además, muchas CPUs pueden no necesitar acceder a un dispositivo de memoria en cada ciclo. Si una CPU normalmente sólo necesita acceder a la memoria en dos de cada tres ciclos, un dispositivo DMA de baja prioridad puede aprovechar los ciclos en los que el bus de memoria estaría inactivo.

Sin embargo, incluso en los casos en los que cada ciclo DMA causaría que la CPU se detuviera durante un ciclo, el DMA puede seguir siendo muy útil si los datos llegan a un ritmo lo suficientemente lento como para que la CPU pueda hacer otras cosas entre los elementos de datos entrantes, pero lo suficientemente rápido como para que la sobrecarga por elemento deba ser minimizada. Si un puerto SPI estaba alimentando datos a un dispositivo a un ritmo de un byte cada 16 ciclos de CPU, por ejemplo, interrumpir la CPU para cada transferencia probablemente haría que pasara casi todo su tiempo entrando y volviendo de la rutina de servicio de interrupción y ninguno haciendo ningún trabajo real. Sin embargo, utilizando DMA, la sobrecarga podría reducirse al 13%, incluso si cada transferencia DMA causara que la CPU se detuviera durante dos ciclos.

Por último, algunas CPUs permiten realizar DMA mientras la CPU está dormida. Utilizando una transferencia basada en interrupciones requeriría que el sistema se despertara completamente para cada unidad de datos transferida. Sin embargo, usando DMA, puede ser posible que el controlador de reposo alimente al controlador de memoria un par de relojes cada cada vez que entra un byte, pero dejar que todo lo demás permanezca dormido, reduciendo así el consumo de energía.

1 votos

Las piezas Cortex-M como el LPC1768 tienen una ruta de memoria distinta desde la flash hasta el decodificador de instrucciones, por lo que, de hecho, las operaciones de registro a registro pueden significar que la CPU puede ejecutar varias instrucciones entre momentos en los que necesita acceder a la memoria de datos.

6voto

Smith Puntos 71

Como programador, DMA es una opción para transferir datos hacia y desde los periféricos que lo soportan. Para el ejemplo clásico de desplazar un gran buffer a través de un periférico serie como SPI o UART, o recoger un número de muestras de un ADC, tienes tres métodos para mover esos datos:

  1. Método de votación. En este método se espera a que las banderas de los registros permitan la entrada/salida del siguiente byte. El problema es que estás deteniendo toda la ejecución de la CPU mientras esperas esto. O, si tienes que compartir el tiempo de la CPU en un sistema operativo, entonces tu transferencia se ralentizará drásticamente.

  2. Método de interrupción. Aquí 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 la ISR que gestiona la transferencia. Esto es más eficiente para la CPU porque la CPU atenderá su ISR sólo cuando sea necesario. Está libre para su uso en todos los demás momentos, excepto en el ISR. El ISR es también una de las opciones más rápidas para hacer la transferencia en términos de velocidad de transferencia.

  3. DMA. Se configura el DMA con los punteros de origen/destino, el número de transferencias y se pone en marcha. Robará ciclos de bus y tiempo de la CPU para realizar la transferencia, y la CPU queda libre para hacer otras cosas mientras tanto. Se puede configurar una bandera o una interrupción para indicar cuando la transferencia ha terminado. Suele ser un poco más rápido que el ISR y suele ser 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 hacer la transferencia. Normalmente, sólo hay que configurar un par de registros para los punteros de origen/destino y el número de transferencias a realizar y ya está. Paso muchas más horas trabajando en código ISR que en 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 de paso consigo la máxima velocidad de transferencia.

En mi experiencia, últimamente con los procesadores SAM3/4 de Atmel, el DMA funciona un poco más rápido que un ISR eficiente de mi propia elaboración. Tenía una aplicación que leía un montón de bytes desde SPI cada 5 mseg. Una gran cantidad de matemáticas de punto flotante estaba ocurriendo en tareas de fondo por lo que quería que la CPU estuviera lo más libre posible para esas tareas. La implementación inicial era ISR, y luego pasé a DMA para comparar y tratar de ganar un poco más de tiempo de CPU entre muestras. La ganancia de velocidad de transferencia mejoró ligeramente, pero sólo por un poco. Apenas era medible en el o-scope.

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

En raros casos, he visto periféricos que tienen su propia área de RAM que era accesible SOLO por DMA. Esto era en MACs Ethernet o USBs.

3voto

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

Sí, si se trata de un autobús compartido... hay que compartirlo.

La cpu no siempre utiliza el bus, por lo que a veces es una buena idea compartir con un motor dma. Y, por supuesto, esto significa que las prioridades se involucran, a veces es sólo quién llegó primero (por ejemplo, tener un comando fifo en frente del recurso, y las solicitudes fifo up, en el orden en que llegan, sí que sería no-necesariamente-determinista). En un caso como este puedes querer que la dma tenga prioridad sobre la cpu para que las cosas sensibles al tiempo como los DACs o ADCs tengan un tiempo determinista. Depende de cómo hayan decidido implementarlo.

La gente a veces tiene esta suposición, a menudo incorrecta, de que la dma es gratuita. No lo es, sigue consumiendo tiempo de bus, si se comparte con la cpu (que eventualmente lo es, ya que habla con un recurso con el que la cpu puede hablar) entonces la cpu y/o la dma se detienen, por lo que la cpu todavía tiene que esperar algún tiempo, en algunas implementaciones (probablemente no su microcontrolador) la cpu se detiene por completo hasta que la dma se completa, la cpu se detiene por la duración. Solo depende de la implementación. La parte libre de esto es que la cpu no tiene que estar constantemente siendo interrumpida o sondeando o conteniendo la respiración por algún evento para alimentar los datos. Puede tomarse su tiempo para crear el siguiente búfer para dma. Tiene que mirar para la transferencia dma para completar y tratar con eso, pero en lugar de decir cada byte es ahora múltiples bytes, algún bloque de datos.

No hay una respuesta universal. "Depende"... del diseño específico de la cosa concreta que estés utilizando. Incluso dentro de un diseño de chip/placa/sistema puede haber múltiples motores dma y no hay razón para asumir que todos funcionan de la misma manera. Para cada caso tienes que averiguarlo, y desafortunadamente, a menudo no lo documentan o lo hacen lo suficientemente bien. Así que puede que tengas que crear algunos experimentos si es una preocupación.

0 votos

El punto de dma es ganar rendimiento posiblemente haciendo trabajo para la cpu para que no tenga que tener código, y para aprovechar ciclos de bus normalmente no utilizados y hacer trabajo allí. También para cosas como en su pregunta de la alimentación de datos en el momento adecuado, idealmente sin sobrecarga de la CPU. estas ventajas son útiles incrustado o no.

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