Estoy transfiriendo datos de la memoria a un registro de la periferia en un uC STM32. Por ejemplo tomar 20 bytes. Entiendo que después de enviar los 20 bytes, se producirá la interrupción "Transferencia completa". Mi pregunta es: entre bytes individuales (por ejemplo, el 4º y el 5º) ¿cómo sabe el DMA cuándo es el momento de enviar el siguiente byte? ¿Cómo ajusta su velocidad?
Respuestas
¿Demasiados anuncios?Este es un tema complicado. STM32 tiene una arquitectura ARM Cortex de E/S muy avanzada. Los dispositivos periféricos están conectados a la "matriz de bus" (o "tejido de conmutación") a través de un conjunto de buses "AHB/AXI". Echa un vistazo a 1/4 de la STM32H750 diagrama de bloques:
Cada bus dispone de medios hardware locales para arbitrar el acceso al mismo, por lo que éste es uno de los mecanismos que regula la tasa de transferencias atómicas. El otro mecanismo está integrado en los búferes FIFO (First In First Out) asociados a cada canal DMA. Cada FIFO suele funcionar mediante "marcas de agua", que indican el nivel de llenado del búfer. Si el búfer alcanza un determinado nivel preconfigurado, el motor DMA comienza a transferir los bytes intermedios; cuando el nivel desciende, el DMA se detiene temporalmente. El otro extremo del FIFO se llena mediante una interfaz con un dispositivo periférico, que suele tener también algunos búferes, y las máquinas de estado del hardware local se encargan de la transferencia de datos según lo permitan las condiciones. Así, el motor DMA "sabe" cuándo transmitir datos intermedios cuando un conjunto de banderas/semáforos a lo largo de la larga cadena de interfaces le dan "luz verde". Obviamente no hay "interrupciones" involucradas en esta cadena de apretones de manos, esta es toda la idea de DMA (también conocida como "Bus Mastering"), sólo el final de la transacción completa es señalada por una interrupción (o/y por una bandera de estado), por lo que un software puede recargar los punteros DMA.