Kegagalan baca / tulis I2C di bawah beban interupsi berat

10

Dalam sistem saya, saya menggunakan I2C dan saya menyadari di bawah beban interupsi yang berat (dari sumber lain), komunikasi I2C mudah terganggu. Apakah ini perilaku yang diharapkan untuk I2C? Saya akan berharap meskipun beban interupsi, masih akan baik-baik saja karena I2C bukan antarmuka waktu kritis, jam dilengkapi dengan data.

Memperbarui:

Prosesornya adalah STM32. Interupsi disebabkan oleh ADC, saya tidak dapat menonaktifkan interupsi selama peristiwa baca karena itu saya harus menemukan solusi di mana saya dapat membuat komunikasi i2c lebih stabil. STM32 adalah master dan slave adalah perangkat lain (accelerometer).

Pembaruan2:

Ketika saya menghubungkan penganalisa logika ke jam dengan kabel terbang kecil, masalahnya hilang. Menariknya, tidak ada interupsi, baca tulis berfungsi dengan baik, ketika ada interupsi, mereka tidak. Namun, jika saya lampirkan probe ke jam, baca karya tulis di bawah beban interupsi juga. Saya pikir, ada masalah kapasitansi di suatu tempat.

Ktc
sumber
1
Pertanyaan Anda sangat umum karena semuanya tergantung pada desain sistem Anda. Cara menangani I2C sangat tergantung pada perangkat di bus. Bisakah Anda mengabaikannya dan sampai nanti? Dalam FPGA, Anda bisa mendesain logika untuk mengurus banyak hal untuk Anda dan menghindari ini. Sekali lagi, kami memerlukan informasi lebih lanjut tentang mikrokontroler dan hal-hal lain apa yang Anda miliki. Biasanya solusi yang baik di sini adalah menggunakan RTOS dan mendesain tugas dengan benar.
Gustavo Litovsky
Dua hal yang harus dicari, tegangan melorot pada pullup atau daya ke master dan slave i2c Anda, atau masalah emi atau kapasitansi. Adapun beban interupsi, maksud Anda tuan Anda berhenti untuk menangani interupsi? Beberapa chip tidak memungkinkan peregangan jam tanpa batas.
Pejalan kaki
@ GustavoLitovsky Anda benar tetapi 80% dari siklus CPU melayani interupsi ADC dan tidak ada cukup waktu untuk melakukan siklus baca selama jendela non ISR. Jadi membaca akan terganggu tidak peduli seberapa baik saya merancang sistem OS.
Ktc
@Passerby Anda mungkin benar. Masalahnya hilang ketika saya memasang probe penganalisis logika ke garis jam.
Ktc
Berapa nilai Anda saat ini untuk pull-up. Sudahkah Anda mencoba mengubahnya ke nilai yang berbeda? (Coba 10rb atau 4rb atau 2rb hanya untuk tebakan pertama)
Tom L.

Jawaban:

9

Ini adalah masalah perangkat lunak, Anda menghabiskan terlalu banyak waktu untuk menyela & rutin I2C Anda tidak dapat mengatasinya (jadi itu adalah dua hal yang tidak benar). Saya telah melalui beberapa situasi yang serupa.

Pertama: Anda harus melakukan sesedikit mungkin dalam interupsi, hanya membaca & menyimpan data, jangan melakukan pemrosesan apa pun yang dapat Anda lakukan di luar ISR, matematika dapat mengambil banyak siklus CPU dan CPU tidak dapat melakukan hal lain sementara di interupsi itu.

Kedua: Selidiki DMA untuk mengotomatisasi hal-hal, sehingga gangguan Anda hampir menjadi proses otomatis latar belakang.

Ketiga: Jika I2C penting, masukkan ITU dalam interupsi juga, tetapi pastikan Anda menentukan prioritas!

Keempat: Cari tahu mengapa rutinitas I2C Anda gagal, I2C itu sendiri bisa tahan terhadap timing yang sangat terputus-putus, jeda & menunggu dll. Sehingga rutin Anda mungkin perlu memodifikasi untuk memungkinkan ini.

