Je faisais récemment un projet avec le mbed (LPC1768), en utilisant le DAC pour produire différentes ondes. J'ai lu des parties de la fiche technique et il a expliqué comment il disposait de DMA pour de nombreux périphériques. Cela semblait être utile, mais à la lecture, j'ai trouvé que le DMA utilisait le même bus de données que le processeur (ce qui, je suppose, est normal). Est-ce à dire que le CPU ne peut pas interagir avec l'une des mémoires pendant que le DAC reçoit des données? De plus, comme le DAC n'avait pas de tampon (pour autant que je sache) et doit donc très souvent utiliser le DMA, quel est l'intérêt du DMA? Si le CPU ne peut pas faire de transactions en mémoire, peut-il faire quelque chose?
microcontroller
mbed
dma
BeB00
la source
la source
Réponses:
La fiche technique LPC1768 que j'ai trouvée contient les citations suivantes (c'est moi qui souligne):
Le diagramme de la page 6 montre SRAM avec plusieurs canaux entre la matrice AHB et la citation suivante le confirme:
Et cela est renforcé par la citation suivante:
Par conséquent, vous pouvez diffuser des données vers votre DAC à partir de l'un des blocs SRAM séparés ou d'un périphérique différent, tout en utilisant la SRAM principale pour d'autres fonctions.
Ce type de DMA périphérique-périphérique est courant dans les petites pièces où l'interface mémoire est assez simple (par rapport à un processeur Intel moderne, par exemple).
la source
Le long et le court terme sont que le DMA permet au CPU de se comporter efficacement à sa vitesse native, tandis que les périphériques peuvent se comporter efficacement à leur vitesse native. La plupart des nombres dans l'exemple sont constitués.
Comparons deux options pour collecter périodiquement des données à partir d'un ADC:
Transférons 1000 échantillons de l'ADC vers la RAM.
En utilisant l'option 1: Pour chaque échantillon, il y a
Imaginons que cette fonction d'interruption soit de 76 instructions, la routine entière est de 100 instructions, en supposant une exécution en un seul cycle (dans le meilleur des cas). Cela signifie que l'option 1 passera 100 000 cycles de temps CPU à s'exécuter.
Option 2: DMA est configuré pour collecter 1000 échantillons d'ADC. Supposons que l'ADC dispose d'un déclencheur matériel provenant d'un compteur de temporisation.
Prétendre l'interruption entière (avec des frais généraux d'entrée et de sortie) est de 100 instructions à cycle unique. En utilisant DMA, vous ne passez que 100 cycles pour enregistrer les mêmes 1000 échantillons.
Maintenant, chaque fois que le DMA accède au bus, oui, il peut y avoir un différend entre le CPU et le DMA. Le processeur peut même être obligé d'attendre la fin du DMA. Mais attendre la fin du DMA est beaucoup plus court que de verrouiller le CPU pour entretenir l'ADC. Si l'horloge principale du processeur est une horloge de bus 2x, le processeur peut perdre quelques cycles principaux en attendant la fin du DMA. Cela signifie que votre temps d'exécution effectif du transfert est compris entre 1 000 (en supposant que le processeur n'attend jamais) et 9 000 cycles. Encore bien mieux que les 100 000 cycles.
la source
Si, à un cycle donné, le processeur et un contrôleur DMA devaient accéder au même bus, l'un ou l'autre devrait attendre. De nombreux systèmes, cependant, contiennent plusieurs zones de mémoire avec des bus séparés ainsi qu'un "pont" de bus qui permettra au CPU d'accéder à une mémoire tandis que le contrôleur DMA en accède à une autre.
En outre, de nombreux processeurs peuvent ne pas avoir besoin d'accéder à un périphérique de mémoire à chaque cycle. Si un processeur n'a normalement besoin d'accéder à la mémoire que sur deux cycles sur trois, un périphérique DMA de faible priorité peut être en mesure d'exploiter des cycles alors que le bus mémoire serait autrement inactif.
Même dans les cas où chaque cycle DMA entraînerait le blocage du processeur pour un cycle, cependant, le DMA peut toujours être très utile si les données arrivent à un rythme suffisamment lent pour que le processeur puisse faire d'autres choses entre les éléments de données entrants. , mais suffisamment rapide pour que les frais généraux par article doivent être minimisés. Si un port SPI alimentait des données à un périphérique à un taux d'un octet tous les 16 cycles de CPU, par exemple, interrompre le CPU pour chaque transfert lui ferait probablement passer presque tout son temps à entrer et à revenir de la routine de service d'interruption et aucun faire un travail réel. Cependant, en utilisant le DMA, la surcharge pourrait être réduite à 13% même si chaque transfert DMA entraînait le blocage du processeur pendant deux cycles.
Enfin, certains processeurs permettent l'exécution de DMA pendant que le processeur est endormi. L'utilisation d'un transfert basé sur une interruption nécessiterait que le système se réveille complètement pour chaque unité de données transférée. En utilisant DMA, cependant, il peut être possible pour le contrôleur de sommeil d'alimenter le contrôleur de mémoire de quelques horloges à chaque fois qu'un octet entre, mais de laisser tout le reste rester endormi, réduisant ainsi la consommation d'énergie.
la source
En tant que programmeur, DMA est une option pour transférer des données vers et depuis les périphériques qui les prennent en charge. Pour l'exemple classique de déplacement d'un grand tampon à travers un périphérique série comme SPI ou UART, ou de collecte d'un certain nombre d'échantillons à partir d'un ADC, vous avez trois méthodes pour déplacer ces données:
Méthode d'interrogation. C'est là que vous attendez sur les drapeaux d'enregistrement pour vous permettre de passer dans / hors du prochain octet. Le problème est que vous attendez toute exécution du CPU en attendant cela. Ou, si vous devez partager le temps CPU dans un système d'exploitation, votre transfert sera considérablement ralenti.
Méthode d'interruption. C'est là que vous écrivez une routine de service d'interruption (ISR) qui s'exécute à chaque transfert d'octets et que vous écrivez le code dans l'ISR qui gère le transfert. Ceci est plus efficace pour le CPU car le CPU ne servira votre ISR qu'en cas de besoin. Il est gratuit pour une utilisation à tout autre moment, sauf dans l'ISR. ISR est également l'une des options les plus rapides pour effectuer le transfert en termes de vitesse de transfert.
DMA. Vous configurez le DMA avec des pointeurs source / destination, le nombre de transferts et c'est parti. Il volera les cycles de bus et le temps CPU pour effectuer le transfert, et le CPU est libre de faire d'autres choses en attendant. Vous pouvez configurer un indicateur ou une interruption pour indiquer quand le transfert est effectué. C'est généralement une touche plus rapide que l'ISR et c'est généralement votre option de transfert la plus rapide.
En tant que programmeur, je préfère le DMA car c'est le plus facile à coder et c'est essentiellement la technique la plus rapide pour effectuer le transfert. En règle générale, il vous suffit de configurer quelques registres pour les pointeurs source / destination et le nombre de transferts à effectuer et hors tension. Je passe beaucoup plus d'heures à travailler dans le code ISR que dans le code accéléré DMA car le code ISR nécessite des compétences de conception critiques et doit être codé, testé, vérifié, etc. Le code DMA est beaucoup plus petit et le code que je dois m'écrire moi-même est relativement trivial, et j'obtiens une vitesse de transfert maximale dans le marché.
D'après mon expérience, ces derniers temps avec les processeurs Atmel SAM3 / 4, le DMA fonctionne plus rapidement qu'un ISR efficace de ma propre fabrication. J'avais une application qui lirait une pile d'octets de SPI toutes les 5 ms. Beaucoup de calculs en virgule flottante se produisaient dans les tâches d'arrière-plan, je voulais donc que le processeur soit aussi libre que possible pour ces tâches. L'implémentation initiale était ISR, et je suis ensuite passé à DMA pour comparer et essayer d'acheter un peu plus de temps CPU entre les échantillons. Le gain de vitesse de transfert a été légèrement amélioré, mais seulement d'un peu. Il était à peine mesurable sur le o-scope.
C'est parce que sur les microprocesseurs récents que j'ai vus, l'ISR et le DMA fonctionnent presque de la même manière - ils prennent des cycles de CPU comme requis et le DMA fait essentiellement les mêmes opérations avec le CPU que j'aurais codées dans un ISR efficace .
Dans de rares cas, j'ai vu des périphériques qui ont leur propre zone RAM qui n'était accessible que par DMA. C'était sur Ethernet MAC ou USB.
la source
Le DMA est très probablement utilisé ici afin que le DAC puisse avoir une synchronisation régulière, générer une forme d'onde en changeant la sortie analogique à un intervalle connu.
Oui, s'il s'agit d'un bus partagé, alors ... vous devez partager.
Le processeur n'utilise pas toujours le bus, c'est donc parfois une bonne idée de partager avec un moteur dma. Et bien sûr, cela signifie que les priorités s'impliquent, parfois c'est juste qui est arrivé en premier (par exemple, avoir une commande fifo devant la ressource, et fifo up demandes, dans l'ordre où elles arrivent, oui ce ne serait pas nécessairement déterministe) ). Dans un cas comme celui-ci, vous souhaiterez peut-être que le DMA soit prioritaire sur le processeur afin que les éléments sensibles au temps comme les DAC ou les ADC aient un timing déterministe. Cela dépend de la façon dont ils ont choisi de le mettre en œuvre.
Les gens ont parfois cette hypothèse souvent incorrecte que dma est gratuit. Ce n'est pas qu'il consomme encore du temps de bus, s'il est partagé avec le cpu (ce qu'il est finalement comme il parle à une ressource avec laquelle le cpu peut parler), alors le cpu et / ou le dma sont bloqués, donc le cpu doit encore attendre temps, dans certaines implémentations (probablement pas votre microcontrôleur) le processeur est complètement bloqué jusqu'à ce que le dma se termine, le processeur est arrêté pour la durée. Tout dépend de la mise en œuvre. La partie libre de celui-ci est que le processeur n'a pas besoin d'être constamment interrompu ou d'interrogation ou de retenir son souffle pour un événement pour alimenter les données. Cela peut prendre son temps pour créer le prochain tampon sur dma. Il doit surveiller le transfert dma pour terminer et gérer cela, mais au lieu de dire chaque octet, il s'agit maintenant de plusieurs octets, d'un bloc de données.
Il n'y a pas de réponse universelle unique. "Cela dépend" ... de la conception spécifique de la chose que vous utilisez. Même dans une conception de puce / carte / système, il peut y avoir plusieurs moteurs dma et il n'y a aucune raison de supposer qu'ils fonctionnent tous de la même manière. Pour chaque instance, vous devez le comprendre, et malheureusement, souvent ils ne le documentent pas ou ne le documentent pas assez bien. Vous devrez donc peut-être créer des expériences si cela vous inquiète.
la source
Jusqu'à présent, les réponses parlent de la «vitesse» de fonctionnement du processeur et des avantages du DMA. Cependant, il y a une autre considération, le pouvoir .
Si le processeur souhaite envoyer un paquet de données sur une liaison lente, il doit être éveillé la plupart du temps si vous utilisez l'interrogation ou les interruptions, mais le processeur principal peut peut-être être en veille pendant que le DMA est en cours. .
la source
Certains processeurs comme la série STM32H7 ont beaucoup d'options RAM et des tas de RAM à couplage étroit. Le fait d'avoir des banques de RAM séparées permet à DMA de marteler un lot de RAM pendant que le processeur traite les données dans le ram à couplage étroit qui ne nécessite pas de mise en cache et n'est pas martelé par DMA. Pour déplacer des données, vous pouvez utiliser MDMA. J'ai construit un ensemble radar FMCW en utilisant l'un d'eux. Les ADC obtiennent les données IQ de deux entrées dans une SRAM. J'effectue ensuite une mise à l'échelle des données et exécute le complexe à virgule flottante de 256 bits fft en dtcm ram. Ensuite, FIFO le résultat dans un tableau 2D dans RAM AXI en utilisant MDMA.
Je prends une seconde fft 64 bin à travers le fifo pour le vecteur vitesse. Je fais ensuite l'ampleur des données complexes et envoie les données résultantes 128 et 64 en virgule flottante à un autre H7 en utilisant SPI à 12,5 MHz pour la détection. Je fais tout cela en 4 ms.
Le taux d'échantillonnage est de l'ADC est de 84 kHz et en utilisant le suréchantillonnage, j'obtiens une résolution d'environ 18 bits.
Pas mal pour un processeur à usage général fonctionnant uniquement dans la plage des MHz et sans RAM externe.
Les grands caches de cet appareil ont également amélioré les performances des calculs en dehors du dtcm.
la source