UART TX/RX Interrupt

Başlatan esdevhk, 08 Mayıs 2020, 21:28:03

esdevhk

Merhaba arkadaşlar,

Bu zamana kadar projelerimde çoğunlukla transmit ağırlıklı işlemler yaptım. MCU receive interrupt işlemi belli zamanlarda çalışan projeler ile uğraştım. Fakat şuan belli bir frekansta TX ve RX işlemleri yapmaktayım. TX_TransferComplete ve RX_TransferComplete callback yapısı içerisinde gerekli işlemleri yaptırıyorum.
RX işleminin de seri şekilde olmasından sonra şöyle bir sorun ile karşılaştım. Bir zamandan sonra RX interrupt işlemi duruyor. Fakat TX işleminde bir sorun yok. Hatayı bulmaya çalışırken de RXIE bitinin 0'da kaldığını farkettim. Normalde her RX_TransferComplete fonksiyonundan çıkarken RXIE bitini set ediyorum. Bu demek oluyor ki RX interrupt rutini tam olarak bitmeden TX interrupt'ı üzerine biniyor ve artık interrupt aktif olmuyor.

Aynı çevre birimine ait iki interrupt bu şekilde üst üste mi biniyor? NVIC dokumanında böyle bir ifade göremedim. Donanımsal olarak birbirlerini kontrol etmiyorlar mı?

Sorunu bir şekilde çözdüm şimdilik ama kalıcı bir çözüm olduğunu düşünmüyorum. Sizlerin de fikirlerini almak istedim.

Teşekkürler, iyi çalışmalar.

ibocakir

Hocam merhaba,



Sorunuzun cevabı bu resimde olabilir mi? İşlemci belirtmediğiniz için örnek olsun diye STM32F407 Reference Manuel'den UART Interrupt Bloğunu koymak istedim.

NVIC Vector'üne UART bloğundan bir yalnızca bir adet interrupt düşüyor, o da resimdeki şemadan oluşan interrupt. Hangi interrupt'ın düştüğünü de Status Flag'lerden anlamak gerekiyor.

Yalnız "bir zaman sonra" dediğiniz beni biraz düşündürdü. Acaba buffer'la alakalı mı bir problem yaşıyorsunuz ? Bir de çözüm yönteminiz nasıldı, neden beğenmediniz ?

esdevhk

Alıntı yapılan: ibocakir - 09 Mayıs 2020, 04:26:56Hocam merhaba,



Sorunuzun cevabı bu resimde olabilir mi? İşlemci belirtmediğiniz için örnek olsun diye STM32F407 Reference Manuel'den UART Interrupt Bloğunu koymak istedim.

NVIC Vector'üne UART bloğundan bir yalnızca bir adet interrupt düşüyor, o da resimdeki şemadan oluşan interrupt. Hangi interrupt'ın düştüğünü de Status Flag'lerden anlamak gerekiyor.

Yalnız "bir zaman sonra" dediğiniz beni biraz düşündürdü. Acaba buffer'la alakalı mı bir problem yaşıyorsunuz ? Bir de çözüm yönteminiz nasıldı, neden beğenmediniz ?

Hocam tampon ile ilgili bir sıkıntı olduğunu düşünmüyorum. Çünkü TX işlemini kapattığımda herhangi bir sıkıntı olmamakta. TX işlemi açık ama RX işlemi periyodik değil de aperiyodik olarak çalışırken de sıkıntı değil. Fakat hem TX hem RX periyodik olarak çalıştığında 5-10sn sürmeden RX işlemi durmakta ve TX işleminde bir sıkıntı olmamakta.

Kafamı karıştıran konu şu ben callback fonksiyonu içerisinde gelen karakteri state-machine'e soktuktan sonra callback bitmeden yeniden RX interrupt'ını aktif ediyorum. Fakat RX işlemi durduğunda görüyorum ki RX interrupt enable biti sıfır olarak kalmış. Bu da bana şunu düşündürtüyor. Benim RX interrupt rutinim tam olarak bitmeden interrupt rutini sonlanıyor. Bunun sebebi olarak da DR registerından okuma yaptıktan sonra interrupt flag'inin otomatik olarak sıfırlanması olabilir mi? Yani tam RXNE sıfırlandığında TC veya TXE interrupt olusursa kesme tümüyle işlenmeden sonlanabilir mi?

ibocakir

Alıntı yapılan: huseyink - 09 Mayıs 2020, 19:32:16Bunun sebebi olarak da DR registerından okuma yaptıktan sonra interrupt flag'inin otomatik olarak sıfırlanması olabilir mi? Yani tam RXNE sıfırlandığında TC veya TXE interrupt olusursa kesme tümüyle işlenmeden sonlanabilir mi?

Hocam siz interruptu manuel olarak sıfırlamadan kendisi otomatik olarak sıfırlanacağını düşünmüyorum. İşlemcide bu konuda bir hata olabilir mi? Errata'sına bakmayı denediniz mi?

esdevhk

Alıntı yapılan: ibocakir - 09 Mayıs 2020, 20:44:02Hocam siz interruptu manuel olarak sıfırlamadan kendisi otomatik olarak sıfırlanacağını düşünmüyorum. İşlemcide bu konuda bir hata olabilir mi? Errata'sına bakmayı denediniz mi?



Buyrun hocam STM32F103 reference manualde yazan bu şekilde. Ben mi yanlış anlıyorum. USART_DR registerı okunarak silinir diyor.

mustafa_cmbz

Piclerde çok çabaladım bu rx interrupt ile.

Orada da aynı sıkıntı vardı bir üre sonra tıkanıyor rx bunun sebebide sanırım donanım alakasız yerde parazit ten dolayı kesmeye giderse ve yarım kalırsa bunu algılayıp gelen kadar bilgiyi bufferdan alıp yani okumak silmek anlamına geliyor sıfırlayıp kesmeleri tekrar kurmak gerekiyordu.

