Menurut dokumentasi Arduino, ATmega328 memiliki 32KB memori Flash untuk bootloader + sketsa yang diunggah, dan hanya 2KB SRAM untuk data runtime. ATmega2560 memiliki sedikit lebih banyak, dengan total 256KB dan 8KB.
Dalam kedua kasus tersebut, batasan tersebut tampak agak kecil, terutama jika dibandingkan dengan perangkat konsumen berukuran sama, seperti smartphone.
Apa yang dapat Anda lakukan jika Anda kehabisan? Misalnya jika sketsa Anda terlalu besar, atau Anda perlu memproses banyak data (seperti string) saat runtime? Apakah ada cara untuk memperluas Flash atau SRAM?
flash
sketch-size
Peter Bloomfield
sumber
sumber
Jawaban:
Optimasi
Pemrograman tingkat rendah untuk sistem tertanam sangat berbeda dari pemrograman untuk perangkat tujuan umum, seperti komputer dan ponsel. Efisiensi (dalam hal kecepatan dan ruang) jauh lebih penting karena sumber daya berada pada premium. Itu berarti hal pertama yang harus dilakukan jika Anda kehabisan ruang adalah untuk melihat bagian mana dari kode Anda yang dapat Anda optimalkan.
Dalam hal mengurangi penggunaan ruang program (Flash), ukuran kode bisa sangat sulit untuk dioptimalkan jika Anda tidak berpengalaman, atau jika Anda lebih terbiasa pemrograman untuk komputer desktop yang tidak cenderung membutuhkan keterampilan itu. Sayangnya, tidak ada pendekatan 'peluru ajaib' yang akan bekerja untuk semua situasi, meskipun akan membantu jika Anda mempertimbangkan dengan serius apa yang sebenarnya perlu dimiliki sketsa Anda . Jika fitur tidak diperlukan, keluarkan.
Terkadang juga membantu untuk mengidentifikasi di mana beberapa bagian kode Anda sama (atau sangat mirip). Anda mungkin dapat menyingkatnya menjadi fungsi yang dapat digunakan kembali yang dapat dipanggil dari berbagai tempat. Namun, perlu diketahui bahwa kadang-kadang mencoba membuat kode terlalu dapat digunakan kembali akhirnya membuatnya menjadi lebih bertele-tele. Ini keseimbangan yang sulit untuk dipukul yang cenderung disertai dengan latihan. Menghabiskan waktu untuk melihat bagaimana perubahan kode mempengaruhi output kompiler dapat membantu.
Optimalisasi data Runtime (SRAM) cenderung sedikit lebih mudah ketika Anda terbiasa. Jebakan yang sangat umum untuk programmer pemula menggunakan terlalu banyak data global. Apa pun yang dinyatakan pada lingkup global akan ada selama sketsa seumur hidup, dan itu tidak selalu diperlukan. Jika variabel hanya digunakan di dalam satu fungsi, dan itu tidak perlu bertahan di antara panggilan, maka jadikan itu variabel lokal. Jika suatu nilai perlu dibagi di antara berbagai fungsi, pertimbangkan apakah Anda dapat meneruskannya sebagai parameter alih-alih menjadikannya global. Dengan begitu Anda hanya akan menggunakan SRAM untuk variabel-variabel tersebut saat Anda benar-benar membutuhkannya.
Pembunuh lain untuk penggunaan SRAM adalah pemrosesan teks (misalnya menggunakan
String
kelas). Secara umum, Anda harus menghindari melakukan operasi String jika memungkinkan. Mereka adalah babi memori besar. Misalnya, jika Anda mengeluarkan banyak teks ke serial, gunakan beberapa panggilan untukSerial.print()
bukannya menggunakan penggabungan string. Coba juga untuk mengurangi jumlah string literal dalam kode Anda jika memungkinkan.Hindari rekursi jika memungkinkan juga. Setiap kali panggilan rekursif dilakukan, dibutuhkan tingkat stack yang lebih dalam. Refactor fungsi rekursif Anda untuk menjadi iteratif sebagai gantinya.
Gunakan EEPROM
EEPROM digunakan untuk penyimpanan jangka panjang hal-hal yang hanya berubah sesekali. Jika Anda perlu menggunakan daftar besar atau mencari tabel data tetap, maka pertimbangkan untuk menyimpannya di EEPROM terlebih dahulu, dan hanya menarik apa yang Anda butuhkan saat diperlukan.
Jelas EEPROM cukup terbatas dalam ukuran dan kecepatan, dan memiliki jumlah siklus tulis yang terbatas. Ini bukan solusi yang bagus untuk keterbatasan data, tetapi mungkin cukup untuk meringankan beban pada Flash atau SRAM. Sangat mungkin juga untuk berinteraksi dengan penyimpanan eksternal yang serupa, seperti kartu SD.
Ekspansi
Jika Anda telah kehabisan semua opsi lain, ekspansi mungkin menjadi suatu kemungkinan. Sayangnya, memperluas memori Flash untuk menambah ruang program tidak dimungkinkan. Namun, adalah mungkin untuk memperluas SRAM. Ini berarti Anda mungkin dapat memperbaiki sketsa Anda untuk mengurangi ukuran kode dengan mengorbankan peningkatan ukuran data.
Mendapatkan lebih banyak SRAM sebenarnya cukup mudah. Salah satu opsi adalah menggunakan satu atau lebih chip 23K256 . Mereka diakses melalui SPI, dan ada perpustakaan SpiRAM untuk membantu Anda menggunakannya. Berhati-hatilah karena mereka beroperasi pada 3.3V, bukan 5V!
Jika Anda menggunakan Mega, Anda bisa mendapatkan pelindung ekspansi SRAM dari Lagrangian Point atau Rugged Circuits .
sumber
Ketika Anda mengunggah kode Anda ke Arduino Anda, ucapkan Uno misalnya, itu akan memberi tahu Anda berapa banyak byte yang digunakan dari 32K yang tersedia. Itu adalah berapa banyak memori flash yang Anda miliki (pikirkan hard disk komputer). Saat program Anda berjalan, ia menggunakan apa yang disebut SRAM, dan ada jauh lebih sedikit dari yang tersedia.
Terkadang Anda akan melihat program Anda bertingkah aneh pada titik yang bahkan belum pernah Anda sentuh. Bisa jadi perubahan terbaru Anda menyebabkannya kehabisan memori (SRAM). Berikut adalah beberapa tips tentang cara membebaskan SRAM.
Menyimpan string dalam Flash bukan SRAM.
Salah satu hal paling umum yang saya lihat adalah chip kehabisan memori karena ada terlalu banyak string panjang.
Gunakan
F()
fungsi ketika menggunakan string sehingga mereka disimpan dalam Flash bukan SRAM, karena Anda memiliki lebih banyak dari yang tersedia.Gunakan tipe data yang tepat
Anda dapat menyimpan byte dengan beralih dari
int
(2 byte) kebyte
(1 byte). Byte yang tidak ditandatangani akan memberi Anda 0-255 jadi jika Anda memiliki angka yang tidak lebih tinggi dari 255, simpan byte!Bagaimana saya tahu saya kehabisan memori?
Biasanya Anda akan mengamati program Anda bertingkah aneh dan bertanya-tanya apa yang salah ... Anda tidak mengubah apa pun dalam kode di dekat titik di mana itu kacau, jadi apa yang menyebabkannya? Kehabisan memori.
Ada beberapa fungsi untuk memberi tahu Anda berapa banyak memori yang tersedia yang Anda miliki.
Memori yang tersedia
sumber
F()
masalahnya adalah fungsi spesifik Arduino atau ada di perpustakaan AVR? Anda dapat mempertimbangkan untuk menyebutkanPROGMEM const ...
juga.Selain apa yang dikatakan orang lain (yang saya setujui sepenuhnya), saya akan menyarankan untuk membaca artikel AdWords tentang memori ini; itu ditulis dengan baik, menjelaskan banyak hal tentang memori dan memberikan petunjuk tentang cara mengoptimalkannya.
Di akhir bacaan, saya pikir Anda akan mendapatkan jawaban yang cukup lengkap untuk pertanyaan Anda.
Singkatnya, Anda memiliki 2 target optimasi yang mungkin (tergantung di mana masalah memori Anda berada):
F()
makro)Pendekatan tambahan untuk mengurangi penggunaan SRAM juga dijelaskan (tetapi jarang digunakan, karena agak berat ketika pengkodean dan tidak sangat efisien), itu termasuk menggunakan EEPROM untuk menyimpan data yang dibangun oleh program Anda, tetapi tidak digunakan sampai nanti ketika beberapa kondisi terjadi, ketika data dapat dimuat kembali dari EEPROM.
sumber
Ada dua hal yang harus dilakukan jika Anda kehabisan penyimpanan:
Ada banyak kiat daring tentang cara melakukan yang pertama (dan untuk sebagian besar hal yang dilakukan orang dengan Arduino, penyimpanan bawaan lebih dari cukup setelah "mengoptimalkan"). Jadi saya akan fokus pada yang kedua:
Ada 3 hal yang menggunakan flash atau SRAM; masing-masing memerlukan pendekatan yang sedikit berbeda untuk menambahkan penyimpanan:
penyimpanan variabel: dimungkinkan untuk memperluas SRAM, seperti yang telah ditunjukkan oleh sachleen. SRAM, FRAM, dan NVSRAM semuanya sesuai untuk variabel yang berubah dengan cepat. (Meskipun pada prinsipnya Anda bisa menggunakan flash untuk menyimpan variabel, maka Anda harus khawatir tentang flash yang aus). SPI (protokol serial) adalah yang termudah untuk terhubung ke Arduino. The perpustakaan SpiRAM bekerja dengan Microchip 23K256 Chip SRAM serial. Chip FRAM serial Ramtron FM25W256 (sekarang dimiliki oleh Cypress) juga menggunakan SPI. The Cypress CY14B101 NVSRAM juga menggunakan SPI. Dll
data konstan yang perlu tetap ada di sana saat daya dinyalakan: ini hampir sesederhana memperluas SRAM. Ada banyak perangkat penyimpanan EEPROM eksternal , FRAM, NVSRAM, dan FLASH . Saat ini biaya terendah per MB adalah kartu flash SD (yang dapat diakses melalui SPI). Ramtron FM25W256 (lihat di atas), Cypress CY14B101 (lihat di atas), dll. Juga dapat menyimpan data konstan. Banyak perisai ekspansi termasuk slot kartu SD, dan beberapa perpustakaan dan tutorial mendukung membaca dan menulis ke (flash) kartu SD. (Kami tidak dapat menggunakan SRAM untuk ini, karena SRAM melupakan segalanya ketika listrik padam).
kode yang dapat dieksekusi: Sayangnya, memperluas memori Flash Arduino untuk menambah ruang program tidak dimungkinkan. Namun, seorang programmer selalu dapat membuat ulang sketsa untuk mengurangi ukuran kode dengan mengorbankan peningkatan ukuran data dan membuatnya berjalan sedikit lebih lambat. (Secara teori, Anda bisa menerjemahkan seluruh sketsa Anda ke dalam bahasa yang ditafsirkan, menyimpan versi sketsa Anda pada kartu SD, dan kemudian menulis penerjemah untuk bahasa yang berjalan di Arduino untuk mengambil dan menjalankan instruksi dari Kartu SD - Untuk Arduino , juru bahasa BASIC, juru bahasa Tom Napier Picaro, beberapa bahasa khusus aplikasi, dll.).
sumber