Pertanyaan umum, di sini dan di tempat lain. Apakah C ++ cocok untuk embedded system?
Mikrokontroler? RTOS? Pemanggang roti? PC Tertanam?
Apakah OOP bermanfaat pada mikrokontroler?
Apakah C ++ menghapus programmer terlalu jauh dari perangkat keras untuk menjadi efisien?
Haruskah Arduino C ++ (tanpa manajemen memori dinamis, templat, pengecualian) dianggap sebagai "nyata C ++"?
(Semoga wiki ini akan berfungsi sebagai tempat untuk mengandung potensi perang suci ini)
microcontroller
embedded
programming
c++
Toby Jaffey
sumber
sumber
Jawaban:
Ya, C ++ masih berguna dalam sistem embedded. Seperti orang lain katakan, itu masih tergantung pada sistem itu sendiri, seperti 8-bit UC mungkin akan menjadi tidak-tidak dalam buku saya meskipun ada kompiler di luar sana dan beberapa orang melakukannya (bergidik). Masih ada keuntungan menggunakan C ++ bahkan ketika Anda menurunkannya ke sesuatu seperti "C +" bahkan di dunia mikro 8-bit. Apa yang saya maksud dengan "C +"? Maksud saya jangan gunakan baru / hapus, hindari pengecualian, hindari kelas virtual dengan pewarisan, mungkin hindari pewarisan bersama-sama, berhati-hatilah dengan templat, gunakan fungsi sebaris alih-alih makro, dan gunakan
const
variabel sebagai ganti#defines
.Saya telah bekerja baik di C dan C ++ dalam sistem tertanam selama lebih dari satu dekade sekarang, dan beberapa antusiasme muda saya untuk C ++ telah hilang karena beberapa masalah dunia nyata yang mengguncang kenaifan seseorang. Saya telah melihat yang terburuk dari C ++ dalam sistem tertanam yang saya ingin sebut sebagai "programmer CS menjadi liar di dunia EE." Bahkan, itu adalah sesuatu yang saya kerjakan dengan klien saya untuk meningkatkan basis kode yang mereka miliki antara lain.
Bahaya C ++ adalah karena ini adalah alat yang sangat sangat kuat seperti pedang bermata dua yang dapat memotong lengan dan kaki Anda jika tidak dididik dan didisiplinkan dengan baik dalam bahasa dan pemrograman umum itu sendiri. C lebih seperti pedang bermata tunggal, tetapi masih sama tajamnya. Dengan C ++ terlalu mudah untuk mendapatkan abstraksi tingkat tinggi dan membuat antarmuka yang tidak jelas yang menjadi tidak berarti dalam jangka panjang, dan itu sebagian karena fleksibilitas C ++ dalam memecahkan masalah yang sama dengan banyak fitur bahasa yang berbeda (template, OOP, prosedural, Template RTTI, OOP +, kelebihan beban, inlining).
Saya menyelesaikan dua seminar 4 jam tentang Perangkat Lunak Tertanam di C ++ oleh guru C ++, Scott Meyers. Dia menunjukkan beberapa hal tentang template yang tidak pernah saya pertimbangkan sebelumnya dan berapa banyak lagi yang dapat membantu menciptakan kode keamanan-kritis. Intinya adalah, Anda tidak dapat memiliki kode mati dalam perangkat lunak yang harus memenuhi persyaratan kode keamanan yang ketat. Templat dapat membantu Anda mencapai hal ini, karena kompilator hanya membuat kode yang dibutuhkan saat membuat template. Namun, seseorang harus menjadi lebih terdidik dalam penggunaannya untuk merancang dengan benar untuk fitur ini yang lebih sulit untuk dicapai dalam C karena linker tidak selalu mengoptimalkan kode mati.
Scott Meyers adalah pendukung yang sangat besar pada template dan penggunaan inlining yang bijaksana, dan saya harus mengatakan saya masih skeptis tentang menjadi gung ho tentang template. Saya cenderung menghindar dari mereka, meskipun dia mengatakan mereka hanya boleh diterapkan di mana mereka menjadi alat terbaik. Ia juga menyatakan bahwa C ++ memberi Anda alat untuk membuat antarmuka yang benar-benar bagus yang mudah digunakan dan membuatnya sulit digunakan. Sekali lagi, itu bagian yang sulit. Seseorang harus mencapai tingkat penguasaan dalam C ++ sebelum Anda bisa tahu bagaimana menerapkan fitur-fitur ini dengan cara yang paling efisien untuk menjadi solusi desain terbaik.
Hal yang sama berlaku untuk OOP. Di dunia yang disematkan, Anda harus membiasakan diri dengan jenis kode yang akan dimuntahkan kompiler untuk mengetahui apakah Anda dapat menangani biaya run-time polimorfisme run-time. Anda harus mau melakukan pengukuran juga untuk membuktikan bahwa desain Anda akan memenuhi persyaratan tenggat waktu Anda. Apakah kelas InterruptManager yang baru akan membuat latensi interupsi saya terlalu lama? Ada bentuk-bentuk polimorfisme lain yang mungkin lebih sesuai dengan masalah Anda seperti polimorfisme tautan-waktu yang dapat dilakukan C juga, tetapi C ++ dapat dilakukan melalui pola desain Pimpl (penunjuk buram) .
Saya mengatakan bahwa semua untuk mengatakan, bahwa C ++ memiliki tempatnya di dunia tertanam. Anda bisa membenci itu semua yang Anda inginkan, tetapi itu tidak hilang. Ini dapat ditulis dengan cara yang sangat efisien, tetapi lebih sulit untuk belajar bagaimana melakukannya dengan benar daripada dengan C. Kadang-kadang dapat bekerja lebih baik daripada C dalam memecahkan masalah dan kadang-kadang mengekspresikan antarmuka yang lebih baik, tetapi sekali lagi, Anda harus mendidik diri sendiri dan jangan takut untuk belajar caranya.
sumber
C ++ sangat cocok untuk embedded system. Sekarang saya menggunakan ada / tidaknya alat pengembangan yang baik (atau ketiadaannya) sebagai kriteria utama saya untuk menggunakan mikroprosesor tertentu atau tidak.
Area C ++ yang baik untuk digunakan pada sistem embedded karena mereka memiliki biaya sumber daya yang rendah:
Area OK:
Area yang tidak digunakan, sebagian besar karena overhead run-time yang tidak dapat diterima pada sistem kecil:
sumber
foo
panggilanbar
dalam bloktry
/catch
, danbar
membuat beberapa objek dan panggilanboz
, yang melempar pengecualian, sistem harus entah bagaimana memanggil destruktor untuk objek yangbar
dibuat sebelum mengembalikan kontrol kefoo
. Kecuali pengecualian benar-benar dinonaktifkan, tidakbar
akan memiliki cara untuk mengetahui apakahboz
mungkin melempar, dan karenanya harus menyertakan kode tambahan untuk memungkinkan kemungkinan itu. Saya ingin melihat variasi C ++ dengan "pengecualian yang diperiksa" untuk menghadapinya; jika rutinitas yang dapat memungkinkan pengecualian untuk melarikan diri ...add r15,r14,#2
bukanmov r15,r14
; untuk keluar melalui pengecualianldrhs r0,[r14] / add r15,r14,r0
,. Biaya nol siklus untuk keluar normal, dan tidak ada batasan stack-frame.Ya, C ++ tentu cocok untuk sistem embedded. Pertama mari kita jelaskan beberapa kesalahpahaman tentang perbedaan antara C dan C ++:
Dalam mikro tertanam, Anda akan selalu perlu menggunakan bahasa tingkat tinggi dengan hati-hati jika Anda khawatir tentang kendala waktu atau ruang. Sebagai contoh, banyak MCU tidak menangani pointer dengan baik, sehingga sangat tidak efisien ketika menggunakan stack. Ini berarti Anda harus berhati-hati tentang meneruskan variabel ke fungsi, menggunakan array dan pointer, dan rekursi. Garis C sederhana seperti:
dapat menghasilkan sekitar 4 halaman instruksi tergantung pada sifat variabel-variabel tersebut.
Setiap kali Anda menggunakan setiap bahasa tingkat tinggi, dan Anda khawatir tentang waktu dan ruang kendala, maka Anda perlu mengetahui bagaimana setiap fitur bahasa yang diterjemahkan ke dalam instruksi mesin pada MCU Anda (setidaknya, setiap fitur yang Anda gunakan). Ini berlaku untuk C, C ++, Ada, apa pun. Mungkin semua bahasa akan berisi fitur yang tidak diterjemahkan secara efisien pada MCU kecil. Selalu periksa daftar pembongkaran untuk memastikan kompiler tidak menghasilkan rim instruksi untuk sesuatu yang sepele.
Apakah C cocok untuk MCU tertanam? Ya, selama Anda mengawasi kode yang dihasilkan.
Apakah C ++ cocok untuk MCU tertanam? Ya, selama Anda mengawasi kode yang dihasilkan.
Inilah mengapa saya berpikir bahwa C ++ lebih baik daripada C bahkan pada MCU 8-bit: C ++ memberikan peningkatan dukungan untuk:
Tidak satu pun dari fitur ini yang lebih berat daripada fitur khas C.
Ketika Anda naik ke 16 atau 32 bit MCU, maka mulai masuk akal untuk menggunakan fitur C yang lebih berat (stack, heap, pointer, array, printf, dll.) Dengan cara yang sama, pada MCU yang lebih kuat menjadi tepat. untuk menggunakan fitur C ++ yang lebih berat (tumpukan, tumpukan, referensi, STL, baru / hapus).
Jadi, tidak perlu ngeri membayangkan C ++ pada PIC16. Jika Anda tahu bahasa Anda dan MCU Anda dengan benar, maka Anda akan tahu bagaimana menggunakannya secara efektif bersama-sama.
sumber
a[i] = b[j] * c[k];
dapat menghasilkan sekitar 4 halaman instruksi tergantung pada sifat dari variabel-variabel itu." Jika MCU / kompiler Anda melakukan ini, itu karena Anda menggunakan beberapa CPU hobi garasi dari tahun 80-an.Saya selalu menemukan debat yang menghibur untuk dibaca. Tidak begitu banyak untuk diskusi intelektual tentang pro dan kontra dari berbagai bahasa yang tersedia tetapi karena Anda biasanya dapat mematok sikap seseorang pada topik berdasarkan pekerjaan / pengalaman / bidang minat mereka. Itu tepat di sana dengan argumen "optimasi prematur" adalah jurusan CS dan programer pemeliharaan mengutip Knuth kiri dan kanan dan mereka yang bekerja di dunia nyata di mana masalah kinerja berpikir mereka semua gila (saya anggota grup terakhir) untuk bersikap adil).
Pada akhirnya, Anda dapat mengembangkan perangkat lunak yang sangat baik dalam C atau C ++ atau memasukkan bahasa di sini . Itu datang ke kemampuan pengembang bukan bahasa. Menjadi ahli dalam suatu bahasa biasanya hanya diperlukan jika Anda telah memilih bahasa yang salah untuk memulai dan sekarang perlu membengkokkannya untuk menyelesaikan masalah Anda, dalam kebanyakan kasus ini adalah satu-satunya situasi di mana Anda perlu menyelam ke fitur yang tidak jelas atau kompiler trik untuk mencapai tujuan.
Saya sering mendengar orang memulai argumen ini sebagai "Saya seorang ahli dalam bahasa X dan bla bla" Jujur saya segera mendiskreditkan orang-orang ini karena, menurut pendapat saya, mereka sudah mendekati masalah dari sudut yang salah dan semuanya setelah itu ternoda oleh keinginan mereka untuk menggunakan alat mereka untuk memecahkan masalah dan menunjukkan betapa 'kerennya itu'.
Saya sering melihat pengembang memilih alat yang ditetapkan terlebih dahulu dan berusaha membengkokkannya ke masalah mereka yang kedua, yang sepenuhnya salah dan menghasilkan solusi omong kosong.
Seperti yang saya sebutkan dalam komentar untuk jawaban lain, perang bahasa ini sering beralih ke argumen bahwa bahasa X memungkinkan programmer untuk melakukan lebih banyak hal bodoh. Sambil menghibur untuk membaca, semua pernyataan ini benar-benar berarti bahwa Anda memiliki masalah dalam merekrut pengembang yang baik dan perlu untuk mengatasi masalah itu secara langsung daripada mencoba untuk membantu situasi dengan terus merekrut pengembang yang buruk dan memilih alat sehingga mereka dapat melakukan sedikit Kerusakan mungkin.
Menurut pendapat saya pengembang yang baik, baik itu pengembangan perangkat lunak atau perangkat keras, riset masalah, arsitek solusi dan temukan alat yang memungkinkan mereka mengekspresikan solusi dengan 'cara terbaik'. Seharusnya tidak masalah jika alat yang diperlukan adalah sesuatu yang belum pernah Anda gunakan sebelumnya, setelah Anda menggunakan 3-4 bahasa / alat pengembangan untuk proyek mengambil yang baru harus memiliki dampak minimal pada waktu pengembangan Anda.
Tentu saja, 'cara terbaik' adalah istilah subyektif dan juga perlu didefinisikan dalam fase penelitian. Orang perlu mempertimbangkan banyak masalah: kinerja, kemudahan berekspresi, kepadatan kode, dll berdasarkan masalah yang dihadapi. Saya tidak memasukkan perawatan dalam daftar itu karena suatu alasan, saya tidak peduli bahasa apa yang Anda pilih, jika Anda memilih alat yang tepat dan meluangkan waktu untuk memahami masalah ini harusnya 'gratis'. Sulit untuk mempertahankan kode sering merupakan hasil dari memilih alat yang salah atau struktur sistem yang buruk, ini mengakibatkan kekacauan yang jelek untuk membuatnya berfungsi.
Mengklaim bahasa apa pun 'lebih baik' daripada yang lain adalah konyol tanpa mendefinisikan masalah minat tertentu. Pendekatan berorientasi objek tidak selalu lebih baik dari pendekatan fungsional. Ada beberapa masalah yang cocok untuk paradigma desain berorientasi objek. Ada banyak yang tidak. Pernyataan yang sama dapat dibuat tentang banyak fitur bahasa yang tampaknya dinikmati orang-orang.
Jika Anda menghabiskan lebih dari 20% waktu Anda untuk masalah mengetik kode, Anda mungkin menghasilkan sistem yang sangat buruk, atau memiliki pengembang yang sangat buruk (atau Anda masih belajar). Anda harus menghabiskan sebagian besar waktu Anda di muka untuk membuat diagram masalah dan menentukan bagaimana berbagai bagian aplikasi berinteraksi. Menempelkan sekelompok pengembang berbakat di ruangan dengan papan penanda dan masalah untuk dipecahkan dan memberi tahu mereka bahwa mereka tidak diperbolehkan menulis kode apa pun atau memilih alat apa pun sampai mereka merasa nyaman dengan keseluruhan sistem akan berbuat lebih banyak untuk meningkatkan kualitas pengembangan keluaran dan kecepatan daripada memilih alat baru yang panas yang dijamin untuk meningkatkan waktu pengembangan. (lihat pengembangan scrum sebagai referensi untuk kebalikan dari argumen saya)
Seringkali kenyataan yang disayangkan adalah bahwa banyak bisnis hanya dapat mengukur nilai pengembang dengan jumlah baris yang ditulis, atau dengan melihat 'hasil nyata'. Mereka melihat 3 minggu di sebuah ruangan dengan papan penanda sebagai kehilangan produktivitas. Pengembang sering dipaksa untuk mempercepat melalui tahap pengembangan 'pemikiran' atau dipaksa menggunakan alat yang ditetapkan oleh beberapa masalah politik dalam perusahaan, "Saudara bos saya bekerja untuk IBM sehingga kami hanya dapat menggunakan alat mereka", sampah semacam itu . Atau lebih buruk, Anda mendapatkan serangkaian persyaratan yang terus berubah dari perusahaan karena mereka tidak mampu melakukan riset pasar yang tepat atau tidak memahami dampak perubahan pada siklus pengembangan.
Maaf karena sedikit keluar dari topik dengan kata-kata kasar ini, saya memiliki pendapat yang cukup kuat tentang topik ini.
sumber
Bahasa apa pun bisa cocok untuk sistem tertanam. Embedded just berarti: bagian dari peralatan yang lebih besar, yang bertentangan dengan komputer yang bebas digunakan.
Pertanyaan ini memiliki relevansi lebih ketika ditanya untuk sistem ( sumber daya waktu nyata) atau sumber daya terbatas (sulit) .
Untuk sistem waktu-nyata C ++ adalah salah satu bahasa tertinggi yang masih sesuai saat pemrograman untuk batasan waktu yang ketat. Dengan pengecualian penggunaan heap (operator gratis), ia tidak memiliki konstruksi yang memiliki waktu eksekusi yang tidak ditentukan, sehingga Anda dapat menguji apakah program Anda memenuhi persyaratan waktu, dan dengan pengalaman yang lebih banyak Anda bahkan dapat memperkirakannya. Penggunaan heap tentu saja harus dihindari, meskipun operator baru masih dapat digunakan untuk alokasi satu kali. Konstruk yang ditawarkan C ++ di atas C dapat digunakan dengan baik di sistem tertanam: OO, pengecualian, templat.
Untuk sistem yang sangat terbatas sumber daya (chip 8-bit, kurang dari beberapa Kb RAM, tidak ada tumpukan yang dapat diakses) C ++ penuh mungkin tidak cocok, meskipun mungkin masih digunakan sebagai 'C yang lebih baik'.
Saya pikir sangat disayangkan bahwa Ada tampaknya hanya digunakan di beberapa ceruk. Dalam banyak hal ini adalah Pascal ++, tetapi tanpa beban untuk menjadi kompatibel dengan bahasa yang sudah berantakan sejak awal. (sunting: kekacauan yang serius tentu saja C. Pascal adalah bahasa yang indah tapi agak tidak praktis.)
================================================== ==============
EDIT: Saya sedang mengetik jawaban untuk pertanyaan baru ("Dalam kasus mana C ++ diperlukan ketika kita sedang memprogram mikrokontroler"?) Yang ditutup merujuk pada yang ini, jadi saya akan menambahkan apa yang saya tulis:
Tidak pernah ada alasan yang sepenuhnya melarang penggunaan bahasa pemrograman apa pun , tetapi mungkin ada argumen yang memiliki bobot lebih atau kurang dalam situasi tertentu. Diskusi tentang ini dapat ditemukan di banyak tempat, dengan posisi yang diambil berkisar dari "tidak pernah menggunakan C ++ untuk mikrokontroler" hingga "selalu menggunakan C ++". Saya lebih banyak dengan posisi terakhir. Saya dapat memberikan beberapa argumen, tetapi Anda harus memutuskan sendiri berapa banyak beban yang mereka bawa dalam situasi tertentu (dan ke arah mana).
Blog saya memiliki beberapa tulisan tentang penggunaan C ++ pada sistem kecil (= pengendali mikro).
sumber
Dalam pengalaman saya, C ++ biasanya tidak cocok untuk sistem embedded kecil. Maksud saya, mikrokontroler dan perangkat tanpa OS.
Banyak teknik C ++ OOP mengandalkan alokasi memori dinamis. Ini sering hilang dalam sistem kecil.
STL dan Boost benar-benar menunjukkan kekuatan C ++, keduanya sangat besar dalam footprint.
C ++ mendorong programmer untuk mengabstraksi mesin, di mana dalam sistem terbatas itu harus dipeluk.
Tahun lalu, saya porting produk desktop remote komersial ke ponsel. Itu ditulis dalam C ++ dan dijalankan pada Windows, Linux dan OSX. Tapi, itu sangat bergantung pada pengecualian STL, memori dinamis dan C ++. Untuk menjalankannya pada WinCE, Symbian dan lingkungan tanpa OS, penulisan ulang C adalah opsi yang paling baik.
sumber
Saya berharap dapat menambahkan lebih banyak cahaya daripada panas pada diskusi ini tentang C ++ pada sistem bare metal dan sumber daya terbatas.
Masalah dalam C ++:
Pengecualian khususnya merupakan masalah RAM karena "buffer darurat" yang diperlukan (di mana pengecualian kehabisan memori misalnya) dapat lebih besar dari RAM yang tersedia dan tentu saja merupakan pemborosan pada mikrokontroler. Untuk info lebih lanjut, lihat n4049 dan n4234 . Mereka harus dimatikan (yang saat ini perilaku yang tidak ditentukan jadi pastikan dan tidak pernah melempar). SG14 saat ini sedang mengerjakan cara yang lebih baik untuk melakukan ini.
RTTI mungkin tidak pernah sebanding dengan overhead, itu harus dimatikan
Membangun debug besar, meskipun ini bukan masalah dalam pengembangan desktop klasik jika debug tidak sesuai pada chip itu bisa menjadi masalah. Masalah muncul dari kode templated atau panggilan fungsi tambahan ditambahkan untuk kejelasan. Panggilan fungsi ekstra ini akan dihapus lagi oleh pengoptimal dan kejelasan atau fleksibilitas yang ditambahkan dapat menjadi keuntungan besar, namun dalam debug membangun ini bisa menjadi masalah.
Alokasi tumpukan. Meskipun STL memungkinkan untuk menggunakan pengalokasi khusus, ini bisa menjadi rumit bagi kebanyakan programmer. Alokasi heap bersifat non deterministik (yaitu bukan waktu nyata yang sulit) dan fragmentasi dapat menyebabkan situasi memori yang tidak terduga terjadi meskipun telah bekerja dalam pengujian. Pembukuan yang dibutuhkan oleh heap untuk melacak ruang kosong dan ukuran yang bervariasi dapat menjadi masalah dengan benda-benda kecil. Biasanya lebih baik menggunakan alokasi pool (baik dalam C dan C ++) tetapi ini bisa abnormal untuk programmer C ++ dulu hanya menggunakan heap.
Polimorfisme Runtime dan panggilan tidak langsung lainnya biasanya merupakan hit kinerja besar, masalahnya biasanya lebih karena pengoptimal tidak dapat melihat melalui mereka lebih dari mengambil dan melompat ke alamat yang sebenarnya. Panggilan tidak langsung harus dihindari karena alasan ini dalam C dan C ++ di mana seperti dalam C ++ mereka lebih tertanam dalam budaya (dan cukup berguna dalam domain lain).
interfacing implisit dengan clib bisa bermasalah. Mungkin berlawanan dengan intuisi bahwa masalah clib berada dalam kategori C ++ tetapi masalahnya muncul dari berbagi sumber daya secara implisit dalam lingkungan bersamaan (berbagi lebih eksplisit dalam C). Penggunaan implementasi newLib yang umum sering kali menyeret banyak mengasapi yang biasanya tidak diperlukan di UC, di sisi lain newLibNanno tidak reentrant sehingga akses ke sana harus diserialisasi (terlalu menyederhanakan sini). Ini juga masalah untuk C tetapi aksesnya lebih eksplisit. Sebagai aturan praktis kita harus menggunakan apa-apa dari namespace std dalam konteks ISR kecuali Anda yakin itu tidak mengakses negara di clib entah bagaimana (errorno atau heap misalnya). Ini juga penting jika Anda menggunakan utas (saya lebih suka RTC) untuk mengganti yang baru dan menghapus untuk menyinkronkan akses ke malloc dan gratis.
Kesimpulannya C ++ memiliki beberapa masalah tetapi pada dasarnya semuanya dapat diperbaiki atau dihindari.
Sekarang untuk C, di sini masalahnya adalah urutan yang lebih tinggi. Saya tidak memiliki kemampuan sintaksis dalam C untuk mengabstraksikan hal-hal sedemikian rupa sehingga saya dapat melakukan optimasi atau memeriksa invarian pada waktu kompilasi. Oleh karena itu saya tidak dapat merangkum hal-hal dengan benar sehingga pengguna tidak perlu tahu cara kerjanya untuk menggunakannya dan sebagian besar deteksi kesalahan saya dilakukan saat runtime (yang tidak hanya terlambat tetapi juga menambah biaya). Pada dasarnya satu-satunya cara untuk menjadi generik dalam C adalah melalui data, saya meneruskan string format ke printf atau scanf yang dievaluasi saat runtime misalnya. Maka sangat sulit bagi kompiler untuk membuktikan bahwa saya tidak menggunakan beberapa opsi yang secara teori dimungkinkan ketika melewati data yang tepat yang berarti potensi pembuatan kode mati dan hilangnya potensi optimisasi.
Saya tahu saya mungkin mengeluarkan shitstorm di sini tapi pengalaman saya pada mikrokontroler 32 bit adalah bahwa dalam sebuah apel dengan perbandingan apel C dan C ++ keduanya ditulis oleh para ahli (seperti dalam C ++ berpotensi sangat templated) C ++ adalah bahasa yang jauh lebih efisien segera setelah semuanya harus sama sekali generik (seperti di perpustakaan mana saja) dan mereka pada dasarnya setara dalam kasus non generik. Juga lebih mudah bagi pemula untuk memanfaatkan keahlian seorang pelaksana perpustakaan ahli dalam C ++.
Pada saat yang sama sebenarnya ada beberapa fungsi yang saya tidak dapat mengirimkan data yang salah, segera setelah input bukan int tetapi
something
saya kebetulan menggunakan int sebagai metode representasi maka ada potensi untuk mendapatkannya salah (memberikan nilai yang tidak valid atau 'otherThing' daripada 'sesuatu'). Di C, satu-satunya metode saya memeriksa apakah pengguna salah adalah saat runtime. Dalam C ++ saya memiliki kemampuan untuk melakukan beberapa pemeriksaan, tidak semua pemeriksaan tetapi beberapa pemeriksaan pada waktu kompilasi yang gratis.Pada akhirnya, tim C seringkali sama kuatnya dengan programmer yang paling lemah dan manfaat kode yang dihasilkan memiliki multipemain 1 atau penalti kinerja. Yang saya maksud dengan ini adalah apakah itu kinerja tinggi untuk satu dan hanya satu pekerjaan unik dalam lingkungan yang unik dari keputusan desain yang unik atau cukup umum untuk digunakan dalam berbagai lingkungan (mikrokontroler lain, strategi manajemen memori lain, latensi lain vs. tradeput trade off dll. dll) tetapi memiliki biaya kinerja yang melekat.
Dalam C ++ hal-hal dapat dirangkum oleh para ahli dan digunakan di banyak lingkungan di mana kompilasi pembuatan kode waktu beradaptasi dengan tugas spesifik dan pengecekan statis membuat pengguna tidak melakukan hal-hal bodoh dengan biaya nol. Di sini kita memiliki jauh lebih sedikit pertukaran antara menjadi generik dan menjadi cepat dan dengan demikian akhirnya dari sudut pandang biaya vs manfaat adalah bahasa yang lebih berkinerja, lebih aman dan lebih produktif.
Ini adalah kritik yang valid bahwa masih ada kekurangan besar pustaka C ++ yang bagus untuk disematkan, ini dapat mengarah pada keputusan pragmatis untuk menggunakan sebagian besar C pada kompiler C ++. Keputusan untuk menggunakan hanya C dalam suatu proyek pada dasarnya baik didorong secara ideologis, karena kebutuhan akan dukungan warisan atau pengakuan bahwa tim tidak cukup disiplin untuk menahan diri dari serangkaian hal-hal bodoh yang sangat dipilih yang dapat dilakukan seseorang dalam C ++ tetapi tidak dalam C dan pada saat yang sama cukup disiplin untuk tidak melakukan hal-hal bodoh yang jauh lebih besar yang tidak dapat dijaga oleh seseorang di C tetapi bisa di C ++.
sumber
Latar belakang saya: baru keluar dari pelatihan sekolah di bawah programmer Bell Labs; telah bekerja selama 3 tahun, 2 di proyek penelitian sarjana; akuisisi data / kontrol proses di VB.NET. Menghabiskan 1,5 tahun melakukan pekerjaan pada aplikasi database perusahaan di VB6. Saat ini sedang mengerjakan proyek untuk PC tertanam dengan penyimpanan 2GB, RAM 512MB, CPU 500MHz x86; beberapa aplikasi berjalan secara bersamaan ditulis dalam C ++ dengan mekanisme IPC di antaranya. Ya saya masih muda.
Pendapat saya: Saya pikir C ++ dapat bekerja secara efektif mengingat lingkungan yang saya tulis di atas . Memang, kinerja real-time yang sulit bukanlah persyaratan untuk aplikasi yang saya gunakan, dan dalam beberapa aplikasi yang disematkan, itu bisa menjadi masalah. Tapi inilah hal-hal yang saya pelajari:
C ++ pada dasarnya berbeda dari C (yaitu, tidak ada C / C ++). Sementara semua yang valid C adalah valid C ++, C ++ adalah bahasa yang sangat berbeda dan orang perlu belajar bagaimana memprogram dalam C ++, bukan C, untuk menggunakannya secara efektif dalam situasi apa pun . Dalam C ++, Anda perlu memprogram berorientasi objek, tidak secara prosedural, dan bukan hibrida dari keduanya (kelas besar dengan banyak fungsi). Secara umum, Anda harus fokus membuat kelas kecil dengan beberapa fungsi, dan menyusun semua kelas kecil menjadi solusi yang lebih besar. Salah satu rekan kerja saya menjelaskan kepada saya bahwa saya dulu memprogram secara prosedural dalam objek, yang merupakan kekacauan besar dan sulit untuk dipertahankan. Ketika saya mulai menerapkan lebih banyak teknik berorientasi objek, saya menemukan pemeliharaan / keterbacaan kode saya meningkat.
C ++ menyediakan fitur tambahan dalam bentuk pengembangan berorientasi objek yang dapat menyediakan cara untuk menyederhanakan kode agar lebih mudah dibaca / dipelihara . Jujur, saya tidak berpikir ada banyak cara peningkatan kinerja / efisiensi ruang dalam melakukan OOP. Tapi saya pikir OOP adalah teknik yang dapat membantu membagi masalah yang kompleks menjadi banyak bagian kecil. Dan itu bermanfaat bagi orang-orang yang mengerjakan kode, sebuah elemen dari proses ini yang tidak boleh diabaikan.
Banyak argumen yang menentang C ++ terutama berkaitan dengan alokasi memori dinamis. C juga memiliki masalah yang sama. Anda dapat menulis aplikasi berorientasi objek tanpa menggunakan memori dinamis, meskipun salah satu manfaat menggunakan objek adalah Anda dapat mengalokasikan hal-hal ini secara dinamis dengan cara yang mudah. Sama seperti di C, Anda harus berhati-hati tentang bagaimana mengelola data untuk mengurangi kebocoran memori, tetapi teknik RAII membuat ini lebih sederhana dalam C ++ (membuat kehancuran memori dinamis secara otomatis dengan mengenkapsulasi dalam objek). Dalam beberapa aplikasi, di mana setiap lokasi memori diperhitungkan, ini mungkin terlalu liar & sulit untuk dikelola.
SUNTING:
sumber
Ya, masalah dengan C ++ adalah peningkatan jejak kode.
Dalam beberapa sistem Anda menghitung byte, dan dalam hal ini Anda harus menerima biaya menjalankan yang dekat dengan batas-batas sistem Anda meningkat biaya pengembangan C.
Tetapi, bahkan dalam C, untuk sistem yang dirancang dengan baik, Anda harus menyimpan segala sesuatu yang terkurung. Sistem yang dirancang dengan baik sulit, dan C ++ memberi programmer tempat untuk metode pengembangan yang sangat terstruktur dan terkontrol. Ada biaya untuk mempelajari OOP, dan jika Anda ingin beralih ke itu Anda banyak menerimanya, dan dalam banyak kasus manajemen lebih suka melanjutkan dengan C dan tidak membayar biaya, karena sulit untuk mengukur hasil dari saklar yang meningkatkan produktivitas. Anda dapat melihat artikel oleh guru sistem tertanam Jack Ganssle di sini .
Manajemen memori dinamis adalah iblis. Tidak juga, iblis adalah auto-route, manajemen memori dinamis bekerja sangat baik pada PC, tetapi Anda dapat berharap untuk me-restart PC setidaknya setiap beberapa minggu. Anda akan menemukan bahwa ketika sistem tertanam terus berjalan selama 5 tahun, manajemen memori dinamis dapat benar-benar kacau dan sebenarnya mulai gagal. Ganssle membahas hal-hal seperti tumpukan dan tumpukan di artikelnya.
Ada beberapa hal dalam C ++ yang lebih rentan menyebabkan masalah dan menggunakan banyak sumber daya, menghapus manajemen memori dinamis dan templat adalah langkah besar untuk menjaga jejak C ++ lebih dekat dengan jejak C. Ini masih C ++, Anda tidak perlu dinamis manajemen memori atau template untuk menulis C ++ yang baik. Saya tidak menyadari mereka menghapus pengecualian, saya menganggap pengecualian sebagai bagian penting dari kode saya yang saya hapus dalam rilis, tetapi gunakan sampai saat itu. Dalam pengujian lapangan saya dapat memiliki pengecualian yang menghasilkan pesan untuk memberitahu saya tentang pengecualian yang ditangkap.
sumber
Saya pikir ini anti-C ++ kata-kata kasar oleh Linus Torvalds menarik.
Dia tidak berbicara tentang dunia sistem tertanam, tetapi pengembangan kernel Linux. Bagi saya, relevansinya berasal dari ini: C ++ memerlukan pemahaman konteks yang lebih luas, dan saya bisa belajar menggunakan seperangkat templat objek, saya tidak percaya diri untuk mengingatnya ketika saya harus memperbarui kode dalam beberapa bulan.
(Di sisi lain, saya saat ini sedang bekerja pada perangkat yang tertanam menggunakan Python (bukan C ++, tetapi menggunakan paradigma OOP yang sama) yang akan memiliki masalah itu. Dalam pertahanan saya, ini adalah sistem tertanam yang cukup kuat untuk disebut PC 10 tahun yang lalu.)
sumber
Saya pikir jawaban lain membuat kasus yang cukup baik untuk pro dan kontra dan faktor keputusan, jadi saya ingin meringkas dan menambahkan beberapa komentar.
Untuk mikrokontroler kecil (8-bit), tidak mungkin. Anda hanya meminta untuk melukai diri sendiri, tidak ada keuntungan dan Anda akan memberikan terlalu banyak sumber daya.
Untuk mikrokontroler kelas atas (mis. 32-bit, 10-an atau 100-an MB untuk RAM dan penyimpanan) yang memiliki OS yang layak, itu sangat oke dan, saya berani mengatakan, bahkan direkomendasikan.
Jadi pertanyaannya adalah: di mana batasnya?
Saya tidak tahu pasti, tetapi begitu saya mengembangkan sistem untuk UC 16-bit dengan 1 MB RAM & 1 MB penyimpanan di C ++, hanya untuk menyesal nanti. Ya, itu berhasil, tetapi pekerjaan ekstra yang saya miliki tidak sepadan. Saya harus membuatnya pas, memastikan hal-hal seperti pengecualian tidak akan menghasilkan kebocoran (dukungan OS + RTL cukup buggy dan tidak dapat diandalkan). Selain itu, aplikasi OO biasanya melakukan banyak alokasi kecil, dan biaya overhead untuk itu adalah mimpi buruk lain.
Mengingat pengalaman itu, saya akan menganggap untuk proyek-proyek masa depan bahwa saya akan memilih C ++ hanya dalam sistem setidaknya 16-bit, dan dengan setidaknya 16 MB untuk RAM & penyimpanan. Itu batas yang sewenang-wenang, dan mungkin akan bervariasi sesuai dengan hal-hal seperti jenis aplikasi, gaya pengkodean dan idiom, dll. Tetapi mengingat peringatan, saya akan merekomendasikan pendekatan yang sama.
sumber
Ada beberapa fitur C ++ yang berguna dalam sistem embedded. Ada yang lain, seperti pengecualian, yang bisa mahal, dan yang biayanya tidak selalu jelas.
Jika saya memiliki pemabuk saya, akan ada bahasa populer yang menggabungkan yang terbaik dari kedua dunia, dan termasuk beberapa fitur yang kurang dalam kedua bahasa; beberapa vendor menyertakan beberapa fitur seperti itu, tetapi tidak ada standar. Beberapa hal yang ingin saya lihat:
Saya tahu bapak C ++ tidak terlalu tertarik pada versi khusus C ++ yang tertanam, tapi saya pikir itu bisa menawarkan beberapa perbaikan yang cukup besar daripada hanya menggunakan C.
Adakah yang tahu jika sesuatu seperti di atas dipertimbangkan untuk semua jenis standar?
sumber
C ++ lebih dari satu bahasa pemrograman:
a) Ini "lebih baik" C b) Ini adalah bahasa yang berorientasi objek c) Ini adalah bahasa yang memungkinkan kita untuk menulis program generik
Meskipun semua fitur ini dapat digunakan secara terpisah, hasil terbaik dicapai ketika ketiganya digunakan secara bersamaan. Meskipun demikian, jika Anda memilih untuk memilih salah satunya saja, kualitas perangkat lunak yang disematkan akan meningkat.
a) Ini "lebih baik" C
C ++ adalah bahasa yang diketik dengan kuat; lebih kuat dari C. Program Anda akan mendapat manfaat dari fitur ini.
Beberapa orang takut akan petunjuk. C ++ termasuk referensi. Fungsi kelebihan beban.
Dan layak untuk dikatakan: Tidak satu pun dari fitur ini muncul dalam program yang lebih besar atau lebih lambat.
b) Bahasa ini berorientasi pada objek
Seseorang berkata dalam posting ini bahwa mengabstraksikan mesin dalam mikrokontroler bukanlah ide yang baik. Salah! Kita semua, para insinyur yang tertanam, selalu mengabstraksi mesin, hanya dengan sintaks lain yang dari C ++. Masalah yang saya lihat dengan argumen ini adalah bahwa beberapa programmer tidak terbiasa berpikir dalam objek, dengan begitu mereka tidak melihat manfaat dari OOP.
Setiap kali Anda siap untuk menggunakan perangkat mikrokontroler, kemungkinan perangkat tersebut telah diabstraksikan untuk kami (dari Anda sendiri atau pihak ketiga) dalam bentuk driver perangkat. Seperti yang saya katakan sebelumnya, driver itu menggunakan sintax C, seperti contoh berikut menunjukkan (diambil langsung dari contoh NXP LPC1114):
/ * Pengaturan timer untuk pertandingan dan interupsi di TICKRATE_HZ * /
Chip_TIMER_Reset (LPC_TIMER32_0);
Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);
Chip_TIMER_SetMatch (LPC_TIMER32_0, 1, (timerFreq / TICKRATE_HZ2));
Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);
Chip_TIMER_Enable (LPC_TIMER32_0);
Apakah Anda melihat abstraksi? Jadi, ketika menggunakan C ++ untuk tujuan yang sama, abstraksi dibawa ke tingkat berikutnya melalui mekanisme abstraksi dan enkapsulasi C ++, tanpa biaya!
c) Ini adalah bahasa yang memungkinkan kita untuk menulis program generik
Program generik dicapai melalui templat, dan templat juga tidak memiliki biaya untuk program kami.
Selain itu, polimorfisme statis dicapai dengan templat.
Metode virtual, RTTI, dan pengecualian.
Ada kompromi ketika menggunakan metode virtual: perangkat lunak yang lebih baik vs beberapa penalti dalam kinerja. Namun, ingat bahwa pengikatan dinamis kemungkinan akan diimplementasikan menggunakan tabel virtual (array pointer fungsi). Saya telah melakukan hal yang sama di C berkali-kali (bahkan secara teratur), jadi saya tidak melihat kekurangan dalam menggunakan metode virtual. Selain itu, metode virtual dalam C ++ lebih elegan.
Akhirnya, saran tentang RTTI dan pengecualian: JANGAN GUNAKAN MEREKA dalam sistem embedded. Hindari mereka sama sekali !!
sumber
Latar belakang saya, tertanam (mcu, pc, unix, lainnya), realtime. Keselamatan penting. Saya memperkenalkan majikan sebelumnya ke STL. Saya tidak melakukan itu lagi.
Beberapa konten Api
Apakah C ++ cocok untuk embedded system?
Ah. C ++ adalah rasa sakit untuk menulis dan rasa sakit untuk dipertahankan. C + agak baik-baik saja (jangan gunakan beberapa fitur)
C ++ di Mikrokontroler? RTOS? Pemanggang roti? PC Tertanam?
Sekali lagi saya katakan Meh. C + tidak terlalu buruk, tetapi ADA tidak terlalu menyakitkan (dan itu benar-benar mengatakan sesuatu). Jika Anda beruntung seperti saya, Anda bisa melakukan embedded Java. Akses array diperiksa dan tidak ada aritmatika pointer membuat kode yang sangat andal. Pengumpul sampah di Jawa yang disematkan bukan prioritas tertinggi, dan ada ruang lingkup memori dan penggunaan kembali objek, sehingga kode yang dirancang dengan baik dapat berjalan selamanya tanpa GC.
Apakah OOP bermanfaat pada mikrokontroler?
Tentu saja. UART adalah sebuah objek ..... DMAC adalah sebuah objek ...
Mesin Object State sangat mudah.
Apakah C ++ menghapus programmer terlalu jauh dari perangkat keras untuk menjadi efisien?
Kecuali itu PDP-11, C bukan CPU Anda. C ++ awalnya merupakan preprocessor ontop C sehingga Bjarne Stroustrup akan berhenti ditertawakan karena memiliki simulasi Simula yang lambat saat di AT&T. C ++ bukan CPU Anda.
Dapatkan MCU yang menjalankan bytecodes java. Program di Jawa. Tertawa pada teman-teman C.
Haruskah Arduino C ++ (tanpa manajemen memori dinamis, templat, pengecualian) dianggap sebagai "nyata C ++"?
Nggak. sama seperti semua kompiler C bastardised di luar sana untuk MCU.
Keempat, Embedded Java atau Embedded ADA distandarisasi (ish); yang lainnya adalah kesedihan.
sumber
Sistem tertanam dirancang untuk melakukan beberapa tugas tertentu, alih-alih menjadi komputer tujuan umum untuk banyak tugas. Sistem tertanam adalah kombinasi perangkat keras dan perangkat lunak komputer. C adalah ibu dari semua bahasa modern. Ini adalah bahasa tingkat rendah tetapi penuh daya dan menangani semua jenis perangkat keras. Jadi C / C ++ adalah pilihan optimal untuk mengembangkan perangkat lunak untuk sistem embedded, yang sangat penuh digunakan untuk setiap sistem embedded. Seperti yang kita tahu C adalah bahasa berkembang. Sistem operasi UNIX ditulis dalam bahasa C. Karena pengembangan perangkat lunak yang sukses sering kali mengenai pemilihan bahasa terbaik untuk proyek yang diberikan, sangat mengejutkan menemukan bahwa bahasa C / C ++ telah terbukti cocok untuk prosesor 8-bit dan 64-bit. ; dalam sistem dengan byte, kilobyte, dan megabita memori. C memiliki keunggulan independensi prosesor, yang memungkinkan programmer untuk berkonsentrasi pada algoritma dan aplikasi, bukan pada detail arsitektur prosesor tertentu. Namun, banyak dari keunggulan ini berlaku untuk bahasa tingkat tinggi lainnya. Tapi C / C ++ berhasil dimana banyak bahasa lain gagal?
sumber
<rant>
Saya pikir C ++ adalah bahasa yang jelek di tempat pertama. Jika Anda ingin menggunakan OOP, tulislah program Java. C ++ tidak melakukan apa pun untuk menegakkan paradigma OOP, karena akses memori langsung sepenuhnya berada dalam kekuasaan Anda untuk (ab) digunakan.
Jika Anda memiliki MCU, Anda berbicara tentang kemungkinan besar memori flash kurang dari 100kB. Anda ingin memprogram dalam bahasa yang abstraksi memori: ketika saya mendeklarasikan variabel atau array, ia mendapat memori, titik; malloc (alias kata kunci "baru" dalam C ++) harus lebih atau kurang dilarang digunakan dalam perangkat lunak yang disematkan, kecuali mungkin dalam beberapa kesempatan satu panggilan selama startup program.
Sial, ada (sering) kali dalam pemrograman tertanam di mana C tidak cukup tingkat rendah, dan Anda perlu melakukan hal-hal seperti mengalokasikan variabel ke register, dan menulis inline assembly untuk memperketat rutinitas layanan interupsi Anda (ISR). Kata kunci seperti "volatile" menjadi sangat sangat penting untuk dipahami. Anda menghabiskan banyak waktu memanipulasi memori pada level bit , bukan level objek .
Mengapa Anda ingin menipu diri sendiri dengan berpikir bahwa segala sesuatunya lebih sederhana daripada kenyataannya?
</rant>
sumber