Bagaimana saya bisa menggunakan malloc()
dan free()
fungsi dalam PIC? Saya sudah memeriksa stdlib.h
tajuknya dan tidak disebutkan. Saya menggunakan MCC18.
Adakah yang harus menggunakannya?
Saya membutuhkannya karena saya porting perpustakaan dari Windows XP ke PIC. Panduan porting mengatakan untuk
menyesuaikan fungsi spesifik Sistem Pengoperasian dengan fungsi PIC saya
Tapi saya tidak tahu bagaimana "menerjemahkan" malloc()
dan free()
fungsinya.
Jawaban:
Dalam banyak aplikasi, seseorang perlu mengalokasikan memori, tetapi tidak perlu membebaskan apa pun sambil menjaga sesuatu yang dialokasikan setelah itu. Pada sistem seperti itu, yang perlu dilakukan hanyalah menggunakan linker untuk mendefinisikan array menggunakan semua RAM yang tersedia, mengatur pointer ke awal array itu, dan kemudian menggunakan fungsi malloc mudah yang bagus:
Bagus dan mudah, dan hanya dua byte total overhead untuk sejumlah alokasi. Menelepon gratis () pada blok akan membatalkan alokasi blok itu dan semuanya setelahnya.
Pola alokasi yang sedikit lebih rumit dapat ditangani dengan menggunakan dua petunjuk - satu yang mengalokasikan hal-hal dari bagian bawah memori bergerak ke atas, dan satu di antaranya bergerak dari bagian atas memori ke bawah. Dimungkinkan juga untuk menggunakan pemulung sampah yang kompak jika data dalam tumpukan itu homogen dan ada yang tahu di mana semua referensi luar untuk itu.
sumber
malloc()
dalam mikrokontroler umumnya dianggap sebagai "hal buruk". Tetapi, jika Anda benar-benar membutuhkannya maka Anda akan ingin menemukan versi pihak ketiga.Jika Anda beruntung, kode yang Anda porting mungkin tidak bergantung pada penggunaan kembali blok memori. Jika demikian, Anda dapat menulis pengalokasi sederhana yang mengembalikan pointer ke buffer RAM, lalu memajukan pointer dengan ukuran blok yang diminta.
Saya telah berhasil menggunakan pendekatan ini sebelumnya dalam porting pustaka PC ke mikrokontroler.
Di bawah, Anda akan menyiapkan pengalokasi dengan
my_malloc_init()
dan mengalokasikan memori denganmy_malloc()
.my_free()
ada untuk memenuhi ketergantungan tetapi tidak akan benar-benar melakukan apa pun. Akhirnya Anda akan kehabisan ruang, tentu saja.Agar ini berfungsi, Anda harus mengukur kebutuhan memori terburuk dari kode Anda (lakukan ini pada PC jika memungkinkan) kemudian atur
HEAP_SIZE
sesuai kebutuhan. Sebelum memasuki bagian perpustakaan Anda yang membutuhkan memori dinamis, hubungimy_malloc_init()
. Sebelum digunakan kembali, pastikan tidak ada yang menunjukheap
.(catatan: di dunia nyata, Anda mungkin perlu mempertimbangkan penyelarasan pointer, mis. pembulatan
heap_ptr
sebesar 2 atau 4 byte)Pilihan lain adalah menggunakan struktur alokasi yang lebih sederhana daripada
malloc()
biasanya, seperti FreeList , meskipun ini mungkin tidak memungkinkan Anda untuk mengalokasikan blok berukuran variabel.sumber
Ini bukan jawaban untuk pertanyaan Anda, tetapi alokasi memori dinamis umumnya disukai pada lingkungan RAM kecil dan dengan tidak adanya sistem operasi (misalnya dalam dunia mikrokontroler) ... ... ruang tumpukan yang Anda miliki di lingkungan tertanam biasanya diukur dalam ratusan byte ...
Menerapkan malloc dan gratis pada dasarnya adalah pemeliharaan dari daftar terkait struktur "segmen bebas", dan seperti yang dapat Anda bayangkan, metadata yang terkait dengan segmen bebas tidak substansial bila dibandingkan dengan jumlah memori yang biasanya tersedia ... yaitu "overhead" "Mengelola kumpulan memori dinamis mengkonsumsi sejumlah besar sumber daya yang tersedia.
sumber
Saya tidak tahu apakah pustaka standar C18 mendukung
malloc
danfree
, tetapi Microchip App Note AN914 menunjukkan bagaimana Anda dapat menerapkannya sendiri.Bagaimanapun, Thomas dan poster lainnya telah menyarankan, menggunakan memori dinamis pada PIC dengan ruang RAM yang sangat kecil penuh dengan bahaya. Anda dapat dengan cepat kehabisan ruang yang bersebelahan karena kurangnya manajer memori virtual yang lebih maju yang memberikan OS penuh sesak nafas, yang mengarah ke alokasi dan crash yang gagal. Lebih buruk lagi, itu mungkin tidak deterministik, dan kemungkinan akan merepotkan.
Jika apa yang Anda lakukan benar-benar ditentukan secara dinamis pada saat run-time (jarang untuk hal-hal yang tertanam), dan Anda hanya perlu mengalokasikan ruang pada beberapa acara yang sangat istimewa , saya bisa melihat
malloc
danfree
diterima.sumber
Nah, seberapa besar PIC Anda dalam hal memori?
malloc adalah cara yang sangat tidak efisien dalam mengalokasikan memori. Masalahnya adalah memori dapat menjadi terfragmentasi dengan sering membebaskan dan mallocs dan dengan hanya beberapa kilobyte memori, kegagalan alokasi terlalu umum. Sangat mungkin bahwa jika Anda menggunakan chip yang lebih kecil atau PIC18 sebelumnya tidak ada dukungan untuk malloc, karena Microchip memandangnya sebagai sangat sulit untuk diterapkan (atau mungkin bahkan tidak mungkin dalam beberapa kasus) atau tidak cukup digunakan untuk menjadi setimpal. Belum lagi, tetapi juga cukup lambat, Anda sedang melihat 1 siklus untuk menggunakan buffer statis yang sudah tersedia dan 100 untuk 1.000-an siklus untuk melakukan malloc.
Jika Anda ingin mengalokasikan secara statis, buat hal-hal seperti buffer untuk fungsi sprintf Anda (jika ada, sekitar 128 byte), buffer untuk kartu SD Anda (jika ada), dan seterusnya, hingga Anda menghapus kebutuhan untuk malloc. Idealnya, Anda hanya menggunakannya di mana Anda benar-benar membutuhkannya dan tidak dapat pergi dengan alokasi statis, tetapi situasi ini biasanya jarang dan mungkin pertanda bahwa Anda harus melihat mikrokontroler yang lebih besar / lebih kuat.
Dan jika Anda mengembangkan / porting "sistem operasi" pada PIC18 dan jika itu mendukung mikrokontroler mungkin memiliki dukungan untuk alokasi statis. Sebagai contoh, SQLite3 mendukung alokasi statis - Anda mengalokasikannya buffer array besar dan menggunakannya jika memungkinkan, meskipun bukan untuk mikrokontroler. Jika tidak, maka apakah Anda yakin itu dirancang untuk PIC18 kecil?
sumber
Jika Anda mempertimbangkan
malloc()
danfree()
untuk perangkat lunak tertanam Anda, saya sarankan Anda melihat uC / OS-II danOSMemGet()
danOSMemPut()
. Meskipunmalloc()
memungkinkan Anda mengalokasikan blok memori yang sewenang-wenang,OSMem*()
memberi Anda blok berukuran tetap dari kumpulan yang dialokasikan sebelumnya. Saya menemukan pendekatan ini keseimbangan yang baik antara fleksibilitasmalloc()
dan ketahanan alokasi statis.sumber
AFAIK, untuk melakukan ini dengan benar, Anda benar-benar harus melihat perangkat dengan beberapa jenis unit manajemen memori (MMU). Meskipun mekanisme alokasi dinamis untuk seri PIC18 memang ada, mereka tidak benar-benar akan sekokoh itu - dan berbicara sebagai seseorang yang bekerja pada firmware yang mendorong batas-batas seri PIC18, saya dapat mengatakan bahwa Anda tidak akan mendapatkan aplikasi yang cukup besar di sana jika Anda menghabiskan semua overhead pada manajer memori.
Solusi yang lebih baik: cobalah memahami apa yang dilakukannya, dan mengapa perlu alokasi yang dinamis. Lihat apakah Anda tidak dapat memfaktorkan ulang faktor itu agar berfungsi dengan alokasi statis. (Mungkin ini masalahnya tidak mungkin - jika perpustakaan / aplikasi dirancang untuk melakukan sesuatu yang berskala bebas, atau tidak memiliki batasan jumlah input yang dapat diterimanya.) Tetapi kadang-kadang, jika Anda benar-benar berpikir tentang apa yang Anda coba lakukan, Anda mungkin menemukan itu mungkin (dan mungkin bahkan cukup mudah) untuk menggunakan alokasi statis sebagai gantinya.
sumber