Ağır kesme yükü altında I2C okuma / yazma hatası


10

Sistemimde I2C kullanıyorum ve ağır kesme yükü altında (diğer kaynaklardan) fark ediyorum, I2C iletişimi kolayca kesiliyor. Bu I2C için beklenen bir davranış mı? Kesme yüküne rağmen beklerdim, I2C tam olarak zaman açısından kritik bir arayüz olmadığından hala iyi olurdu, saat verilerle sağlandı.

Güncelleme:

İşlemci STM32'dir. Kesmeler ADC'den kaynaklanmaktadır, okuma olayları sırasında kesmeleri devre dışı bırakamam, bu nedenle i2c iletişimini daha kararlı hale getirebileceğim bir çözüm bulmalıyım. STM32 master ve slave başka bir cihazdır (ivmeölçer).

Update2:

Küçük bir uçan kabloyla saate mantık analizörü bağladığımda sorun kayboluyor. İlginçtir, kesme yükü yoktur, okuma yazma iyi çalışır, kesme yükü olduğunda, yoktur. Ancak, prob saate takılırsa, kesme yükü altında okuma yazma çalışmaları da okunur. Bence, bir yerlerde bir kapasite sorunu var.


1
Sorunuz çok genel çünkü hepsi sisteminizin tasarımına bağlı. I2C'nin nasıl işlediği gerçekten veri yolundaki cihazlara bağlıdır. Onları görmezden gelip daha sonra gelebilir misin? Bir FPGA'da, sizin için çok şey halletmek ve bundan kaçınmak için mantık tasarlayabilirsiniz. Yine, mikrodenetleyici ve başka neler hakkında daha fazla bilgiye ihtiyacımız var. Genellikle burada iyi bir çözüm bir RTOS kullanmak ve görevleri uygun şekilde tasarlamaktır.
Gustavo Litovsky

Aranacak iki şey, Gerilim çekme veya i2c master ve slave'inizin gücü ya da emi veya kapasitans sorunları. Kesme yüküne gelince, master'ınız kesme işlemini durdurmak için mi duruyor demektir? Bazı yongalar sonsuz saat uzamasına izin vermez.
Passerby

@GustavoLitovsky haklısınız, ancak CPU döngülerinin% 80'i ADC kesintisine hizmet ediyor ve ISR olmayan pencere sırasında bir okuma döngüsü yapmak için yeterli zaman yok. Bu nedenle, işletim sistemini ne kadar iyi tasarlasam da okuma kesilir.
Ktc

@Passerby haklı olabilirsin. Mantık analizörünün probunu saat hattına bağladığımda sorun ortadan kalktı.
Ktc

Pull-up'lar için şu anki değeriniz nedir. Bunları farklı bir değere değiştirmeyi denediniz mi? (Sadece ilk tahmin için 10k veya 4k7 veya 2k'yi deneyin)
Tom L.

Yanıtlar:


9

Bu bir yazılım sorunudur, kesintilere servis vermek için çok fazla zaman harcıyorsunuz ve I2C rutininiz bunu başaramıyor (bu yüzden doğru olmayan iki şey var). Birkaç benzer durumdan geçtim.

Birincisi: Kesintilerde mümkün olduğunca az şey yapmanız, sadece verileri okuyup saklamanız, ISR dışında yapabileceğiniz herhangi bir işlem yapmamanız gerekir, matematik çok fazla CPU döngüsü alabilir ve CPU başka bir şey yapamaz bu kesintide.

İkincisi: İşleri otomatikleştirmek için DMA'yı araştırın, böylece kesintileriniz neredeyse arka plan otomatik bir işlem haline gelir.

Üçüncüsü: I2C önemliyse, bunu da bir kesinti yapın, ancak öncelikleri çözdüğünüzden emin olun!

Dördüncü: I2C rutininizin neden başarısız olduğunu öğrenin, I2C'nin kendisi çok aralıklı zamanlamalara, duraklamalara ve beklemeye vb. Dayanabilir, böylece rutininizin buna izin vermek için değiştirilmesi gerekebilir.

