Ini mungkin hanya kebetulan tapi saya perhatikan mikrokontroler yang saya gunakan reboot ketika mereka kehabisan RAM (Atmega 328 jika hardware khusus). Itukah yang dilakukan mikrokontroler ketika kehabisan memori? Jika tidak, lalu apa yang terjadi?
Mengapa bagaimana? Penunjuk tumpukan tentu saja ditingkatkan secara membuta ke rentang memori yang tidak dialokasikan (atau terguling), tetapi yang terjadi kemudian: apakah ada beberapa jenis perlindungan yang membuatnya reboot atau apakah itu (di antara efek lainnya) hasil dari penimpaan kritis data (yang saya anggap berbeda dari kode yang saya pikir dijalankan langsung dari flash)?
Saya tidak yakin ini harus ada di sini atau di Stack Overflow, tolong beri tahu saya jika ini harus dipindahkan walaupun saya cukup yakin perangkat keras memiliki peran dalam hal itu.
Memperbarui
Saya harus menunjukkan bahwa saya sangat tertarik dengan mekanisme aktual di balik kerusakan memori (apakah ini hasil dari penggulingan SP -> apakah itu tergantung pada pemetaan memori UC, dll.)?
sumber
Jawaban:
Secara umum tumpukan dan tumpukan menabrak satu sama lain. Pada saat itu semuanya menjadi berantakan.
Tergantung pada MCU, satu dari beberapa hal dapat (atau akan) terjadi.
Ketika saya terjadi Anda mulai mendapatkan perilaku aneh - hal-hal tidak melakukan apa yang seharusnya. Ketika 2 terjadi, semua jenis neraka lepas. Jika alamat pengirim di tumpukan (jika ada) rusak, maka panggilan saat ini akan kembali adalah dugaan siapa pun. Pada saat itu pada dasarnya MCU akan mulai melakukan hal-hal acak. Ketika 3 terjadi lagi, siapa yang tahu persis apa yang akan terjadi. Ini hanya terjadi ketika Anda mengeksekusi kode dari RAM.
Secara umum, ketika tumpukan rusak, semua sudah berakhir. Yang terjadi adalah ke MCU.
Mungkin mencoba mengalokasikan memori pada awalnya gagal sehingga korupsi tidak terjadi. Dalam hal ini MCU dapat mengajukan pengecualian. Jika tidak ada pengecualian handler yang diinstal, maka MCU yang paling sering hanya akan berhenti (setara dengan
while (1);
. Jika ada handler yang diinstal, maka mungkin reboot secara bersih.Jika alokasi memori tidak berjalan, atau jika mencoba, gagal, dan hanya berlanjut tanpa memori yang dialokasikan, maka Anda masuk ke ranah "siapa yang tahu?". MCU mungkin akan me-reboot dirinya sendiri melalui kombinasi peristiwa yang tepat (interupsi yang menyebabkannya mengatur ulang chip, dll), tetapi tidak ada jaminan hal itu terjadi.
Apa yang biasanya bisa menjadi probabilitas tinggi terjadi, meskipun, jika diaktifkan, adalah pengawas waktu internal (jika ada) waktu keluar dan me-reboot chip. Ketika program berjalan sepenuhnya AWOL melalui jenis crash ini petunjuk untuk mengatur ulang timer umumnya tidak akan berjalan, sehingga akan habis dan reset.
sumber
Pandangan alternatif: Mikrokontroler tidak kehabisan memori.
Paling tidak, tidak ketika diprogram dengan benar. Memprogram mikrokontroler tidak persis seperti pemrograman tujuan umum, untuk melakukannya dengan benar, Anda harus mengetahui kendala dan programnya. Ada alat untuk membantu memastikan ini. Cari dan pelajari - setidaknya cara membaca skrip tautan dan peringatan.
Namun seperti yang dikatakan Majenko dan yang lainnya, mikrokontroler yang diprogram dengan buruk dapat kehabisan memori, dan kemudian melakukan apa saja termasuk infinite loop (yang setidaknya memberi pengawas waktu kesempatan untuk mengatur ulang. Anda mengaktifkan pengawas waktu, bukan? )
Aturan pemrograman umum untuk mikrokontroler menghindari ini: misalnya, semua memori dialokasikan pada stack atau dialokasikan secara statis (global); "Baru" atau "malloc" dilarang. Demikian juga rekursi, sehingga kedalaman maksimum dari subrutin bersarang dapat dianalisis dan ditampilkan agar sesuai dengan tumpukan yang tersedia.
Dengan demikian, penyimpanan maksimum yang diperlukan dapat dihitung ketika program dikompilasi atau ditautkan, dan dibandingkan dengan ukuran memori (sering dikodekan dalam skrip tautan) untuk prosesor spesifik yang Anda targetkan.
Maka mikrokontroler mungkin tidak kehabisan memori, tetapi program Anda mungkin. Dan dalam hal ini, Anda harus melakukannya
Satu set aturan umum untuk pemrograman mikrokontroler adalah MISRA-C , yang diadopsi oleh industri motor.
Praktik terbaik dalam pandangan saya adalah dengan menggunakan subset SPARK-2014 dari Ada. Ada sebenarnya menargetkan pengontrol kecil seperti AVR, MSP430 dan ARM Cortex dengan cukup baik, dan secara inheren menyediakan model yang lebih baik untuk pemrograman mikrokontroler daripada C. Tetapi SPARK menambahkan anotasi ke program, dalam bentuk komentar, yang menggambarkan apa yang sedang dilakukan program.
Sekarang alat SPARK akan menganalisis program, termasuk anotasi tersebut, dan membuktikan properti tentang hal itu (atau melaporkan potensi kesalahan). Anda tidak perlu membuang waktu atau ruang kode yang berhubungan dengan akses memori yang salah atau kelebihan integer karena mereka terbukti tidak pernah terjadi.
Meskipun ada lebih banyak pekerjaan di muka yang terlibat dengan SPARK, pengalaman menunjukkan itu bisa menjadi produk lebih cepat dan lebih murah karena Anda tidak menghabiskan waktu mengejar reboot misterius dan perilaku aneh lainnya.
Perbandingan MISRA-C dan SPARK
sumber
malloc()
(dan ini adalah pendamping C ++new
) ke AVR adalah salah satu hal terburuk yang bisa dilakukan orang Arduino, dan telah menyebabkan banyak, banyak programmer yang sangat bingung dengan kode rusak baik di forum mereka, dan pertukaran stack Arduino. Ada sangat, sangat sedikit situasi di mana memilikimalloc
ATmega bermanfaat.Saya sangat suka jawaban Majenko dan memberi +1 pada saya sendiri. Tetapi saya ingin mengklarifikasi hal ini ke titik yang tajam:
Apa pun bisa terjadi ketika mikrokontroler kehabisan memori.
Anda benar-benar tidak bisa mengandalkan apa pun ketika itu terjadi. Ketika mesin kehabisan memori tumpukan, tumpukan kemungkinan besar menjadi rusak. Dan ketika itu terjadi, apa pun bisa terjadi. Nilai variabel, tumpahan, register temp, semuanya menjadi rusak, mengganggu aliran program. Jika / maka / elses dapat mengevaluasi secara tidak benar. Alamat pengirim kacau, membuat program melompat ke alamat acak. Kode apa pun yang Anda tulis dalam program dapat dijalankan. (Pertimbangkan kode seperti: "jika [syarat] maka {fire_all_missiles ();}"). Juga sejumlah instruksi yang belum Anda tulis dapat dieksekusi ketika inti melompat ke lokasi memori yang tidak terhubung. Semua taruhan dibatalkan.
sumber
AVR memiliki reset vektor di alamat nol. Ketika Anda menimpa tumpukan dengan sampah acak Anda akhirnya akan berputar dan menimpa beberapa alamat pengirim dan itu akan menunjuk ke "tempat"; kemudian ketika Anda kembali dari subrutin ke tempat itu, eksekusi akan berputar ke alamat 0 di mana lompatan untuk mengatur ulang handler biasanya berada.
sumber