Estaba haciendo un proyecto recientemente 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 periféricos. Esto parecía ser útil, pero en una lectura posterior, descubrí que el DMA usaba el mismo bus de datos que la CPU (lo que supongo que es normal). ¿Significa esto que la CPU no puede interactuar con ninguno de los recuerdos 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 DMA muy a menudo, ¿cuál es el punto de DMA? Si la CPU no puede hacer transacciones de memoria, ¿puede hacer algo?
microcontroller
mbed
dma
BeB00
fuente
fuente
Respuestas:
La hoja de datos LPC1768 que encontré tiene las siguientes citas (énfasis mío):
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:
Y esto se ve reforzado por la siguiente cita:
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).
fuente
Lo largo y corto es que DMA permite que la CPU se comporte de manera efectiva 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 datos periódicamente de un ADC:
Transfieramos 1000 muestras del ADC a la RAM.
Usando la opción 1: Para cada muestra hay
Supongamos que esta función de interrupción tiene 76 instrucciones, toda la rutina tiene 100 instrucciones de largo, suponiendo la ejecución de un solo ciclo (el mejor de los casos). Eso significa que la opción 1 pasará 100.000 ciclos de tiempo de CPU ejecutándose.
Opción 2: DMA está configurado para recolectar 1000 muestras de ADC. Supongamos que el ADC tiene un activador de hardware de un contador de temporizador.
Fingir toda la interrupción (con sobrecarga de entrada y salida) son 100 instrucciones de ciclo único. Con DMA, solo gasta 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 incluso puede verse obligada a esperar a que termine el DMA. Pero esperar a que termine el DMA 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 puede desperdiciar algunos ciclos principales esperando que termine el DMA. Esto significa que su tiempo de ejecución efectivo de la transferencia está entre 1000 (suponiendo que la CPU nunca espere) y 9000 ciclos. Todavía MUCHO mejor que los 100,000 ciclos.
fuente
Si en un ciclo dado el procesador y un controlador DMA tendrían que 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á que la CPU acceda 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 necesita acceder a la memoria en dos de los tres ciclos, un dispositivo DMA de baja prioridad puede explotar los ciclos cuando el bus de memoria estaría inactivo.
Incluso en los casos en que cada ciclo de DMA causaría que la CPU se detenga durante un ciclo, sin embargo, DMA puede ser muy útil si los datos llegan a una velocidad lo suficientemente lenta como para que la CPU pueda hacer otras cosas entre los elementos de datos entrantes. , pero lo suficientemente rápido como para minimizar la sobrecarga por artículo. Si un puerto SPI estaba alimentando 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 su tiempo entrando y regresando de la rutina de servicio de interrupción y ninguno haciendo cualquier trabajo real. Sin embargo, usando DMA, la sobrecarga podría reducirse al 13% incluso si cada transferencia de DMA causara que la CPU se detuviera durante dos ciclos.
Finalmente, algunas CPU permiten que se realice DMA mientras la CPU está dormida. El uso de una transferencia basada en interrupciones requeriría que el sistema se active por completo para cada unidad de datos transferida. Sin embargo, utilizando DMA, es posible que el controlador de reposo alimente al controlador de memoria un par de relojes cada vez que ingresa un byte, pero deja que todo lo demás permanezca dormido, lo que reduce el consumo de energía.
fuente
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 recolectar una serie de muestras de un ADC, tiene tres métodos para mover esos datos:
Método de sondeo. Aquí es donde espera en las banderas de registro para permitirle entrar / salir el próximo 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, su transferencia se ralentizará drásticamente.
Método de interrupción. Aquí es donde escribe una rutina de servicio de interrupción (ISR) que se ejecuta con cada transferencia de bytes y escribe el código en el ISR que administra la transferencia. Esto es más eficiente para la CPU porque la CPU prestará servicio a su ISR solo cuando sea necesario. Es de uso gratuito en cualquier otro momento, excepto en el ISR. ISR es también una de las opciones más rápidas para realizar la transferencia en términos de velocidad de transferencia.
DMA Configura el DMA con punteros de origen / destino, número de transferencias y listo. Robará los ciclos de bus y el tiempo de CPU para realizar la transferencia, y la CPU es libre de hacer otras cosas mientras tanto. Puede configurar una bandera o interrupción para indicar cuándo se realiza la transferencia. Por lo general, es un toque más rápido que ISR y suele ser su 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 el número de transferencias para realizar y desactivar. 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 estoy obteniendo la máxima velocidad de transferencia en el negocio.
En mi experiencia, últimamente con los procesadores Atmel SAM3 / 4, DMA ejecuta un toque más rápido que un ISR eficiente de mi propia creación. Tenía una aplicación que leería en una pila de bytes de SPI cada 5 ms. Se estaban produciendo muchas matemáticas de coma flotante en las tareas en segundo plano, así que quería que la CPU fuera lo más libre posible para esas tareas. La implementación inicial fue ISR, y luego me mudé a DMA para comparar e intentar comprar un poco más de tiempo de CPU entre muestras. La ganancia de velocidad de transferencia se mejoró ligeramente, pero solo un poco. Apenas era medible en el alcance.
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 sea necesario y la DMA está haciendo esencialmente las mismas operaciones con la CPU que habría codificado en un ISR eficiente .
En casos raros, he visto periféricos que tienen su propia área RAM a la que DMA solo puede acceder. Esto fue en Ethernet MAC o USB.
fuente
Lo más probable es que se use DMA aquí para que el DAC pueda tener una sincronización regular, generar una forma de onda cambiando la salida analógica en algún intervalo conocido.
Sí, si es un autobús compartido, entonces ... tienes que compartir.
La CPU no siempre usa 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ó allí primero (por ejemplo, tener un comando quince delante del recurso y quince solicitudes arriba, en el orden en que llegan, sí, eso no sería necesariamente determinista ) En un caso como este, es posible que desee que el dma tenga prioridad sobre la CPU para que las cosas sensibles al tiempo como los DAC o los ADC tengan un tiempo determinista. Depende de cómo eligieron implementarlo.
La gente a veces tiene esta suposición a menudo incorrecta de que dma es gratis. Todavía no consume tiempo de bus, si se comparte con la CPU (que eventualmente es cuando habla con un recurso con el que la CPU puede hablar), entonces la CPU y / o el dma se detienen, por lo que la CPU aún tiene que esperar un poco tiempo, en algunas implementaciones (probablemente no en su microcontrolador), la CPU se detiene por completo hasta que la dma se completa, la CPU se detiene durante el tiempo que dure. Solo depende de la implementación. La parte libre de esto es que la CPU no tiene que ser interrumpida constantemente o sondear o contener la respiración para que algún evento alimente datos. Puede tomar su tiempo crear el próximo búfer para dma. Tiene que estar atento a que se complete la transferencia de dma y lidiar con eso, pero en lugar de decir cada byte, ahora son múltiples bytes, algún bloque de datos.
No hay una respuesta universal. "Depende" ... del diseño específico de la cosa específica que está utilizando. Incluso dentro del diseño de un chip / placa / sistema puede haber múltiples motores dma y no hay razón para suponer que todos funcionan de la misma manera. Para cada caso, tiene que resolverlo, y desafortunadamente, a menudo no lo documentan o lo documentan lo suficientemente bien. Por lo tanto, es posible que deba crear algunos experimentos si le preocupa.
fuente
Las respuestas hasta ahora hablan sobre la "velocidad" que la CPU puede hacer funcionar y cómo DMA se beneficia de eso. Sin embargo, hay otra consideración, el poder .
Si la CPU deseaba enviar un paquete de datos en un enlace lento, necesitaría estar despierto la mayor parte del tiempo si utiliza sondeos o interrupciones, sin embargo, la CPU principal podría estar en estado de suspensión mientras se realiza DMA .
fuente
Algunos procesadores como la serie STM32H7 tienen muchas opciones de RAM y montones de 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 se ve afectado por DMA. Para mover datos, 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 escalo los datos y realizo el complejo de coma flotante 256 bin fft en dtcm ram. Luego FIFO el resultado en una matriz 2d en ram AXI usando MDMA.
Yo tomo un segundo bin fft 64 a través del fifo para el vector de velocidad. Luego hago la magnitud de los datos complejos y envío los datos resultantes de los valores de coma flotante 128 y 64 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 con el sobremuestreo 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 ayuda la gran cantidad de cachés que este dispositivo ha mejorado en el rendimiento de los calcs fuera del dtcm.
fuente