Beşinci: Kesintileri "zincirleyebiliyorsanız" bakın, ADC okumalarına daha verimli bir şekilde hizmet verebileceğinizi veya ADC'yi kesintiye uğramadan önce sizin için daha fazla işe yaradığı farklı bir moda koyabileceğinizi görebilirsiniz (EG, tüm okumaların kullanılabilir olmasını bekler, ardından 8 ayrı ADC kanal okuması için 8 ayrı kesinti yerine hepsini tek bir vuruşta okuyun).

Altıncı: Her bir kod bitinde ne kadar zaman harcadığınızı izlemek ve hızlandırabileceğinizi görmek için bir osiloskop veya mantık analizörü ve yedek IO pinlerini kullanın. (Bir işleve / ISR'ye girdiğinizde pimi yüksek olarak ayarlayın, çıkışta tekrar düşük olarak ayarlayın).

Yedinci: ADC'yi gerçekten bu kadar çok okumaya ihtiyacınız olup olmadığına karar verin, yavaşlamak işleri daha da kötüleştirecek mi? Bu sezgiseldir, ancak bazen daha yavaş çalışır, aslında daha iyi sonuçlar verir, sizin için sinyalin ortalamasını alma ve sorunlara neden olabilecek veya kaldırmak için fazladan işlem gerektiren sivri / geçici kesintileri azaltır. Motor kontrol PID rutinini, sadece 1/4 hızda çalıştırarak geliştirdik, bu sayede işlemde bir miktar CPU zamanı açtık.


Önerileriniz için teşekkürler. Sorun bir şekilde donanıma işaret ediyor.
Ktc

4

Başka şeylerle meşgul olan bir otobüs kölesi, iletişimin sonuna kadar devam edebilene kadar zaman satın almak için esneme saatine sahiptir. Bunu, ACK / NACK saat darbesini hemen göndermeyerek, cevaplamaya hazır olana kadar iletişimi ara durumda tutarak yapar.

Saat germe, bu tür bir durumla başa çıkmanın uygun yoludur. Gerilmeyen ve başka kötü şeyler yapan bir aygıt (veriyolu asmak / yeniden başlatmak, geçerli bir adres veya komutu NACKs) sorunlu olabilir ve işleri sıralamak için master'a ekstra yük getirir (komutları tekrarlamak zorundadır) , NACK'leri takip edin vb.)


Haklısın ama sorun ev sahibi. Ev sahibi köle değil, başka şeylerle meşgul. Yani bir saat uzatma yapabileceğimden emin değilim.
Ktc

Yerleşik I2C donanımı mı kullanıyorsunuz yoksa protokolü GPIO hatlarından mı çıkarıyorsunuz? Standartta tanımlanmış belirli bir I2C zaman aşımı aralığı yoktur, bu nedenle slave'ler master'ın bir paketi bitirmesi için süresiz olarak beklemelidir.
Adam Lawrence

STM32 IC2 API'lerini kullanıyorum. Lütfen güncellemeye bakın, kapasite sorunu gibi görünüyor.
Ktc

1

