2016-09-06 4 views
1

C'est peut-être une question idiote, mais je ne l'ai pas si loin à propos de DMA. Lorsque vous effectuez une mémoire DMAing, vous devez allouer le tampon DMA (par exemple avec dma_alloc_coherent()), puis pour chaque transfert, nous devons copier le tampon dans la mémoire allouée (tampon source), puis déclencher la transaction DMA.Transaction DMA nécessite la copie dans le tampon à chaque fois?

Ainsi, si elle a besoin memcpy() supplémentaire pour chaque transaction, quel est l'avantage d'utiliser DMA?

Procédure pour la copie source à la destination - sans DMA:

  1. tampon de copie (memcpy()) de la source à destination

étapes pour copier la source vers la destination - avec DMA:

  1. copie tampon (memcpy()) de la source à tampon DMA
  2. transaction DMA de déclenchement (qui copie le tampon éventuellement à tampon de destination)

Un exemple de ce problème est avec le pilote Ethernet, qui ont besoin de copier de la sk_buf Recieved en adresse physique du FPGA. Dans ce cas, il faut d'abord copier le sk_buf dans le tampon source DMA (à partir de dma_alloc_coherent()).

+0

De quel pilote parlez-vous exactement? Pouvez-vous nous montrer du vrai code ** dans le noyau principal ** où vous voyez le problème? –

+0

Il est un peu difficile de trouver un exemple simple dans le noyau. J'écris mon propre pilote ethernet, et je ne suis pas sûr que l'utilisation de dma est efficace - comme je l'ai écrit. S'il y a une erreur dans mes questions ou hypothèses, j'aimerais savoir. – ransh

Répondre

2

Si vous pouvez utiliser dma_map_single() avec le pointeur sk_buf, vous n'avez pas besoin de le copier dans un buffer alloué avec dma_alloc_coherent(). Il existe de nombreux exemples dans les pilotes de périphériques réseau.

int dma_len = skb->len; 
dma_addr_t dma_addr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE); 

// error checking code here 
// then send the dma_addr to the drvice 
// when it is done, unmap it 
dma_unmap_single(dev, dma_addr, dma_len, DMA_TO_DEVICE); 

Pour plus de détails, voir le document .

+0

mais j'utilise de la mémoire pour la mémoire (l'espace fpga est mappé), donc je ne suis pas sûr que je devrais utiliser DMA_TO_DEVICE? J'ai lu la documentation de l'API DMA Mapping, mais elle ne précise pas quand il doit y avoir mémoire-à-mémoire et quand mémoire-à-partir de périphérique – ransh

+1

* memory-to-memory * ne se produit que lorsque vous utilisez la mémoire des deux côtés avec adresses ** incrémentales ** et largeur de bus correspondante En cas d'adresse ** fixe ** du FIFO, vous devez utiliser les transferts * memory-to-device * et * device-to-memory * – 0andriy

+0

adresse, comment est-ce que je précise qu'il est mémoire-à-mémoire? – ransh