Mengapa C mendominasi di pasar perangkat lunak tertanam? [Tutup]

14

Hampir setiap orang sekarang akan mengucapkan berkat:

kinerja !

Oke, C memang memungkinkan untuk menulis kode atletik. Namun, ada bahasa lain yang bisa melakukannya! Dan kekuatan optimalisasi kompiler modern luar biasa. Apakah C memiliki beberapa kelebihan yang tidak dimiliki bahasa lain? Atau sama sekali tidak perlu untuk instrumen yang lebih fleksibel dalam domain?

tanaman merambat
sumber
1
FWIW, Arduino dapat dikontrol dengan C #: arduino.cc/playground/Interfacing/Csharp
FrustratedWithFormsDesigner
@ Frustasi: Ya, tapi itu adalah salah satu contohnya, dan kebanyakan orang membuat perangkat menggunakan Arduino.
Ed S.
2
Lihat juga: stackoverflow.com/questions/812717/…
Steve Melnikoff
1
@ Dan04, dalam sebagian besar kasus, itu sebenarnya bukan masalah. Kelompok simulasi 6DOF di Texas Instruments Defense Systems dan Electronics Group melakukan percobaan kecil sekitar tahun 1988. Sampai saat itu, mereka telah melakukan semua simulasi mereka di FORTRAN. Mereka mencoba menulis satu di PASCAL, untuk melihat seberapa buruk itu akan menyakitkan. Mereka menemukan bahwa PASCAL memberi mereka hit kinerja kecil, tetapi peningkatan keandalan dan kemudahan debugging LEBIH dari pada dibuat untuk itu. Terus terang, mereka menemukan bahwa pengecekan tipe PASCAL yang kuat adalah hal yang BAIK. (Dan ya, mereka sedang melakukan array.)
John R. Strohm

Jawaban:

41

Hampir setiap orang sekarang akan mengucapkan berkat:

kinerja!

Itu bagian dari itu; penggunaan sumber daya deterministik penting pada perangkat dengan sumber daya terbatas untuk memulai, tetapi ada alasan lain.

  1. Akses langsung ke API perangkat keras tingkat rendah.
  2. Anda dapat menemukan kompiler C untuk sebagian besar perangkat ini. Ini tidak benar untuk bahasa tingkat tinggi apa pun dalam pengalaman saya.
  3. C (runtime dan executable yang Anda hasilkan) adalah "kecil". Anda tidak perlu memuat banyak hal ke dalam sistem untuk menjalankan kode.
  4. API / driver perangkat keras kemungkinan akan ditulis dalam C atau C ++.
Ed S.
sumber
14
+1 Ketersediaan kompiler. Kembali ketika kami menulis semuanya dalam kumpulan, kompiler gen pertama adalah dewa-kirim.
Christopher Bibbs
8
+1, saya pikir penggunaan sumber daya deterministik adalah salah satu alasan paling penting. Anda tidak memiliki banyak memori untuk melakukan semua jenis pengumpulan sampah mewah di mesin pencuci piring.
user281377
4
+1 juga untuk "penggunaan sumber daya deterministik". Pada banyak sistem embedded, persyaratan ini bahkan menghalangi penggunaan alokasi memori dinamis. Banyak bahasa lain sangat bergantung pada alokasi memori dinamis (bahkan banyak aspek menguntungkan dari C ++ memerlukan memori dinamis).
Michael Burr
2
Saya akan menambahkan satu poin tambahan, yang ternyata lebih merupakan alasan sosial daripada teknis - saya pikir pengembang perangkat lunak yang disematkan cenderung jauh lebih konservatif dan tahan terhadap perubahan daripada pengembang lain. Tergantung pada sudut pandang Anda, ini bisa menjadi hal yang baik atau buruk.
Michael Burr
1
Berbicara sebagai seorang pria sistem, saya curiga abstraksi besar. Mereka hebat, sampai mereka berhenti bekerja atau melakukan sesuatu yang lucu, dalam hal ini bisa menjadi sakit kepala yang sangat besar untuk debug. Itu bukan sesuatu yang saya inginkan dalam sistem tingkat rendah.
Ed S.
18

C dirancang untuk memodelkan CPU, karena C dibuat untuk membuat Unix portable lintas platform, bukan hanya menulis bahasa assembly.

Ini berarti bahwa program C bekerja dengan baik sebagai bahasa pemrograman untuk program yang perlu memiliki tingkat abstraksi yang sangat dekat dengan CPU yang sebenarnya, yang merupakan kasus untuk perangkat keras tertanam.

