Alat atau standar apa yang dapat digunakan untuk meningkatkan keandalan kode C tertanam?


9

Saya biasanya memprogram PIC dalam C, biasanya untuk konverter mode yang diaktifkan. Saya pernah mendengar tentang berbagai alat analisis statis dan standar seperti MISRA C yang dapat digunakan untuk membantu meningkatkan keandalan kode. Saya ingin tahu lebih banyak. Standar atau alat apa yang mungkin sesuai untuk konteks saya?


1
Seberapa banyak Anda menggunakan bahasa C?
Brian Drummond

1
Saya bisa dibujuk untuk beralih ke hal lain jika ada kasus yang sangat bagus untuk dibuat. Tapi itu harus menjadi kasus yang sangat bagus.
Stephen Collings

"Kasus yang sangat bagus" untuk beralih dari C tidak dapat dibuat dengan cepat, dan untuk PIC, mungkin belum sama sekali. Untuk AVR, ARM, atau MSP430, Ada akan layak untuk dilihat secara serius (meskipun negativitas menarik, seperti yang Anda lihat!) Dan untuk rel tinggi, SPARK patut dilihat.
Brian Drummond

Anda mungkin menemukan ini menarik sebagai informasi latar belakang: SPARK vs MISRA-C spark-2014.org/entries/detail/… dan studi kasus yang sedang berlangsung ini: spark-2014.org/uploads/Nosegearpaper_1.pdf
Brian Drummond

Mungkin waktu yang lebih baik diinvestasikan untuk membuat kasus untuk beralih dari PIC ke sesuatu yang modern ... Terutama jika Anda merancang jenis sistem mission-critical yang awalnya dimaksudkan untuk MISRA dan SPARK.
Lundin

Jawaban:


11

Validasi kode tertanam sulit, terutama ketika berhadapan dengan bagian sumber daya terbatas seperti PIC. Anda sering tidak memiliki kemewahan pengkodean dalam kasus uji karena kendala memnry bagian dan pemrograman "real-time" yang sering dilakukan pada perangkat semacam ini.

Berikut ini beberapa pedoman saya:

  1. Tulis spec jika tidak ada: Jika Anda tidak mengkode terhadap spec, dokumentasikan apa yang seharusnya kode Anda, apa input yang valid, apa output yang diharapkan, berapa lama setiap rutin mengambil, apa yang bisa dan tidak bisa dapatkan musnah, dll - teori operasi, diagram alur, segala sesuatu lebih baik daripada tidak sama sekali.

  2. Komentari kode Anda: Hanya karena sesuatu sudah jelas bagi Anda, tidak berarti bahwa kode itu jelas (atau benar) untuk orang lain. Komentar dalam bahasa biasa diperlukan untuk peninjauan dan pemeliharaan kode.

  3. Kode bertahan: Jangan hanya memasukkan kode untuk input normal. Menangani input yang hilang, input yang berada di luar jangkauan, luapan matematis, dll. - semakin banyak sudut yang Anda cakup oleh desain kode Anda, semakin sedikit derajat kebebasan yang dimiliki kode ketika digunakan.

  4. Gunakan alat analisis statis: Dapat merendahkan berapa banyak alat bug seperti PC-lint dapat ditemukan dalam kode Anda. Pertimbangkan menjalankan analisis statis bersih sebagai titik awal yang baik untuk pengujian serius.

  5. Ulasan rekan sangat penting: Kode Anda harus bersih dan cukup terdokumentasi sehingga dapat ditinjau secara efisien oleh pihak independen. Periksa ego Anda di pintu dan pertimbangkan dengan serius kritik atau saran apa pun yang dibuat.

  6. Pengujian sangat penting: Anda harus melakukan validasi sendiri, serta memiliki validasi independen terhadap kode. Orang lain dapat memecahkan kode Anda dengan cara yang tidak mungkin Anda bayangkan. Uji setiap kondisi valid dan setiap kondisi tidak valid yang dapat Anda pikirkan. Gunakan PRNG dan masukkan data sampah. Lakukan apa saja untuk memecahkan masalah, lalu perbaiki dan coba lagi. Jika Anda beruntung, Anda akan dapat menjalankan kode Anda dalam mode debug dan mengintip register dan variabel - jika tidak, Anda harus menggunakan LED / sinyal digital yang licik dan bergantian untuk mendapatkan gambaran tentang keadaan komputer Anda. alat. Lakukan apa pun yang diperlukan untuk mendapatkan umpan balik yang Anda butuhkan.

  7. Lihat di bawah kap: Jangan takut untuk melihat kode mesin yang dihasilkan oleh kompiler C Anda. Anda dapat (akan?) Menemukan tempat-tempat di mana kode C indah Anda telah meledak menjadi puluhan jika tidak ratusan operasi, di mana sesuatu yang harus aman (karena hanya satu baris kode, kan?) Membutuhkan waktu lama untuk mengeksekusi beberapa gangguan telah memecat dan membatalkan persyaratan. Jika sesuatu menjadi sangat tidak efisien, refactor dan coba lagi.