Karmaşık anlatmış olabilirim ama benim kanaatimce de olay buffer temizleme ile ilgili hele bir süre sonra yapıyor diyorsanız başka bir açıklaması yok gibi gereksiz bir bilgi alıyor yada çevreden etkileniyor buffer temizlemediğin için muhtmel kilit oluyor

esdevhk

Alıntı yapılan: mustafa_cmbz - 10 Mayıs 2020, 04:17:45Piclerde çok çabaladım bu rx interrupt ile.

Orada da aynı sıkıntı vardı bir üre sonra tıkanıyor rx bunun sebebide sanırım donanım alakasız yerde parazit ten dolayı kesmeye giderse ve yarım kalırsa bunu algılayıp gelen kadar bilgiyi bufferdan alıp yani okumak silmek anlamına geliyor sıfırlayıp kesmeleri tekrar kurmak gerekiyordu.

Karmaşık anlatmış olabilirim ama benim kanaatimce de olay buffer temizleme ile ilgili hele bir süre sonra yapıyor diyorsanız başka bir açıklaması yok gibi gereksiz bir bilgi alıyor yada çevreden etkileniyor buffer temizlemediğin için muhtmel kilit oluyor

Hocam dediklerinizde haklı olabilirsiniz fakat dediğim gibi TX işlemi kapalıyken böyle bir sıkıntı ile karşılaşmıyorum. Yani interruptların birbirlerini etkiliyor olması muhtemel değil mi?
Çünkü kafamı karıştıran konu interrupt rutini sonunda kesmeyi yeniden aktif etmeme rağmen kesmenin aktif olmamasını nasıl bir hataya yormam gerek? Rutin sonuna kadar tamamlanmıyorsa sebep nedir?

z

Rx ile ilgili tum hata flaglarini kontrol ediyormusun?

Eger hata varsa onlarin da gereklerini yapmak zorundasin.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

esdevhk

Alıntı yapılan: z - 10 Mayıs 2020, 05:39:41Rx ile ilgili tum hata flaglarini kontrol ediyormusun?

Eger hata varsa onlarin da gereklerini yapmak zorundasin.



Zaten şuan HAL sürücüsünü kullanmaktayım hocam. Sürücü kendi içerisinde kontrol yapmakta. Ama çalışma esnasında kalıcı bir hata gözlemleniyorum. RX işlemi çalışmasını durduktan sonra da bir hata gözükmüyor.
Sizce neden TX esnasında RX işlemi duruyor olabilir?

mufitsozen

#9
Alıntı yapılan: huseyink - 10 Mayıs 2020, 12:32:34......  RX işlemi <neden> duruyor olabilir?

framing, overrun, parity vb bir hata oluyor ve siz bunu gosteren bitleri temizlemiyorsunuz.

mesela:
According to the reference guide, the RXNE interrupt can fire if either the RXNE flag or the ORE flag in UART->CR is set. The ORE flag can only be cleared by a software sequence: read UART->SR then read UART->DR.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

esdevhk

Alıntı yapılan: mufitsozen - 10 Mayıs 2020, 13:21:04framing, overrun, parity vb bir hata oluyor ve siz bunu gosteren bitleri temizlemiyorsunuz.

mesela:
According to the reference guide, the RXNE interrupt can fire if either the RXNE flag or the ORE flag in UART->CR is set. The ORE flag can only be cleared by a software sequence: read UART->SR then read UART->DR.

Hocam bakın yaptığım işlemi ve sonuçları ayrıntıları ile anlatayım..

HAL_UART_Receive_IT(&huart2,&comm.gelen_veri_u8,sizeof(comm.gelen_veri_u8));

Yukarıdaki fonksiyonu main içerisinde çağırıyorum ve bu şekilde RXNE_IT aktif ediyorum ve her karakter okumamda CallBack fonksiyonuma giriyor.

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 if(huart->Instance == USART2)
 {
 paket_coz(&comm);
 HAL_UART_Receive_IT(&huart2,&comm.gelen_veri_u8,sizeof(comm.gelen_veri_u8));
 }
}

paket_coz() methodu içerisinde state machine bulunmakta ve veriler doğru gelmişse gelen paket içerisinden anlamlı veriler elde edilmekte. Daha sonra Callback fonksiyonundan çıkarken interrupt yeniden aktif edilmekte. Bu kısımda aslında hiçbir sıkıntı yok.

HAL_UART_Transmit_IT(&huart2,comm.giden_veri_u8,veri_boyutu);

Transmit_IT ile de verilerimi yollamaktayım. RX ve TX işlemi 50hz olarak periyodik bir şekilde çalışmaktadır. Sıkıntı da tam burada başlıyor. Veri gonderme yapmadığım zaman hiçbir sıkıntı olmamakta ve RX işlemimi devamlı sürmektedir. Fakat gönderme işlemi de yaptığımda RX işlemi durmakta.

Dediklerinize tek tek baktım RX işlemi durduğunda SR durum register'ını okudum ve RXNE ve ORE(Overrun Error) bitleri SET olmakta. Fakat CR1 register'ını okudugumda ise RXNEIE bitinin yani RX Interrupt Enable bitinin'de sıfır olduğunu gözlemledim.

ORE ve RXNE bitlerinin aynı anda SET olması sebebiyle RXNE interrupt yeniden aktif mi olmuyor? Bu hataya sebep olan şey tam olarak ne olabilir? Peki TX işlemi varken bu sıkıntı ile karşılaşıyorum da TX işlemi kapalıyken neden karşılaşmıyorum?