Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

DMA vs interrupt

Başlatan mr.engineer, 04 Aralık 2022, 17:02:49

mr.engineer

Merhaba, hangi durumlarda DMA kullanımını interrupt'a tercih ediyorsunuz? Mesela Uart veya ADC 'den okuma yaparken DMA mı interrupt mı kullanmanız gerektiğini nasıl anlıyorsunuz?

Interrupt yerine her zaman DMA kullanmak mümkün mü? Mümkün olmayan durumlar neler olabilir?

Andromeda

DMA dedikleri bilgisayarlara özgü bir tanımlama değil mi?
" Tanrı, iradesini hakim kılmak için yeryüzündeki iyi insanları kullanır, yeryüzündeki kötü insanlar ise kendi iradelerini hakim kılmak için Tanrı'yı kullanırlar." ..." Tanrı'dan mesaj gelmiyor, biz Tanrı'ya mesaj gönderiyoruz"

mr.engineer

Belirtmemişim ama MCU'lar için konuşuyorum

MrDarK

Mikro işlemci üzerinde çalışırken bazı şeyleri otomatize etmek için DMA kullanmak güzel oluyor.

Örneğin bir timer flag ini Adcnin ölçüm başlangıcı için kullanabiliyorsun. Aynı işlemi interrupt ile de yapabilirsin fakat mcu bu işlemi yapmak için ana programdaki işini bırakması gerekir.

Birde pilli uygulamalarda çok faydalı oluyor. Örneğin bir analog çıkış veren bir sensörün var bu sensörden aldığın 100 örnek sonra uyanıp değerlendirme yapacaksın dmayı kurup chipi uyutuyorsun. 100 kere int gelmediği için mcu uyanmıyor ve güç tasarrufu yapıyorsun.
Picproje Eğitim Gönüllüleri ~ MrDarK

quarko

Alıntı yapılan: mr.engineer - 04 Aralık 2022, 17:02:49Merhaba, hangi durumlarda DMA kullanımını interrupt'a tercih ediyorsunuz? Mesela Uart veya ADC 'den okuma yaparken DMA mı interrupt mı kullanmanız gerektiğini nasıl anlıyorsunuz?

Interrupt yerine her zaman DMA kullanmak mümkün mü? Mümkün olmayan durumlar neler olabilir?


STM32 lerde DMA i sıklıkla kullanıyorum. Çoklu ADC kanal okumalarda iyi oluyor. Tek dma interruptında tüm kanallar okunmuş oluyor. USART ile veri gönderirken iyi oluyor. Ayrıca SPI, I2C ile oled vs sürerken çok iyi oluyor. Buffer ı ayarlıyorum. DMA i tetikliyorum. Gerisini hallediyor. Özellikle büyük boyutlu verilerde mükemmel tercih oluyor. USART tan alırken DMA kullanmayı tercih etmiyorum. Kullanışsız oluyor. Esnekliği elimden alıyormuş gibi hissediyorum. Onun yerine gelen veriyi rx interruptı ile tek tek alıp işliyorum.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

mr.engineer

@MrDarK güç tasarrufu için kullanmayı ilk defa duydum ama mantıklıymış.

@quarko UART receive yaparken de aslında sıkça kullanıyorlar. Rx interruptı ile byte-byte veriyi almak yerine DMA kullanmak daha iyi değil mi?

Tagli

Eğer ilgili DMA kanalları müsaitse, yani birbirleri ile çakışmıyorsa mutlaka DMA kullanıyorum. Yani DMA her zaman öncelikli tercihim. Gerçi DMA transferinin tamamlanması da yine interrupt ile bildiriliyor, ama tabi bu klasik interrupt yaklaşımına göre çok daha seyrek oluyor.
Gökçe Tağlıoğlu

quarko

Alıntı yapılan: mr.engineer - 04 Aralık 2022, 22:31:44@quarko UART receive yaparken de aslında sıkça kullanıyorlar. Rx interruptı ile byte-byte veriyi almak yerine DMA kullanmak daha iyi değil mi?


Protokollerin çoğunda alınacak byte sayısı belli değil. USART Rx DMA kullanılacaksa baştan dma i ayarlarken kaç byte aldığını belirtmek gerekiyor. Sürekli DMA i 1 byte veri almaya kurup DMA interruptı beklemekte mantıklı bir hareket değil. Bu nedenle haberleşmenin hangi anında hatta dahil olunduğu baştan kestirilemediğinden usart tan veri alırken en temizi, rx interruptı ile veriyi byte byte almak oluyor.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

Tagli

#8
Alıntı yapılan: quarko - 05 Aralık 2022, 07:36:52Protokollerin çoğunda alınacak byte sayısı belli değil.
Ama paket boyutunun maksimum ne kadar olabileceği genelde belli oluyor.

Alıntı yapılan: quarko - 05 Aralık 2022, 07:36:52Sürekli DMA i 1 byte veri almaya kurup DMA interruptı beklemekte mantıklı bir hareket değil.
Kesinlikle. Yine de bazı genelleştirmelere uymak adına bunu da yaptığım oluyor.

Ancak çoğu zaman iletişim paketler (frame) halinde oluyor ve bu durumlarda paket tamamlandıktan sonra işlemek daha pratik. İşlemcide paketin yerleşebilmesi için zaten uygun boyutta bir buffer tanımlanmalı. DMA alma boyutu da bu buffer'ın boyutu kadar olmalı.

Bu bahsettiğim yöntem örneğin Modbus gibi bir protokolde son derece uygulanabilir. Modbus'ta bir paketin zaten ~256 byte'tan  (tam sayıyı hatırlamıyorum) büyük olmaması gerek. DMA'nın yanı sıra idle detection gibi bir interrupt kullanılırsa değişken boyutlu paketin tamamlandığı tespit edilebilir. Paket işlemesi de interrupt içinde değil, normal fonksiyonlarda yapılır. Dediğim gibi, eğer imkan varsa bu şekilde yapılması daha doğru. Böyle bir yapıda DMA'nın normal bir şekilde tamamlanması aslında bir hataya işaret.

Elbette her byte geldiğinde interrupt'a girip bu byte'ı bir state machine içinde işlemek de bir seçenek ama bence son çare olmadıkça tercih edilmemeli. Protokol kodunun kesmeler ile iç içe girmesini kod yapısı/düzeni açısından uygunsuz buluyorum.
Gökçe Tağlıoğlu

e-zeki

Alıntı yapılan: quarko - 05 Aralık 2022, 07:36:52Protokollerin çoğunda alınacak byte sayısı belli değil. USART Rx DMA kullanılacaksa baştan dma i ayarlarken kaç byte aldığını belirtmek gerekiyor. Sürekli DMA i 1 byte veri almaya kurup DMA interruptı beklemekte mantıklı bir hareket değil. Bu nedenle haberleşmenin hangi anında hatta dahil olunduğu baştan kestirilemediğinden usart tan veri alırken en temizi, rx interruptı ile veriyi byte byte almak oluyor.
Hocam özellikle USART özelinde, USART IDLE LINE  özelliğini kullanırsanız dma çok daha efektif bir çözüm oluyor. o zaman hat sadece aktarım 2Byte uzunlukta bir boşluk oluşuncaya kadar IDLE state göndermiyor ve dma bu süreçte gelen tüm byte'ları topluyor sizin için. sonarsında mesaj sonlandı diyerek bir kesme fırlatıyor. tüm mesajı tek seferde tek bir kesmeyle almış oluyorsunuz.
mesajı parslayacaksanız da gruplayacaksanız da elinizde boyutu belli data oluyor her zaman.