+1 Semua saran suara. Saya berharap setiap pengembang firmware profesional hanya tersenyum dan mengangguk ketika membaca ini.
Lundin

2
Aspek penting dari peer review adalah bahwa review adalah tentang kode, bukan tentang programmer. Jika Anda menganalisis kode dengan istilah seperti "pertama saya lakukan ini, maka saya lakukan itu", Anda mungkin dalam masalah. "Pertama kode melakukan ini, lalu melakukannya" adalah cara yang tepat untuk memikirkannya. Dan hal yang sama berlaku untuk pengulas: bukan "mengapa Anda melakukan ini?", Tetapi "mengapa kode melakukan ini?".
Pete Becker

Anda juga dapat mempertimbangkan untuk menambahkan: 1. Menggunakan pemeriksaan Kompleksitas Cyclomatic 2. Perangkat lunak kontrol versi
AlphaGoku

4

Sebagian besar teknik yang sama untuk membuat perangkat lunak yang andal di PC juga berlaku untuk pengembangan yang disematkan. Sangat membantu untuk memisahkan algoritma Anda dari kode khusus perangkat keras, dan menguji mereka secara terpisah dengan unit test, simulasi, analisis statis, dan alat-alat seperti Valgrind. Dengan begitu ada jauh lebih sedikit kode yang hanya diuji pada perangkat keras.

Saya tidak akan meninggalkan C. Sementara bahasa seperti Ada dapat menawarkan beberapa jaminan kecil, mudah untuk jatuh ke dalam jebakan berpikir bahasa yang dijanjikan lebih dari yang sebenarnya.


Namun Valgrid mungkin sedikit lebih relevan untuk PC daripada MCU 8-bit, :)
Lundin

Sayangnya beberapa teknik untuk membuat perangkat lunak tingkat PC yang baik sangat tidak cocok untuk micros kecil, dan beberapa praktik yang dianggap Buruk dan Salah pada lahan PC sangat dapat diterima di lingkungan tertanam.
John U

3

MISRA-C memang sangat berguna untuk meningkatkan kualitas kode umum dan meminimalkan bug. Pastikan Anda membaca dan memahami setiap aturan, sebagian besar dari mereka baik, tetapi beberapa dari mereka tidak masuk akal.

Sebuah peringatan di sini. Dokumen MISRA mengasumsikan bahwa pembaca adalah seseorang dengan pengetahuan luas tentang bahasa C. Jika Anda tidak memiliki veteran C yang keras di tim Anda, tetapi memutuskan untuk mendapatkan penganalisa statis dan kemudian secara membabi buta mengikuti setiap peringatan yang diberikan, kemungkinan besar akan menghasilkan kode kualitas yang lebih rendah , karena Anda mungkin mengurangi keterbacaan dan membuat bug secara tidak sengaja. Saya sudah sering melihat ini terjadi, mengonversi kode ke kepatuhan MISRA bukanlah tugas sepele.

Ada dua versi dokumen MISRA-C yang mungkin berlaku. Baik MISRA-C: 2004, yang masih menjadi standar industri de facto saat ini. Atau MISRA-C baru: 2012 yang mendukung standar C99. Jika Anda belum pernah menggunakan MISRA-C sebelumnya, saya akan merekomendasikan Anda untuk mengimplementasikan yang terakhir.

Perlu diketahui bahwa vendor alat biasanya merujuk ke MISRA-C: 2004 ketika mereka mengatakan bahwa mereka memiliki pengecekan MISRA (kadang-kadang mereka bahkan merujuk ke versi MISRA-C: 1998 yang sudah usang). Sejauh yang saya tahu, dukungan alat untuk MISRA-C: 2012 masih terbatas. Saya pikir hanya beberapa analisa statis yang telah mengimplementasikannya sejauh ini: Klocwork, LDRA, PRQA dan Polyspace. Mungkin lebih, tetapi Anda pasti perlu memeriksa versi MISRA yang didukungnya.

Sebelum memutuskan, tentu saja Anda dapat mulai dengan membaca dokumen MISRA dan melihat apa yang disyaratkan. Ini dapat dibeli seharga £ 10 dari misra.org , cukup terjangkau dibandingkan dengan harga untuk standar ISO.


1

Mathworks (orang-orang MATLAB) memiliki alat analisis kode statis yang disebut Polyspace .

Selain analisis kode statis, serat dan sejenisnya, saya akan menyarankan definisi dan desain antarmuka yang cermat (dengan proses peninjauan formal) dan analisis cakupan kode.

