STM32'de DMA ile UART Alımı: Kayıpsız Veri İçin Halka Tampon
Yüksek baud hızlarında (1 Mbit/s ve üzeri) karakter başına kesme üretmek, Cortex-M4 gibi çekirdeklerde bile ciddi bir yük oluşturur. Çözüm, dairesel DMA ile alım yapıp yalnızca hat boşa düştüğünde (IDLE) işlem yapmaktır.
Neden dairesel DMA?
DMA denetleyicisi veriyi CPU'ya hiç dokunmadan tampona yazar. Tampon sonuna gelindiğinde otomatik olarak başa döner; böylece sürekli akış kesintiye uğramaz.
IDLE hattı kesmesi
UART çevre birimi, hat belirli bir süre boşta kaldığında IDLE bayrağını kaldırır. Bu kesmede DMA'nın kalan transfer sayacını (NDTR) okuyarak tamponun neresine kadar yazıldığını buluruz.
uint16_t pos = BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
if (pos != old_pos) {
/* old_pos .. pos aralığını işle */
}Dikkat edilecekler
- Tampon boyutu, en uzun mesajın en az iki katı olmalı.
- D-Cache açıksa DMA tamponunu
__DSB()ve cache invalidate ile korumalısınız. - Overrun bayrağını temizlemeyi unutmayın; aksi halde alım sessizce durur.
Bu yapıyla 3 Mbit/s hızda dahi CPU kullanımı %1'in altında kalıyor.