Apa yang terjadi jika ada kesalahan runtime dalam suatu program? Apakah eksekusi program hanya akan berhenti? Apakah ada cara agar Arduino memberi tahu saya apa kesalahannya?
Pertama, mari kita lihat beberapa contoh tentang apa yang salah.
void setup() {
int status;
pinMode(13, OUTPUT);
digitalWrite(13, status);
}
Seperti yang ditunjukkan oleh Edgar Bonet dalam komentar, variabel lokal seperti status
pada kode di atas tidak secara implisit diinisialisasi oleh kompiler C ++. Jadi, hasil dari kode di atas tidak pasti. Untuk menghindari itu, pastikan Anda selalu memberikan nilai ke variabel lokal Anda.
Hal-hal yang sedikit berbeda dengan variabel global dan statis:
Variabel global dan statis dijamin akan diinisialisasi ke 0 oleh standar C.
Itu berarti Anda tidak perlu khawatir tentang inisialisasi mereka ke 0 dalam kode Anda. Bahkan, Anda harus benar-benar menghindarinya, karena inisialisasi dapat menghabiskan memori. Hanya inisialisasi mereka ke nilai selain 0.
int array[10];
int v = array[100];
array[-100] = 10;
Masalah pertama di sini adalah bahwa Anda tidak tahu apa yang akan ditugaskan ke v, tetapi lebih buruk adalah bahwa Anda tidak tahu apa yang Anda kacau dengan tugas ke posisi -100 dari array
.
void doSomething( void ) {
for (int i = 0; i < 1000; i++);
}
void setup ()
{
void (*funcPtr)( void );
funcPtr = &doSomething;
funcPtr(); // calls doSomething();
funcPtr = NULL;
funcPtr(); // undefined behavior
}
Panggilan pertama ke funcPtr()
sebenarnya adalah panggilan ke doSomething()
. Panggilan seperti panggilan kedua dapat menyebabkan perilaku yang tidak terdefinisi.
Nah, Anda bisa kehabisan RAM, misalnya. Apa lagi. Bagaimanapun, saya pikir program Anda akan tetap berjalan, mungkin bukan seperti yang Anda inginkan.
Dalam sistem komputer, masalah seperti ini biasanya ditangani pada berbagai tingkatan:
Arduino hanya memiliki perlindungan terbatas pada kompiler, dan mungkin tidak ada yang lain. Berita baiknya adalah mereka tidak multi-tugas, jadi satu-satunya program yang terpengaruh adalah milik Anda. Bagaimanapun, salah satu bug itu akan menyebabkan perilaku yang tidak menentu.
Asumsinya adalah semua masalah yang saya nyatakan di atas adalah masalah runtime.
Apa yang terjadi jika ada kesalahan runtime dalam suatu program?
Program akan berlanjut dan apa yang terjadi akan tergantung pada efek samping dari kesalahan runtime. Panggilan ke pointer fungsi nol mungkin akan membuat program melompat ke lokasi yang tidak diketahui.
Apakah eksekusi program hanya akan berhenti?
Tidak, itu akan terus berjalan seolah-olah tidak ada yang luar biasa terjadi, mungkin melakukan apa yang tidak Anda inginkan. Ini dapat mengatur ulang atau bertindak tidak menentu. Mungkin mengubah beberapa input menjadi output dan membakar satu atau dua sensor (tapi itu sangat tidak mungkin ).
Apakah ada cara saya mendapatkan Arduino untuk memberi tahu saya apa kesalahannya?
Saya kira tidak. Seperti yang saya katakan sebelumnya, mekanisme perlindungan tidak ada. Tidak ada dukungan runtime dari bahasa, tidak ada OS, tidak ada perangkat keras yang memeriksa akses memori di luar batas (bootloader tidak masuk hitungan juga). Anda hanya harus berhati-hati dengan program Anda dan mungkin mengatur jaring pengaman Anda sendiri.
Alasan kurangnya perlindungan mungkin karena pengontrol Arduino terlalu murah, memiliki memori terlalu sedikit, dan tidak boleh menjalankan sesuatu yang terlalu penting (ya, sepertinya ada penafian oleh AVR di suatu tempat bagi Anda untuk tidak menggunakan MCU yang biasanya digunakan oleh Arduino dalam sistem pendukung kehidupan).
Tidak ada pengecualian runtime. Hanya ada perilaku yang tidak terdefinisi.
Sungguh, tidak ada pengecualian sama sekali . Jika Anda mencoba melakukan operasi yang tidak valid, hasilnya tidak akan diketahui.
Tidak ada pemeriksaan runtime sama sekali, kecuali apa yang Anda implementasikan. Program Anda berjalan pada perangkat keras logam. Ini setara dengan Desktop yang berjalan di ring-0 sepanjang waktu, karena ATmega tidak memiliki dering .
sumber
Ada satu mekanisme yang bisa mendapatkan MCU dari keadaan tidak menentu dan itu adalah pengawas waktu . Jika Anda menerapkan beberapa kode yang berulang kali berjalan dalam satu lingkaran, yang tidak akan berjalan lebih lama dari waktu tertentu, Anda dapat mengatur waktu ini sebagai periode pengawas dan mengaktifkan timer.
Kemudian, Anda harus berulang kali mereset timer dalam loop. Jika kode Anda membeku di beberapa loop kondisi yang tidak akan pernah berakhir, maka pengawas akan menghitung ke nol dan akhirnya mengatur ulang MCU.
Dengan cara ini Anda kehilangan data, tetapi jika Anda menjalankan AVR WDT dalam mode interupsi, Anda dapat menyimpan beberapa data sebelum mengatur ulang MCU.
Jadi pengawas waktu dapat menjaga kode Anda dari loop tak berujung sesekali yang tidak diinginkan.
Dokumentasi: AVR132: Menggunakan Timer Watchdog Enhanced
sumber
Anda memerlukan debugger perangkat keras untuk hal seperti ini. Tetapi biasanya Anda akan melihat program tidak berperilaku seperti yang Anda harapkan dan harus melihat bagian kode untuk mengidentifikasi masalah.
Cara umum / cepat / mudah untuk melakukan ini adalah menambahkan pernyataan cetak untuk mencetak nilai-nilai variabel atau apa saja sehingga Anda tahu program sampai pada titik itu dalam kode tanpa masalah. Ini akan membantu Anda mengisolasi masalah lebih lanjut.
Saya percaya VisualMicro memiliki beberapa fungsi debugging bawaan .
sumber
Saya akan berasumsi AVR CPU tidak memiliki alat deteksi kesalahan atau pemulihan. Mungkin saja berhenti, atau terus mengabaikan kesalahan dan konsekuensinya. Seperti kata sachleen, Anda harus menambahkan beberapa pernyataan debug di program Anda yang mencetak data di tengah operasi, untuk menguji apakah itu berfungsi. Jika Anda menggunakan emulaor dan mengatur breakpoint, Anda dapat dengan mudah menemukan masalah.
sumber
Arduino akan reboot (yaitu akan meluncurkan kembali
setup()
danloop()
).sumber