Catatan: C dirancang sekitar tahun 1970 dan CPU lebih sederhana saat itu.


sumber
3
1: Ini jelas yang alasan. Mungkin orang telah mencoba merancang bahasa tingkat tinggi yang lebih baru yang menangkap fitur prosesor modern, tetapi tidak ada yang merancang bahasa untuk itu.
Ken Bloom
2
@vines, C adalah bahasa kecil dengan pustaka runtime yang besar. Semua ini dapat dilakukan di perpustakaan runtime. Itu tidak akan bermigrasi secara otomatis ke pustaka C standar sehingga itu adalah platform spesifik.
3
+1. C dibuat untuk, dan awalnya digunakan pada PDP-7, yang memiliki maksimum 64kiloword kata-kata 18-bit. Banyak bahasa "modern" lebih sulit menyesuaikan ruang semacam itu. Terutama untuk menulis OS seperti Unix.
greyfade
2
@ Greyfade: tidak begitu. UNIX berasal dari PDP-7, tetapi C tidak. Mengutip dari kata pengantar untuk Bahasa Pemrograman C : "C pada awalnya dirancang untuk dan diimplementasikan pada sistem operasi UNIX pada DEC PDP-11, oleh Dennis Ritchie."
Jerry Coffin
1
@vines: walaupun tentu saja masuk akal untuk merenungkan dukungan langsung untuk threading dalam bahasa (cf, Concurrent C), sebagian besar poin dari cache adalah membuat lebih cepat tanpa campur tangan programmer atau bahasa.
Jerry Coffin
11

Salah satu alasan dominasi adalah bahwa ia memiliki alat yang tepat untuk tugas tersebut. Setelah dikembangkan di platform tertanam di Java dan C / C ++, saya dapat memberi tahu Anda bahwa pendekatan telanjang ke tulang C ++ lebih alami. Menyelamatkan pengembang dari perasaan bahwa ia sedang melompat-lompat karena bahasa terlalu tinggi adalah hal yang cukup menjengkelkan. Salah satu contoh yang baik adalah tidak adanya variabel yang tidak ditandatangani di Jawa.

Dan fitur-fitur praktis dari VM / bahasa yang ditafsirkan biasanya tidak layak dan ditinggalkan dari implementasi, misalnya pengumpulan sampah.

celebdor
sumber
3
"Java dan C / C ++" - Saya harap Anda maksudkan "ketiganya: Java C dan C ++", karena C dan C ++ adalah bahasa yang berbeda.
BЈовић
1
@ BЈовић: Membalas bertahun-tahun kemudian untuk mengonfirmasi bahwa ya, maksud saya ketiganya. Saya menggunakan kedua definisi berikut ini: "digunakan sebagai kata fungsi untuk menunjukkan dan menekankan penyertaan masing-masing dari dua hal atau lebih" (dua atau lebih hal) :-)
celebdor
10

C membutuhkan dukungan runtime yang sangat sedikit di dalam dan dari dirinya sendiri, sehingga overhead jauh lebih rendah. Anda tidak menghabiskan memori atau penyimpanan pada dukungan runtime, menghabiskan waktu / upaya untuk meminimalkan dukungan itu, atau harus mengizinkannya dalam desain proyek Anda.

geekosaurus
sumber
1
Apakah benar-benar tidak pernah terjadi bahwa Anda memerlukan fungsionalitas itu dan mengubahnya sendiri? Sebagai contoh, mesin negara besar yang dibangun dengan switches mengerikan, dan mesin yang sama dibangun dengan hierarki kelas bagus dan dapat dipertahankan.
tanaman merambat
1
@vines - Anda biasanya memiliki satu set input, mesin negara yang dibangun dengan sakelar / jika tangga lebih jelas dan lebih dapat didokumentasikan daripada heiracrchy magic 'di belakang panggilan polimorfik layar'.
Martin Beckett
2
@ Martin: kepada seseorang dengan sedikit pengalaman dalam pengembangan OO, panggilan polimorfik bukanlah "sihir" atau "di belakang layar", dan gagasan bahwa peralihan besar / jika pernyataan lebih jelas dan lebih dapat didokumentasikan tampaknya sangat aneh.
Michael Borgwardt
3
Temukan apa yang terjadi ketika pin27 menjadi tinggi. Opsi 1, cari "case PIN27:" Opsi 2 menelusuri iterator di atas peta functors untuk menemukan mana yang akan dipanggil untuk objek PIN yang ditugaskan untuk pin 27 saat runtime. Masalah dengan banyak kode OO adalah bahwa satu-satunya cara untuk membacanya adalah dengan menjalankannya. Pada platform tanpa debugging run time atau bahkan konsol yang berarti melacak kode di atas kertas atau di kepala Anda.
Martin Beckett
2
Sedikit menyinggung diskusi ini, ada alasan tangga logika (versi yang bahkan lebih primitif switch, bisa dibilang) masih digunakan di banyak aplikasi embedded. Lebih mudah di-debug, lebih mudah diverifikasi.
geekosaur
9

