DMA CPU'yu rahatlatır ve böylece aynı çekirdek üzerinde çalışan diğer kesintiye dayalı uygulamaların gecikmesini azaltabilirken, bununla ilişkili maliyetler vardır:
Yalnızca sınırlı sayıda DMA kanalı vardır ve bu kanalların farklı çevre birimleriyle nasıl etkileşime girebileceği konusunda sınırlamalar vardır. Aynı kanaldaki başka bir çevre birimi DMA kullanımı için daha uygun olabilir.
Örneğin, her 5 ms'de bir toplu I2C aktarımınız varsa, bu DMA için UART2'ye gelen bir hata ayıklama komutundan daha iyi bir aday gibi görünüyor.
DMA'yı kurmak ve sürdürmek kendi başına bir maliyettir . (Normal olarak, DMA'nın ayarlanması, bellek yönetimi, daha fazla çevre birimi, DMA kullanarak kendi kendine kesintiler ve DMA dışında ilk birkaç karakteri ayrıştırma olasılığınız nedeniyle, karakter başına kesintiye dayalı aktarım ayarlamaktan daha karmaşık olarak kabul edilir. her neyse, aşağıya bakın.)
DMA ek güç kullanabilir , çünkü saatin çekilmesi gereken çekirdeğin başka bir alanıdır. Diğer yandan, çekirdek destekliyorsa, DMA aktarımı devam ederken CPU'yu askıya alabilirsiniz.
DMA, çalışmak için bellek arabellekleri gerektirir (çevre biriminden çevre birimine DMA yapmıyorsanız), bu nedenle onunla ilişkili bir miktar bellek maliyeti vardır.
(Bellek maliyeti olabilir Çerezsiz kesmelerini kullanırken de orada, ancak iletiler hemen kesme içine yorumlanır eğer o da beni çok daha küçük veya hiç yok olabilir.)
DMA bir gecikme oluşturur çünkü CPU yalnızca aktarım tamamlandığında / yarı tamamlandığında bildirim alır (diğer yanıtlara bakın).
Bir halka arabelleğine / aralığından veri aktarımı hariç, ne kadar veri alacağınızı / göndereceğinizi önceden bilmeniz gerekir .
Bu, karakter başına kesmeler kullanarak bir iletinin ilk karakterlerini işlemek gerektiği anlamına gelebilir: örneğin, bir XBee ile arayüz kurarken, önce paket türünü ve boyutunu okur ve ardından tahsis edilen ara belleğe bir DMA aktarımını tetiklersiniz.
Diğer protokoller için, yalnızca mesaj sonu sınırlayıcıları kullanıyorlarsa, bu hiç mümkün olmayabilir: örneğin, '\n'
sınırlayıcı olarak kullanılan metin tabanlı protokoller . (DMA çevre birimi bir karakterle eşleşmeyi desteklemedikçe.)
Gördüğünüz gibi, burada dikkate alınması gereken çok sayıda ödünleşim var. Bazıları donanım sınırlamalarıyla (kanal sayısı, diğer çevre birimleriyle çakışmalar, karakterlerle eşleştirme) ilgilidir, bazıları kullanılan protokole (sınırlayıcılar, bilinen uzunluk, bellek arabellekleri) dayanır.
Bazı anekdot kanıtları eklemek için, tüm bu değiş tokuşlarla çok farklı protokollere sahip birçok farklı çevre birimi kullanan bir hobi projesinde karşılaştım. Çoğunlukla "ne kadar veri aktarıyorum ve ne sıklıkta yapacağım?" Sorusuna dayanarak bazı ödünleşmeler yapıldı. Bu temelde basit kesintiye dayalı aktarımın CPU üzerindeki etkisi hakkında kabaca bir tahmin verir. Böylece, aynı DMA kanalını kullanan birkaç saniyede bir UART aktarımı üzerinden her 5 ms'de bir I2C aktarımına öncelik verdim. Diğer UART aktarımı daha sık ve daha fazla veri ile gerçekleşirken, daha nadiren gerçekleşen başka bir I2C aktarımına göre öncelik kazanmıştır. Hepsi değiş tokuş.
Tabii ki, DMA kullanmanın da avantajları var, ancak istediğiniz şey bu değil.