Apa yang menyebabkan kesalahan UART?

8

Saya ingin tahu untuk mengetahui mengapa kesalahan UART terjadi, dan kapan orang harus memeriksa kesalahan tersebut. Ada posting di sini yang menanyakan tentang penanganan kesalahan individu, seperti overrun, parity, dll ... Saya jelas tentang mengapa overrun data terjadi, mengapa kesalahan paritas terjadi, tetapi saya ingin tahu apa penyebab dasarnya. Pertanyaan saya lebih terfokus pada mengapa kesalahan ini dapat terjadi (alasan fisik), dan ketika seseorang harus melakukan kesalahan memeriksa faktor untuk aplikasi mereka.

Sejauh ini program saya tampaknya bekerja dengan baik (tanpa memeriksa kesalahan), tetapi saya tahu bahwa kebisingan dapat mengacaukan segalanya. Bagaimana saya bisa mensimulasikan kondisi yang dapat menyebabkan port UART Rx / Tx gagal?

pengguna791953
sumber

Jawaban:

8

Ada beberapa sumber potensial untuk kebisingan di sirkuit apa pun. Beberapa yang paling umum termasuk:

  • Catu daya yang tidak diatur dengan baik;
  • Berpindah catu daya;
  • Decoupling kapasitif yang tidak memadai dari rel daya di dekat MCU;
  • Kopling induktif dari sumber elektromagnetik terdekat (termasuk 50 atau 60Hz dari daya listrik; bahkan jika rangkaian bertenaga baterai, ia akan mengalami gangguan ini ketika cukup dekat dengan sumber listrik);
  • Sumber RF dekat frekuensi resonansi jejak pada papan sirkuit, atau salah satu harmoniknya;
  • Routing dari jejak arus tinggi pada papan sirkuit di dekat garis sinyal;
  • Dll

Selain itu (seperti yang disebutkan @jippie), kemiringan jam merupakan penyebab paling umum kesalahan dalam semua jenis komunikasi serial yang menggunakan laju data yang telah ditentukan. Jika Anda menggunakan kristal eksternal dan interfacing ke sistem lain yang secara wajar dapat diharapkan akurat, kecil kemungkinannya menyebabkan masalah. Osilator internal, bagaimanapun, dapat memiliki toleransi yang beberapa urutan besarnya lebih buruk daripada kristal, dan cenderung lebih bervariasi pada rentang suhu.

Ada beberapa tes dasar yang dapat dilakukan pada sistem yang sedang berjalan untuk menentukan kekebalan dasar kebisingan (dan kemiringan) antarmuka Anda, termasuk:

  • Pembekuan (mendinginkan sirkuit ke peringkat minimum komponennya);
  • Baking (panaskan ke peringkat maksimum);
  • Paparan EMI :
    • Tempatkan papan di atas kabel daya pemanas ruang berlari;
    • Kunci radio CB di dekat papan;
    • Letakkan papan di sebelah router nirkabel Anda;
    • Gunakan kabel hookup panjang (bukan kabel serial yang dibangun dengan benar) untuk koneksi UART.

Ada banyak lainnya - pada kenyataannya, ada laboratorium pengujian besar yang didedikasikan untuk kualifikasi EMC .

Secara umum, kecuali beberapa tingkat minimal kehilangan data dapat diterima, selalu bijaksana untuk memasukkan semacam pemeriksaan kesalahan dalam kode komunikasi Anda. Bahkan checksum sederhana lebih baik daripada tidak sama sekali.

Scott Winder
sumber
6

Salah satu sumber kesalahan umum pada UART selain kualitas tingkat sinyal (noise, naik / turunnya waktu) adalah kemiringan jam. Jika jam pemancar dan jam penerima tidak berasal dari sumber yang sama (yang merupakan kasus sebagian besar waktu), maka yang satu akan berjalan lebih cepat daripada yang lain. Ketika kesalahan waktu terlalu besar, Anda mungkin kadang-kadang membaca bit yang salah.

