2
votes

Où le DMA stocke-t-il les valeurs ADC dans STM32?

J'ai activé le transfert de périphérique DMA vers la mémoire pour ADC1 dans CubeMX et généré le code. Cependant, je ne sais pas où les données de l'ADC seront écrites? Dois-je définir explicitement une variable pour contenir ces données? Comment puis-je récupérer les données dans le DMA Channel 1 ISR?


3 commentaires

Pour configurer le DMA, vous devez lui donner l'adresse et la taille effective (en terme de taille et de nombre de mots) d'une mémoire tampon, espérons-le à un endroit valide dans la RAM. Les données y atterriront. Vous seul avez le code, donc vous seul savez où il se trouve.


Le DMA signifie adresse mémoire directe. Cela signifie que l'ADC écrira directement dans l'adresse mémoire que vous lui donnez. Donc d'abord uint16_t adcvalues ​​[10]; , puis configurez DMA pour écrire 10 valeurs dans le pointeur adcvalues ​​, attendez la fin, puis vous lisez les valeurs uniquement à partir de adcvalues ​​.


Remarque: les tampons DMA doivent toujours être déclarés comme volatils , ou vous pouvez obtenir toutes sortes de bogues d'optimisation étranges. Vous devez également envisager une réintroduction entre le matériel DMA et votre application.


4 Réponses :


1
votes

DMA et uC ne savent rien des variables. Le périphérique DMA possède deux registres de configuration dans lesquels vous stockez l'adresse du périphérique et l'adresse mémoire. Si vous commencez par lire la documentation uC au lieu de HAL, tout sera clair instantanément


0 commentaires

2
votes

Si vous jetez un œil aux documents et exemples HAL, vous trouverez un exemple d'utilisation de l'ADC avec DMA.

En bref:

Pour démarrer la conversion, vous utilisez la fonction: p>

HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);

Où pData est votre variable / tableau où le DMA doit placer les données.


0 commentaires

4
votes

Le DMA ne gère pas la mémoire et ne choisit pas d'adresse valide pour définir les données. De manière générale, le DMA permet les transferts de données sans utiliser le processeur, mais pas plus.


Les microcontrôleurs STM32 assurent les transferts depuis:

  • mémoire en mémoire
  • mémoire vers périphérique
  • périphérique en mémoire

Dans chacun d'eux, les développeurs doivent être conscients de leur objectif afin de configurer (en plus de DMA) les lieux source et de destination, tels que l'adresse des périphériques, la mémoire de réserve (et quel type de mémoire), etc. .


Dans votre cas particulier (consultez RM , AN , docs , etc.), les principaux acteurs d'un ADC vers la mémoire (périphérique vers mémoire) les transferts sont:

  • Source: périphérique ADC, le développeur doit savoir où se trouve le périphérique ADC et configurer (outre ADC) le DMA en fonction des paramètres ADC comme source d'informations.
  • Destination: mémoire, le développeur doit réserver un tas de mémoire (tas / stack / global / etc) et configurer le DMA en fonction de l'espace mémoire déjà alloué. En faisant cela, DMA vous permettra de définir les valeurs de différentes manières (en fonction de l'appareil), comme un tampon en anneau continu, un cycle, un tampon ping-pong (stm32 utilise le terme «double tampon circulaire»), etc.
  • Configuration DMA et ADC: il y a une grande quantité de facteurs que je ne vais pas inclure dans un souci de simplicité, généralement simplifiés par le HAL du fabricant (c'est à vous de l'utiliser).

2 commentaires

Bien que faire DMA à une adresse sur la pile ne soit pas fondamentalement impossible à obtenir correctement, le faire n'importe où en dessous, disons main (), est une idée potentiellement mauvaise, car vous devez vous assurer que le code ne retourne pas invalider ce cadre de pile avant le DMA est terminé.


Bien que je sois d'accord sur le commentaire de Lundin concernant la volatilité, je ne suis pas d'accord avec celui-ci lorsqu'il y a des restrictions ou des ressources limitées. Réserver un tas de RAM uniquement pour DMA n'est pas toujours possible, alors qu'il est vrai que ce doit être la première option.



3
votes

Vous indiquez au pilote HAL DMA ADC où placer les exemples de données lorsque vous démarrez la conversion:

volatile uint32_t adcBuffer[SAMPLE_COUNT]; 
HAL_ADC_Start_DMA( &hadc, 
                   adcBuffer, 
                   SAMPLE_COUNT ); 

Notez que certaines parties STM32 ont une SRAM divisée sur plusieurs bus avec une section beaucoup plus petite que d'autres. La réservation de cette section pour les tampons DMA présente des avantages en termes de performances, car elle réduit les conflits de bus avec les extractions de données logicielles normales. Vous pouvez donc personnaliser votre script de création de liens pour créer des sections et placer explicitement des tampons DMA dans un tout en excluant le placement des données d'application.


0 commentaires