Seperti disebutkan dalam jawaban lain, C dikembangkan pada awal tahun 1970-an untuk menggantikan bahasa assembly pada arsitektur komputer mini. Saat itu, komputer ini biasanya berharga puluhan ribu dolar, termasuk memori dan periferal.

Saat ini, Anda bisa mendapatkan daya komputer yang sama atau lebih besar dengan mikrokontroler 16-bit tertanam yang harganya empat dolar atau kurang dalam jumlah tunggal - termasuk built-in RAM dan pengontrol I / O. Mikrokontroler 32-bit harganya mungkin satu atau dua dolar lebih.

Ketika saya memprogram orang-orang kecil ini, yang merupakan apa yang saya lakukan 90% dari waktu ketika saya tidak merancang papan tempat mereka duduk, saya suka memvisualisasikan apa yang akan dilakukan prosesor. Jika saya dapat memprogram dengan cukup cepat di assembler, saya akan melakukannya.

Saya tidak ingin segala macam lapisan abstraksi. Saya sering men-debug dengan melangkah melalui daftar dissembler di layar. Jauh lebih mudah untuk melakukannya ketika Anda telah menulis program dalam C untuk memulai.

tcrosley
sumber
1
Untuk beberapa aplikasi yang disematkan, "satu atau dua dolar lebih" itu sangat signifikan. Tidak ada yang akan memperhatikan dampak harga pada mobil mereka, tetapi mereka akan pada termostat atau pemutar CD mereka.
David Thornley
3
@ David Thornley, ya, setuju sepenuhnya, itu sebabnya saya saat ini memiliki proyek dengan 8, 16, dan 32-bit micros semua pada saat yang sama untuk klien yang berbeda. (Konsumsi daya adalah alasan lain untuk menggunakan perangkat yang lebih kecil.)
tcrosley
1
Harga ditentukan lebih sedikit oleh biaya prosesor daripada jumlah pin. Papan jauh lebih mahal daripada chip.
Yttrill
7

Itu tidak sepenuhnya mendominasi karena C ++ semakin banyak digunakan karena kompiler telah meningkat dan kinerja perangkat keras telah meningkat. Namun C masih sangat populer karena beberapa alasan;

  1. Dukungan luas. Hampir setiap vendor chip menyediakan kompiler ac dan setiap kode contoh dan driver kemungkinan akan ditulis dalam c. Kompiler C ++ semakin umum, tetapi bukan sertifikat mati untuk chip yang diberikan, dan mereka sering buggier. Anda juga tahu bahwa setiap insinyur yang disematkan akan dapat bekerja di c. Ini adalah bahasa perindustrian.

  2. Performa. Yup, Anda mengatakannya. Kinerja masih raja dan dalam lingkungan di mana rutinitas inti masih sering ditulis dalam assembler, atau setidaknya dioptimalkan dalam c dengan mengacu pada output perakitan, tidak pernah meremehkan pentingnya ini. Seringkali target yang disematkan akan berbiaya sangat rendah dan memiliki ingatan yang sangat kecil dan beberapa mips.

  3. Ukuran. C ++ cenderung lebih besar. Tentunya apapun yang menggunakan STL akan lebih besar. Umumnya baik dari segi ukuran program dan jejak memori.

  4. Konservatisme. Ini adalah industri yang sangat konservatif. Sebagian karena biaya kegagalan seringkali lebih tinggi dan debugging sering kurang dapat diakses, sebagian karena itu tidak perlu diubah. Untuk proyek tertanam kecil c melakukan pekerjaan dengan baik.