Anda mungkin juga ingin melihat pedoman untuk desain kode kritis keselamatan, termasuk MISRA, tetapi juga standar UL1998, dan IEC 61508.


Saya tidak merekomendasikan pergi dekat IEC 61508 kecuali Anda harus. Itu memang menyebutkan perangkat lunak, tetapi tidak memiliki sumber ilmiah modern untuk klaimnya. Standar itu datang terlambat 30 tahun - seandainya dirilis pada tahun 70-an seperti sebagian besar yang disebut "sumber", mungkin bermanfaat.
Lundin

1

Untuk jawaban yang lengkap untuk pertanyaan ini, saya akan menekan pemikiran tentang "keandalan kode" dan alih-alih memikirkan "keandalan desain", karena kode tersebut hanyalah ekspresi akhir dari desain.

Jadi, mulailah dengan persyaratan dan tulis serta periksa itu. Jika Anda tidak memiliki dokumen persyaratan, tunjukkan kode acak dan tanyakan pada diri sendiri "mengapa baris itu diperlukan?" Kebutuhan untuk setiap baris kode pada akhirnya harus dapat dilacak ke persyaratan, bahkan jika sesederhana / sejelas "catu daya akan menghasilkan 5VDC jika inputnya antara 12-36VDC." Salah satu cara untuk berpikir tentang hal ini adalah bahwa jika garis kode tidak dapat dilacak ke suatu persyaratan, maka bagaimana Anda tahu itu kode yang benar, atau bahwa itu diperlukan sama sekali?

Selanjutnya, verifikasi desain Anda. Tidak apa-apa jika benar-benar ada dalam kode (misalnya, dalam komentar), tetapi itu membuatnya lebih sulit untuk mengetahui apakah kode tersebut melakukan apa yang benar-benar dimaksudkan. Misalnya, kode mungkin memiliki baris yang bertuliskan output = 3 * setpoint / (4 - (current * 5)); Apakah current == 4/5input yang valid dapat menyebabkan kerusakan? Apa yang harus dilakukan dalam kasus ini untuk mencegah kesenjangan dengan nol? Apakah Anda menghindari operasi sama sekali atau justru menurunkan output? Memiliki catatan umum dalam dokumen desain Anda tentang cara menangani kasing tepi membuatnya lebih mudah untuk memverifikasi desain di tingkat yang lebih tinggi. Jadi, sekarang inspeksi kode lebih mudah karena masalah memeriksa apakah kode tersebut benar mengimplementasikan desain itu.

Bersamaan dengan itu, inspeksi kode harus memeriksa kesalahan umum yang tidak ditangkap oleh IDE Anda (Anda menggunakan IDE, kan?) Seperti '=' ketika Anda bermaksud '==', kawat gigi yang hilang yang mengubah arti 'jika Pernyataan, titik koma di mana mereka seharusnya tidak, dll.

Ketika saya menulis ini, terpikir oleh saya bahwa sangat sulit untuk meringkas tahun pelatihan / pengalaman kualitas perangkat lunak dalam satu posting. Saya menulis kode untuk perangkat medis dan di atas adalah ringkasan yang sangat disederhanakan tentang bagaimana kami mendekatinya.


Pemahaman saya adalah bagian kode dalam perangkat medis diuji hampir seolah-olah itu perangkat yang terpisah. Apakah itu akurat?
Scott Seidman

@ScottSeidman Kemungkinan besar, ini diuji berdasarkan persyaratan, sebagaimana disebutkan dalam jawaban ini. Untuk setiap persyaratan, Anda harus memiliki modul kode, dan untuk setiap modul kode tersebut Anda harus melakukan tes. Jadi pada dasarnya, setiap persyaratan memiliki tes yang sesuai dan kode adalah sarana untuk memenuhi persyaratan. Pelacakan persyaratan semacam ini adalah praktik umum dalam sistem misi-kritis, jauh sebelum kata kunci "TDD" muncul.
Lundin

Saya merujuk secara khusus pada panduan FDA, seperti fda.gov/downloads/RegulatoryInformation/Guidances/ucm126955.pdf Perangkat lunak sebenarnya membutuhkan lebih dari yang Anda kira jika itu bagian dari perangkat medis, mulai dari tahap perencanaan dan kontrol desain.
Scott Seidman

Scott, saya tidak pernah berpikir seperti itu, tetapi Anda benar. Orang-orang dari Jaminan Kualitas Perangkat Lunak kami memverifikasi perangkat lunak secara terpisah dari bagian sistem lainnya (sebanyak mungkin) sebelum menyerahkannya ke grup lain yang bertanggung jawab untuk Verifikasi dan Validasi Sistem.
lyndon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.