Saya menjalankan Microchip dsPIC30F6012a. Saya memiliki chip ini pada beberapa PCB, semuanya menjalankan perangkat lunak yang sama, dan mengamati masalah yang sama pada semuanya. Ini menyiratkan masalah sistemik, bukan masalah produksi satu kali. Masalahnya juga dapat direproduksi, menyiratkan saya harus bisa membunuhnya jika saya tahu ke mana harus mencari. Tapi saya masih mengalami kesulitan mengejutkan dalam debug aplikasi.
Papan yang diuji menerima 24V, yang akan diturunkan menjadi 5V melalui V7805. Chip ini berjalan pada osilator internal, dengan PLL 16x, memberikan kecepatan operasi ~ 29,5 MIPS. Kode yang relevan pada papan ini pada dasarnya sangat sederhana: bangun, baca data dari EEPROM, lalu masukkan infinite loop. Ganggu setiap milidetik, amati beberapa data lingkungan, dan tulis nilai yang diperbarui ke EEPROM. Ada hal-hal lain yang terjadi, tetapi masalah masih terjadi bahkan jika kode yang tidak terkait dikomentari, jadi saya bisa yakin itu tidak relevan dengan masalah yang dihadapi.
Dalam penggunaan umum, 95% dari waktu papan bangun dengan nilai yang benar dalam memori, dan melanjutkan tentang bisnisnya. 5% lainnya, namun terbangun dengan nilai yang salah. Secara khusus, itu bangun dengan versi data yang seharusnya dimiliki sedikit-terbalik. Ini adalah empat byte lama tanpa tanda tangan yang saya tonton, dan kata atas atau bawah yang panjang dapat dibalik. Misalnya, 10 menjadi 2 ^ 16-10, yang kemudian menjadi 2 ^ 32-10. Saya dapat mereproduksi kesalahan dengan kekuatan bersepeda secara manual beberapa lusin kali, tapi itu tidak terlalu konsisten, dan jari saya menjadi usang.
Untuk mereproduksi masalah dengan cara yang terkontrol, saya membuat papan kedua yang menggerakkan pasokan 24V ke papan yang diuji. (DsPIC lain mengendarai optocoupler darlington.) Papan tester mematikan 24V selama 1,5 detik (cukup lama untuk rel 5V turun ke dasarnya 0 dan tinggal di sana selama satu detik), kemudian menyalakan 24V menyala untuk beberapa lama waktu yang dapat dikonfigurasi . Dengan waktu sekitar 520 mS, saya dapat mereproduksi kesalahan EEPROM ini dalam lima siklus daya, setiap kali.
Rel 5V berperilaku wajar. Itu menetap di 5V dalam 1 mS turn-on, dengan mungkin .4V overshoot, dengan asumsi saya bisa mempercayai ruang lingkup saya. Pada saat mematikannya meluruh ke 0V secara eksponensial, mencapai 1V dalam 50 mS. Saya tidak memiliki peringatan bangunan yang tampaknya relevan, hanya variabel yang tidak digunakan dan kehilangan baris baru di akhir file.
Saya sudah mencoba beberapa hal:
- Mengaktifkan / menonaktifkan MCLR
- Mengaktifkan / menonaktifkan WDT
- Mengaktifkan / menonaktifkan perlindungan kode
- Mengaktifkan / menonaktifkan / mengubah tegangan pendeteksian brownout
- Mengaktifkan / menonaktifkan / mengubah timer power-on
- Pengaturan PLL berbeda pada osilator internal utama
- Menghubungkan / memutuskan programmer PICkit 3 saya
- Menambahkan 470 uF kapasitansi ke rel 5V
- Menambah / menghapus .1 uF pada 4.7k pullup pada pin MCLR saya
- Menonaktifkan semua interupsi dalam kode dan tidak meninggalkan apa-apa selain pembaruan EEPROM di loop utama
- Menambahkan penundaan 1,5 detik ke rutinitas startup saya sebelum saya mulai membaca EEPROM
Saya juga menulis kode tes terpisah yang tidak melakukan apa-apa selain terus menulis nilai ke EEPROM dan kemudian membacanya kembali, memastikan bahwa nilainya tidak berubah. Puluhan ribu iterasi tidak memberikan kesalahan. Yang bisa saya simpulkan adalah ada yang tidak beres dengan EEPROM baca atau tulis, khususnya di powerup / powerdown.
Saya telah menggunakan perpustakaan EEPROM yang sama sejak 2007. Saya pernah melihat gangguan sesekali, tapi tidak ada yang bisa direproduksi. Kode yang relevan dapat ditemukan di sini:
http://srange.net/code/eeprom.c
http://srange.net/code/readEEByte.s
http://srange.net/code/eraseEEWord.s
http: / /srange.net/code/writeEEWord.s
Saya telah melihat kesalahan EEPROM sebelumnya di aplikasi lain, tetapi selalu sebagai gangguan sekali saja, tidak ada yang dapat direproduksi atau konsisten.
Adakah yang tahu apa yang sedang terjadi? Saya kehabisan hal untuk dicoba.
sumber
Jawaban:
Dua hal muncul di benak saya:
Pertama, menurut lembar data, siklus hapus-tulis membutuhkan setidaknya 0,8 ms, dan hingga 2,6 ms. Anda mengatakan bahwa Anda memiliki interupsi setiap 1 ms, yang dapat menyebabkan operasi penulisan. Saya telah melihat dalam kode bahwa Anda menonaktifkan interupsi untuk bagian dari menghapus dan untuk bagian-bagian dari fungsi tulis. Tapi Anda mungkin masih mendapatkan interleaving lucu dari pemanggilan fungsi. Mungkin ini membantu ketika Anda menonaktifkan interupsi untuk seluruh urutan penghapusan dan penulisan?
Kedua - Anda mungkin ingin menulis saat daya mati, dan penulisan EEPROM terjadi tepat pada saat tegangan pasokan turun di bawah tegangan pengoperasian. Anda dapat mencoba memonitor tegangan suplai, dan menolak penulisan ketika di bawah, katakanlah, 4.5V. Ini mengasumsikan bahwa ia tetap cukup lama di atas 2.7V sebagai tegangan operasi minimal, dan deteksi brown-out diatur untuk memicu hanya di bawah titik itu.
sumber
Anda telah melihat banyak masalah perangkat keras yang mungkin terjadi. Tidak apa-apa, tetapi kemungkinan besar ini adalah bug firmware.
Sayangnya, kode sumber Anda tidak didokumentasikan dengan baik dan diformat menjadi sulit untuk diikuti secara visual. File pertama Anda berisi deklarasi rutin eksternal di atas:
Bukan hanya itu ide yang buruk untuk menempatkan deklarasi seperti ini di modul klien, tidak ada satu pun komentar yang terlihat! Kami hanya bisa menebak apa yang ingin Anda lakukan dari namanya, dan argumen panggilan benar-benar tidak berdokumen. Lebih jauh dalam file itu Anda memiliki berbagai baris yang dimulai dengan "//" dan seluruh garis tanda sama. Ini menambah kekacauan visual sehingga terlalu banyak kesulitan untuk mencoba mengikuti kode.
Anda dapat mengatakan bahwa semua ini tidak penting untuk pengoperasian kode. Namun, praktik pemrograman yang buruk seperti ini memang penting, banyak. Mereka menyebabkan kode ditulis dengan buruk dan membuatnya sulit menemukan bug atau bahkan apa yang seharusnya dilakukan oleh kode tersebut. Semua ini mengakibatkan bersembunyi sulit untuk menemukan masalah, seperti yang Anda temukan. Anda bahkan mengatakan pada diri sendiri bahwa Anda kadang-kadang melihat gangguan dari kode ini sejak 2007. Itu seharusnya menjadi petunjuk yang kuat dari bug, bahkan mungkin dari keseluruhan desain yang buruk.
Perbaiki kekacauan ini, dokumentasikan dengan benar semua antarmuka, dan masukkan deklarasi umum ke dalam file yang Anda tulis sekali, lalu rujukan bila diperlukan. Pernyataan Anda tentang Saya tidak punya peringatan bangunan yang tampaknya relevan adalah bendera merah besar. Sekali lagi, perbaiki kekacauan. Saat debugging, selalu ikuti masalah yang mudah direproduksi dan diperbaiki terlebih dahulu. Kadang-kadang itu sebenarnya penyebab masalah sulit, atau kadang-kadang dalam memperbaikinya Anda menemukan penyebab masalah lain. Kompiler memperingatkan Anda tentang kecerobohan pada piring perak. Apa lagi yang kamu inginkan? Anda seharusnya tidak memiliki variabel yang tidak digunakan karena menyebabkan kebingungan bagi siapa pun yang mencoba memahami kode Anda, dan tidak ada alasan sama sekali untuk melewatkan baris baru. Sekali lagi, perbaiki kekacauan yang jelas, terutama sebelum meminta orang lain untuk melihat kode Anda.
Kerapian dan perhatian pada hal-hal detail . Banyak.
sumber
Saya memiliki perilaku yang identik dengan 4 pcs dsPIC30F6014A (sekitar 10 digunakan selama beberapa bulan terakhir ..), satu-satunya cara untuk menghindari korupsi data sporadis saat matikan adalah dengan menetapkan nol MCLR sebelum shutdown.
Jelas ini tidak layak dalam prakteknya, jadi saya memilih untuk mengganti "buruk" dsPIC, kalau ada yang punya solusi lain ...
sumber