Kelima: Lihat apakah Anda dapat "rantai" menyela, Anda mungkin menemukan bahwa Anda dapat memperbaiki ADC membaca lebih efisien, atau menempatkan ADC dalam mode yang berbeda di mana ia bekerja lebih baik sebelum menginterupsi (EG tunggu semua bacaan tersedia, kemudian baca semua dalam satu hit, daripada 8 interupsi terpisah untuk 8 kanal ADC terpisah dibaca).

Keenam: Gunakan osiloskop atau penganalisis logika, dan simpan pin IO di papan tulis, untuk melacak berapa banyak waktu yang Anda habiskan di setiap bit kode, untuk melihat apakah Anda dapat mempercepatnya. (Tetapkan pin tinggi ketika Anda memasukkan fungsi / ISR, atur rendah lagi saat keluar).

Ketujuh: Putuskan jika Anda benar-benar perlu membaca ADC, akankah semakin lambat memperburuk keadaan? Ini kontra-intuitif tetapi kadang-kadang berjalan lebih lambat benar-benar memberikan hasil yang lebih baik, melakukan pekerjaan rata-rata sinyal untuk Anda dan mengurangi lonjakan / transien yang dapat menyebabkan masalah atau memerlukan pemrosesan ekstra untuk menghapus. Kami meningkatkan rutin kontrol PID motor dengan hanya menjalankannya 1/4 kecepatan, membebaskan banyak waktu CPU dalam proses.

John U
sumber
Terima kasih atas sarannya. Masalahnya entah bagaimana mengarah ke perangkat keras.
Ktc
4

Budak bus yang sibuk dengan hal-hal lain memiliki kemampuan untuk meregangkan jam untuk mengulur waktu hingga mampu menjalankan komunikasi yang terakhir. Ini dilakukan dengan tidak segera mengirim pulsa clock ACK / NACK, menjaga komunikasi dalam keadaan menengah sampai siap untuk menjawab.

Peregangan jam adalah cara yang tepat untuk menghadapi situasi semacam ini. Perangkat yang tidak melakukan peregangan dan melakukan hal-hal buruk lainnya (bus hang / restart, NACKs alamat atau perintah yang valid, dll.) Dapat bermasalah, dan membuat beban tambahan pada master untuk menjaga hal-hal diurutkan (harus mengulangi perintah , pantau NACK, dll.)

Adam Lawrence
sumber
Anda benar tetapi masalahnya adalah tuan rumah. Tuan rumah sibuk dengan hal-hal lain, bukan budak. Jadi tidak begitu yakin saya bisa melakukan peregangan jam.
Ktc
Apakah Anda menggunakan perangkat keras I2C terintegrasi atau menggigit protokol keluar dari jalur GPIO? Tidak ada interval batas waktu I2C spesifik yang ditentukan dalam standar, jadi budak harus menunggu master untuk menyelesaikan paket tanpa batas waktu.
Adam Lawrence
Saya menggunakan STM32 IC2 API. Silakan lihat pembaruan, sepertinya masalah kapasitansi.
Ktc
1