STM32'nin yeteneklerine bağlı olarak (daha önce hiç kullanmadım), aşağıdaki yaklaşımlardan birini deneyebilirsiniz. Yapmaya çalıştığınız şey hakkında daha fazla ayrıntı verebilir ve her kesmenin neden şimdi sahip olduğunuz formda gerekli olduğuna dair ikna edici bir argüman varsa, daha spesifik bir cevap düşünülebilir. Özellikle sizin durumunuzda, I2C bunun iyi yazılmış kesme rutinlerinde bir sorun olmayacak kadar yavaştır.

  • Herhangi bir şey için kesinti genellikle devre dışı bırakılabilir. Herhangi bir olağan denetleyicide, biri sıfırlanan en fazla bir veya iki Maskelenmeyen Kesinti vardır. Bir şeyin kesinti güdümlü kontrolüne ihtiyacınız yoksa (sizin durumunuzda ADC veya I2C), o çevre kodunu kesinti kullanmayan bir çevreye dönüştürün ve kesintileri devre dışı bırakın.

  • Kesme işleyicileri uzun olmamalıdır. Kesme vektörünün kendisinden mümkün olduğunca az yapmaya çalışın. Kesilmelere karşı son derece minimalist yaklaşım, kesme işleyici rutininin içinden bir bayrak ayarlamak ve diyelim ki, ana döngü oradan tüm ağır kaldırma işlemlerini yapmaktır. Özel uygulama ve ürün yazılımı mimarinizin gerektirdiği kadar basit olmayabilir. ancak, kesinti içinde ne kadar gerçekten yapılması gerektiğini görmek için çaba sarf etmek gerçekten faydalıdır.

  • Çevresel DMA'nız varsa, her baytta kesmek yerine bunu kullanın. Tipik olarak, ADC'yi I2C'nin aksine DMA'ya koymak daha kolay olurdu, ancak farklı yongaların farklı uygulamaları vardır. Ben de DMA I2C değişim kovan için temiz bir yolu olsaydı ben sürpriz olmaz. DMA, kesme sayısını azaltmanıza olanak tanır ve işlemci çekirdeğinizi her veri bloğu ile uğraşmak zorunda bırakmaz.

  • Veri bozulmasını gördüğünüz belirli örnekleri ve veri bozulmasının gerçekleşme mekanizmasını belirlemeye çalışın. Bunu yapmak çok daha zordur, ancak modern bir osiloskop / mantık analizörünün yaratıcı kullanımı ile bazı problemleri görebilirsiniz. Özellikle, sorunun zamanlama ile değil, zamanlama ile ilgili olduğundan emin olun (bu, korkunç kod ve liberal bir derleyici kombinasyonu ile mümkündür)

DÜZENLEME: Sorunun yorumuyla ilgili olarak, sorunun bu örneğiyle ilgili bazı notlar:

  • ADC'yi okumak için% 80 CPU'ya sahip olmak genellikle yapılması gereken bir şey değildir. Veri toplayamıyorsanız ve hatta verileri kaydedemiyorsanız veri toplamak işe yaramaz.
  • Bir şekilde çok miktarda veri topluyor olsanız bile (faydalı olarak), ADC kesintileri, I2C çevre birimini veri kaybına neden olacak kadar uzun süre tamamen bastıracak kadar uzun olmamalıdır. I2C en fazla 100 / 400KHz'de çalışır. I2C'de saat titremesinden daha ciddi bir şey gibi görünmesini sağlayacak kadar uzun süre kesmek için gerçekten, gerçekten uzun bir kesintiye ihtiyacınız olacak.

Teşekkürler. Sistemimiz bu tür karmaşık ve uzun ISR gerektirir, uzun bir hikaye. Yine de haklısın, I2C bu kesme yükü altında bile devam etmeli ve yapamaz. Sorunun donanımda olduğundan şüpheleniyorum, güncellemeye bakın.
Ktc

Değeri için, benim deneyimime göre, delicesine uzun bir ISR'yi zorunlu kılan çoğu kullanım örneği aslında bir RTOS'u hak eden vakalardır. Ve evet, son düzenlemenize göre bir donanım sorunu gibi görünüyor. Mantık analizörünüzün bulunduğu hatta küçük bir kapasitör yerleştirmeyi deneyin ve muhtemelen iyi olacaksınız. Ancak bunun neden gerekli olduğunu cevaplamak biraz daha zordur. I2C çekme dirençlerini (veri yolu kapasiteniz için çok düşük olabilir) kontrol ediyor ve kullandığınız I2C tamponlarının / tekrarlayıcılarının veri sayfalarını kontrol ediyorum.
Chintalagiri Shashank

0

Belirli bir sistemde saate ve veri yollarına giren gürültü olabilir. Mantık çözümleyicinizin sorunu ortadan kaldırması bunu gösterir. Pratik ve hızlı uygulama için, gözleminizin verdiği ipucunu takip etmeniz yeterlidir. Benzer gözlemlere dayanan 400kbit / sn'lik bir i2c veriyolunda, saat ve veri noktalarından toprağa 12pf ile paralel olarak 2M bağladım ve sorunun çözüldüğünü buldum. Bu, belirli i2c iletişimi için gereken ilgi alanı bandının dışındaki gürültüyü kaldırır / filtreler. Lütfen deneyin ve tavsiye edin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.