Luke Graham
sumber
11
Lihat, itu # 3 yang tampaknya menjadi salah satu mitos paling lazim di sekitar tentang C ++. Tulis wadah yang aman untuk 5 jenis berbeda di C dan Anda akan menyebabkan setidaknya "mengasapi" menggunakan wadah STL tunggal pada 5 jenis yang berbeda. Pemrogram C menyiasatinya dengan menulis wadah pada jenis buram (batal *). Membandingkan THAT dengan templat STL adalah kesalahan kategori. Meskipun harus mengakui bahwa itu memang salah satu "alasan" yang paling umum untuk memilih C.
Edward Strange
Saya sepenuhnya setuju bahwa untuk meniru fungsionalitas penuh di c Anda berakhir dengan jejak yang sama seperti c ++. 'Keuntungan' dari c adalah memungkinkan Anda untuk selektif. Pada setiap proyek penting saya lebih suka menggunakan c ++, tetapi kadang-kadang perangkat keras target dibatasi ke titik di mana itu tidak praktis. Setelah mengatakan bahwa # 1 benar-benar alasan utama dalam pengalaman saya.
Luke Graham
6

Untuk sistem embedded, yang paling penting adalah kinerja . Tapi seperti yang Anda katakan, mengapa C dan bukan bahasa pemain lainnya?

Banyak orang sejauh ini menyebutkan ketersediaan kompiler , tetapi tidak ada yang menyebutkan ketersediaan pengembang . Lebih banyak pengembang yang sudah tahu C daripada, katakanlah, OCaml.

Mereka adalah tiga biggies.

BlueRaja - Danny Pflughoeft
sumber
6

Perangkat lunak tertanam sangat berbeda.

Pada aplikasi desktop, abstraksi dan perpustakaan menghemat banyak waktu pengembangan. Anda memiliki kemewahan melempar pasangan lain megabita atau gigabita RAM atau sekitar 2 + GHz 64-bit core CPU pada suatu masalah, dan orang lain (pengguna) membayar untuk perangkat keras itu. Anda mungkin tidak tahu sistem apa yang akan dijalankan aplikasi.

Dalam proyek tertanam, sumber daya seringkali sangat terbatas. Dalam satu proyek saya bekerja pada (prosesor seri 17X-PIC) perangkat keras memiliki 2Kwords memori program, 8 tingkat (in-hardware) stack dan 192 byte (<0,2 kB) RAM. Pin I / O yang berbeda memiliki kemampuan yang berbeda dan Anda mengkonfigurasi perangkat keras sesuai kebutuhan dengan menulis ke register perangkat keras. Debugging melibatkan osiloskop dan penganalisis logika.

Dalam embedded, abstraksi sering menghalangi dan akan mengelola (dan biaya) sumber daya yang tidak Anda miliki. Misalnya kebanyakan sistem embedded tidak memiliki sistem file. Oven microwave adalah sistem tertanam. Pengendali mesin mobil. Beberapa sikat gigi listrik. Beberapa headphone peredam bising.

Salah satu faktor yang sangat penting bagi saya dalam mengembangkan sistem embedded adalah mengetahui dan mengendalikan apa yang diterjemahkan kode dalam hal instruksi, sumber daya, memori dan waktu eksekusi. Seringkali urutan instruksi yang tepat mengontrol mis. Waktu untuk bentuk gelombang antarmuka perangkat keras.

Abstraksi dan 'sihir' di belakang layar (mis. Pengumpul sampah) sangat bagus untuk aplikasi desktop. Pengumpul sampah menghemat BANYAK waktu untuk mengejar kebocoran memori, ketika memori dialokasikan secara dinamis.

Namun di dunia embedded real-time kita perlu tahu dan mengontrol berapa lama, kadang-kadang hingga nanodetik, dan tidak bisa melempar beberapa MB RAM atau CPU yang lebih cepat pada suatu masalah. Salah satu contoh sederhana: ketika melakukan peredupan perangkat lunak LED dengan mengendalikan siklus tugas (CPU hanya memiliki kontrol on / off LED), itu TIDAK OK untuk prosesor untuk pergi dan melakukan mis pengumpulan sampah selama 100 ms karena tampilan akan terlihat flash terang atau keluar.

Contoh yang lebih hipotetis adalah pengontrol mesin yang langsung menyalakan busi. Jika CPU itu mati dan melakukan pengumpulan sampah selama 50 ms, mesin akan berhenti sejenak atau menembak pada posisi poros engkol yang salah, berpotensi mematikan mesin (saat lewat?) Atau merusaknya secara mekanis. Anda bisa membuat seseorang terbunuh.

Technophile
sumber
Itu sama benarnya dengan tidak relevan dengan C - masalah yang Anda rujuk hanyalah perilaku GC ... C ++ tidak memiliki GC, dan tahu apa? Saya pribadi menggunakannya karena komentar garis dan jenis keamanan yang lebih ketat =)
tanaman merambat