jippie
sumber
Apa yang akan menyebabkan jam miring, jika mikrokontroler dibiarkan sendirian di dalam kotak hitam, di tengah-tengah siapa yang tahu di mana?
user791953
1
Menjalankan jam lokal gratis. Setiap osilator memiliki akurasinya sendiri. Jam MCU dapat dibagi menjadi frekuensi yang dapat digunakan untuk UART, tetapi kadang-kadang dimatikan dengan persentase kecil. Ini pada gilirannya disebabkan oleh kenyataan bahwa pembagi adalah bilangan bulat.
jippie
Misalnya. Jam MCU = 16MHz, UART baudrate = 9600Bd. Maka UART biasanya clock dengan 153600Hz. Tetapi 16000000/153600 bukan angka integer, jadi baudrate akan dimatikan.
jippie
Benar, itu akan memberikan persentase kesalahan kecil. Sepertinya saya cukup beruntung tidak mengalami kesalahan, tetapi jika ini adalah data penting, pemeriksaan harus selalu dilakukan.
user791953
Baudrate rendah, clockrate lebih tinggi (meningkatkan resolusi pengambilan sampel dan ketepatan waktu).
jippie
1

Sebagian besar kesalahan berasal dari tiga penyebab: (1) sinyal yang dihasilkan pemancar tidak mewakili data yang valid; (2) sinyal pemancar tidak diterima sebagai yang dihasilkan, atau (3) penerima tidak siap untuk menangani data ketika diterima. Penyebab paling umum yang pernah saya lihat untuk masalah # 1 adalah pemancar yang akan dikonfigurasi ulang atau dimatikan saat sedang mentransmisikan data. Masalah # 2 dapat dengan mudah terjadi untuk sinyal yang bepergian melalui "dunia luar" sebagai akibat dari hal-hal seperti gangguan radio (ponsel bisa sangat buruk!), Tetapi umumnya tidak terjadi untuk sinyal yang terbatas pada papan tunggal. Masalah # 3 dapat terjadi karena terlalu banyak byte yang datang lebih cepat daripada yang dapat diproses, atau karena penerima dikonfigurasi ulang, dimatikan, atau dijalankan saat transmisi.

Dalam banyak kasus, sulit untuk sepenuhnya menghilangkan semua masalah ini; Tujuan seseorang harus memastikan bahwa "kerusakan" total yang dilakukan oleh mereka (probabilitas terjadinya, kali kerusakan per kejadian) dapat diterima rendah. Ini paling mudah dapat dilakukan dengan memilih perkiraan keandalan yang pesimistis, dan kemudian merancang protokol sehingga dampak pada kinerja sistem bahkan dari kegagalan terburuk yang konsisten dengan perkiraan seseorang akan berada dalam batas yang dapat diterima.

supercat
sumber
0

Kesalahan pembingkaian dapat disebabkan oleh apa yang disebutkan oleh @ jippie - penerima telah mendeteksi bit awal dan di mana ia mengharapkan bit stop data dibalik. Ini juga bisa disebabkan oleh korupsi data yang disebabkan oleh interferensi garis yang menimpa stop bit. Anda selalu perlu memeriksa ini untuk setiap byte yang diterima.

Kesalahan paritas terjadi ketika paritas diterapkan pada tautan data dan ada korupsi yang menyebabkan ketidaksesuaian paritas dalam data yang diterima. Anda selalu perlu memeriksa ini untuk setiap byte yang diterima.

Receive break juga dianggap sebagai kesalahan meskipun itu benar-benar indikasi bahwa data yang masuk telah jatuh ke nol logis selama lebih dari 1 byte data. Biasanya logis 1 adalah keadaan "ambient" antara byte data berturut-turut dan tetap seperti ini. Saya pikir ini melempar ke sistem telegrafi lama. Saya tidak akan repot memeriksa ini kecuali Anda menggunakan "fitur" ini untuk menunjukkan (katakanlah) perintah reset ke penerima.

Overrun error adalah ketika byte baru diterima sebelum byte sebelumnya dibaca oleh CPU. Sedikit berbeda ketika FIFO terlibat tetapi sama artinya - data yang diterima yang valid hilang karena kelambatan CPU. Selalu periksa ini sebelum membaca byte dan jika byte tersebut merupakan bagian dari pesan yang lebih panjang (atau perintah), buang seluruh pesan / perintah tersebut dan mintalah pemancar untuk mengirim ulang seluruh pesan / perintah tersebut.

Sedang berjalan bukan benar-benar kesalahan tetapi menunjukkan kepada UART pengirim bahwa buffer pengirimannya kosong yaitu meminta byte baru untuk mengirimkan. Anda tidak perlu memeriksa ini.