Bergantung pada kemampuan STM32 (saya belum pernah menggunakannya), Anda bisa mencoba salah satu pendekatan berikut. Jika Anda dapat memberikan rincian lebih lanjut tentang apa yang Anda coba lakukan, dan memiliki argumen yang meyakinkan tentang mengapa setiap interupsi diperlukan dalam bentuk yang Anda miliki sekarang, maka jawaban yang lebih spesifik mungkin dipikirkan. Khususnya dalam kasus Anda, I2C cukup lambat untuk ini sehingga tidak menjadi masalah dengan rutinitas interupsi yang ditulis dengan baik.

  • Interupsi untuk apa pun biasanya dapat dinonaktifkan. Paling banyak ada satu atau dua Non-Maskable Interrupts di dalam pengontrol biasa, salah satunya di-reset. Jika Anda tidak memerlukan kontrol yang didorong oleh sesuatu (ADC atau I2C, dalam kasus Anda), maka ubah kode perangkat itu menjadi kode yang tidak menggunakan interupsi, kemudian nonaktifkan interupsi.

  • Penanganan interrupt tidak harus lama. Coba lakukan sesedikit mungkin dari vektor interupsi itu sendiri. Pendekatan minimalis yang ekstrim terhadap interupsi adalah dengan hanya mengatur flag dari dalam rutinitas interrupt handler dan memiliki, katakanlah, loop utama melakukan semua pekerjaan berat sejak saat itu. Apa yang dibutuhkan oleh aplikasi spesifik Anda dan arsitektur firmware mungkin tidak sesederhana seperti itu, tetapi benar-benar bermanfaat untuk melakukan upaya untuk melihat berapa banyak yang harus dilakukan dari dalam interupsi.

  • Jika Anda memiliki DMA periferal, gunakan itu alih-alih memotong pada setiap byte. Biasanya, akan lebih mudah untuk menempatkan ADC pada DMA sebagai lawan I2C, tetapi chip yang berbeda memiliki implementasi yang berbeda. Saya tidak akan terkejut jika ada cara bersih untuk menidurkan pertukaran I2C ke DMA juga. DMA memungkinkan Anda mengurangi jumlah interupsi dan membiarkan inti prosesor Anda bebas dari keharusan menangani setiap blok data.

  • Cobalah untuk mengidentifikasi contoh spesifik di mana Anda melihat kerusakan data, dan mekanisme di mana korupsi data terjadi. Ini jauh lebih sulit untuk dilakukan, tetapi dengan penggunaan kreatif osiloskop / penganalisa logika modern Anda mungkin dapat melihat beberapa masalah. Secara khusus, pastikan masalahnya ada pada pengaturan waktu dan bukan memori (yang merupakan kemungkinan dengan kombinasi kode yang buruk dan kompiler liberal)

EDIT: Beberapa catatan khusus tentang masalah ini, dari komentar Anda pada pertanyaan:

  • Memiliki 80% CPU yang digunakan untuk membaca ADC biasanya bukan hal yang bermanfaat untuk dilakukan. Mengumpulkan data tidak berguna jika Anda tidak bisa menindaklanjutinya atau bahkan menyimpan data.
  • Bahkan jika Anda entah bagaimana mengumpulkan (berguna) sejumlah besar data, interupsi ADC tidak boleh selama benar-benar menekan perangkat I2C untuk waktu yang cukup lama untuk membuatnya kehilangan data. I2C berjalan paling banyak, 100 / 400KHz. Anda memerlukan interupsi yang sangat, sangat lama untuk menginterupsi cukup lama agar terlihat seperti sesuatu yang lebih serius daripada clock jitter pada I2C.
Chintalagiri Shashank
sumber
Terima kasih. Sistem kami membutuhkan jenis ISR yang rumit dan panjang, ini adalah cerita yang panjang. Anda benar, I2C harus bertahan bahkan di bawah beban interupsi ini dan itu tidak bisa. Saya menduga ada masalah di perangkat keras, lihat pembaruan.
Ktc
Untuk apa nilainya, dalam pengalaman saya, sebagian besar kasus penggunaan yang tampaknya mengharuskan ISR panjang gila sebenarnya adalah mereka yang layak mendapatkan RTOS. Dan ya, per pengeditan terakhir Anda sepertinya masalah perangkat keras. Coba letakkan kapasitor kecil di jalur tempat penganalisis logika Anda dan Anda mungkin akan baik-baik saja. Namun, mengapa itu perlu, agak sulit dijawab. Saya akan memeriksa resistor pullup I2C (mungkin terlalu rendah untuk kapasitansi bus Anda), dan memeriksa lembar data dari setiap buffer / repeater I2C yang mungkin Anda gunakan.
Chintalagiri Shashank
0

Dalam sistem yang diberikan, mungkin ada kebisingan memasuki jam dan bus data. Fakta bahwa logika Anda menghapus masalah menunjukkan ini. Untuk implementasi yang praktis dan tercepat, ikuti saja petunjuk yang diberikan oleh pengamatan Anda. Pada bus i2c dengan implementasi 400kbits / detik, berdasarkan pengamatan yang sama, saya menghubungkan 2M yang paralel dengan 12pf ke ground dari titik jam dan data dan menemukan bahwa masalah telah terpecahkan. Ini menghilangkan / menyaring kebisingan di luar jalur minat yang diperlukan untuk komunikasi i2c tertentu. Silakan coba dan beri saran.

pengguna41360
sumber