Andy alias
sumber
Saya mengerti apa kesalahan-kesalahan ini dan mengapa itu terjadi, pertanyaan saya lebih pada akhir kapan salah satu harus menyediakan pengecekan kesalahan untuk mereka.
user791953
@ user791953 - selesai
Andy alias
BTW, underrun bukan masalah dengan sebagian besar protokol, tetapi beberapa protokol menggunakan garis siaga untuk menunjukkan paket akhir. Dalam kasus seperti itu, underrun pada sisi pengiriman dapat menyebabkan penerima salah mengira paket berakhir sebelum seharusnya.
supercat
0

Untuk mengatasi kesalahan ini, Anda harus menerapkan protokol logis tingkat yang lebih tinggi. sesuatu yang mirip dengan TCP, atau periksa tumpukan OSI untuk ide-ide.

pada dasarnya, dua bagian penting untuk memulai adalah checksum, dan timeout. menggunakan algoritma untuk menghitung nilai redunden yang mewakili, dalam bentuk yang lebih kecil, isi setiap pesan. kemudian periksa ini di pesan yang diterima. jika jumlahnya tidak cocok, Anda mungkin mendapatkan kesalahan pembingkaian, kebisingan sedikit, dll, dll. dan Anda harus membuang pesan dan mencoba semacam pemulihan, mengirim ulang, sinyal NACK (tidak acknlowledged), dll.

juga, pastikan untuk mengimplementasikan batas waktu dalam protokol tingkat atas Anda. jika Anda mendapatkan semacam kesalahan pembingkaian, UART Anda mungkin tidak akan pernah pulih dan mulai diproses lagi. mungkin menunggu bit stop pada bingkai yang menurut pengirim UART telah dikirim, tetapi rusak oleh noise, kemiringan jam, dll. ini akan mengirim kode input apa pun ke loop tak terhingga. pastikan bahwa Anda memiliki batas yang waras untuk berapa lama bacaan masukan Anda harus menunggu sampai memutuskan untuk meninggalkan pesan ini, dan sekali lagi, coba lagi, NACK, tinggalkan, dll.

Andyz Smith
sumber
Timeout perlu diimplementasikan pada setidaknya satu sisi protokol tingkat tinggi; dalam banyak kasus, yang terbaik adalah menerapkannya di satu sisi. Memiliki satu sisi menunggu selamanya untuk data yang tidak pernah tiba hanya masalah jika ada hal lain yang berguna yang bisa dilakukan sebagai gantinya. Jika X meminta Y untuk beberapa data, X perlu bersiap untuk mengirim ulang permintaannya jika Y tidak menerimanya. Y, bagaimanapun, tidak perlu khawatir tentang apakah X mendapatkan jawabannya. Jika X tidak mendapatkannya, X akan meminta data lagi. Fakta bahwa X tidak meminta data lagi berarti Y tidak perlu mengirim ulang.
supercat
@sercercat benar, ini adalah pola yang baik, tapi saya bertujuan lebih ke arah garis tingkat rendah dengan pengkodean baris. Anda akan selalu memiliki loop yang membaca data, dan mencoba mencari tahu apakah pesan lengkap siap, jika pesan lengkap tidak pernah ada, itu dapat menggantung subsistem input, terlepas dari apakah tidak ada yang lain selain menunggu untuk menjadi selesai dalam hal ini, subsistem input harus setidaknya menyadari bahwa suatu kegagalan terjadi, menyiram data pengukur dan mendapatkan reset untuk percobaan lain.
Andyz Smith
Jika setiap paket dimulai dengan urutan byte yang selalu dapat diidentifikasi dalam konteks apa pun, dan jika penerima tidak ada manfaatnya dapat dilakukan sampai menerima paket lengkap, mengapa harus peduli jika beberapa jam berlalu setelah menerima paket parsial? Lain kali seseorang mencoba mengirim paket nyata, penerima akan melihat penanda awal paket dan mengabaikan paket parsial.
supercat
@supercat karena Anda memiliki loop yang mencari banyak hal. masih mencari akhir dari paket parsial, dan masih mencari awal dari paket baru yang tidak rusak. ini membuat logika jauh lebih kompleks dalam hal praktis, jika kemudian, lakukan sambil, pengkodean.
Andyz Smith
Saya tidak yakin apa kesulitannya. Jika seseorang menggunakan loop terima-byte, seseorang harus keluar darinya jika terjadi timeout atau byte awal. Kedua perilaku perlu ditangani secara identik, kecuali hanya untuk fakta bahwa urutan awal harus menetapkan bendera, sehingga kode berikutnya yang akan mencarinya tidak akan mengganggu.
supercat