Saya kira itu hal yang buruk untuk mencoba men-debug menggunakan proyek berbasis mikrokontroler printf()
.
Saya dapat mengerti bahwa Anda tidak memiliki tempat yang telah ditentukan untuk output, dan bahwa itu dapat mengkonsumsi pin yang berharga. Pada saat yang sama saya telah melihat orang menggunakan pin UART TX untuk keluaran ke terminal IDE dengan DEBUG_PRINT()
makro khusus .
printf
, tentu saja, semua kode yang diperlukan untuk mengimplementasikanprintf
terhubung dengan dieksekusi. Tapi itu karena kode menggunakannya, bukan karena header.Jawaban:
Saya dapat menemukan beberapa kelemahan menggunakan printf (). Ingatlah bahwa "sistem tertanam" dapat berkisar dari sesuatu dengan beberapa ratus byte memori program hingga sistem QNX RTOS yang digerakkan rak-mount penuh dengan gigabytes RAM dan terabyte memori nonvolatile.
Ini membutuhkan tempat untuk mengirim data. Mungkin Anda sudah memiliki port debug atau pemrograman pada sistem, mungkin Anda tidak. Jika Anda tidak (atau yang Anda miliki tidak berfungsi) itu tidak terlalu berguna.
Ini bukan fungsi ringan dalam semua konteks. Ini bisa menjadi masalah besar jika Anda memiliki mikrokontroler dengan hanya beberapa K memori, karena menghubungkan di printf mungkin memakan hingga 4K dengan sendirinya. Jika Anda memiliki mikrokontroler 32K atau 256K, itu mungkin bukan masalah, apalagi jika Anda memiliki sistem tertanam besar.
Ini sedikit atau tidak berguna untuk menemukan beberapa jenis masalah terkait dengan alokasi memori atau interupsi, dan dapat mengubah perilaku program ketika pernyataan dimasukkan atau tidak.
Ini cukup berguna untuk berurusan dengan hal-hal yang sensitif terhadap waktu. Anda akan lebih baik dengan penganalisis logika dan osiloskop atau penganalisa protokol, atau bahkan simulator.
Jika Anda memiliki program besar dan Anda harus mengkompilasi ulang berkali-kali saat Anda mengubah pernyataan printf dan mengubahnya, Anda bisa membuang banyak waktu.
Apa yang baik untuk itu adalah cara cepat untuk menghasilkan data dengan cara yang telah diformat sebelumnya sehingga setiap programmer C tahu cara menggunakan - kurva belajar nol. Jika Anda perlu mengeluarkan matriks untuk filter Kalman yang Anda debug, mungkin lebih baik meludahkannya dalam format yang dapat dibaca MATLAB. Tentunya lebih baik daripada melihat lokasi RAM satu per satu dalam debugger atau emulator .
Saya tidak berpikir itu adalah panah yang tidak berguna dalam quiver, tetapi harus digunakan dengan hemat, bersama dengan gdb atau debugger lainnya, emulator, penganalisa logika, osiloskop, alat analisis kode statis, alat cakupan kode dan sebagainya.
sumber
printf()
implementasi bukan thread-safe (yaitu, non-peserta kembali) yang bukan pembunuh kesepakatan, tetapi sesuatu yang perlu diingat ketika menggunakannya di lingkungan multi-threaded.Selain beberapa jawaban yang bagus lainnya, tindakan mengirim data ke port dengan kecepatan baud serial bisa sangat lambat sehubungan dengan waktu putaran Anda, dan berdampak pada cara sisa fungsi program Anda (seperti halnya debug APA PUN proses).
Seperti yang dikatakan orang lain kepada Anda, tidak ada yang "buruk" tentang penggunaan teknik ini, tetapi memang, seperti banyak teknik debug lainnya, memiliki keterbatasan. Selama Anda tahu dan dapat menangani batasan-batasan ini, ini bisa menjadi kemudahan yang sangat nyaman untuk membantu Anda mendapatkan kode Anda dengan benar.
Sistem tertanam memiliki opacity tertentu yang, secara umum, membuat debugging sedikit masalah.
sumber
Ada dua masalah utama yang akan Anda coba gunakan
printf
pada mikrokontroler.Pertama, mungkin merepotkan untuk mengirimkan output ke port yang benar. Tidak selalu. Tetapi beberapa platform lebih sulit daripada yang lain. Beberapa file konfigurasi dapat didokumentasikan dengan buruk dan banyak eksperimen mungkin diperlukan.
Yang kedua adalah memori.
printf
Perpustakaan yang penuh sesak bisa jadi BESAR. Kadang-kadang Anda tidak memerlukan semua penentu format dan versi khusus dapat tersedia. Misalnya, yangstdio.h
disediakan oleh AVR berisi tigaprintf
ukuran dan fungsi yang berbeda-beda.Saya memiliki contoh di mana tidak ada perpustakaan tersedia dan saya memiliki memori minimal. Jadi saya tidak punya pilihan selain menggunakan makro kustom. Namun penggunaan
printf
atau tidak benar-benar salah satu yang sesuai dengan kebutuhan Anda.sumber
Untuk menambah apa yang Spehro Pefhany katakan tentang "hal-hal yang sensitif terhadap waktu": mari kita ambil sebuah contoh. Katakanlah Anda memiliki giroskop tempat sistem tertanam Anda mengambil 1.000 pengukuran per detik. Anda ingin men-debug pengukuran ini, jadi Anda perlu mencetaknya. Masalah: mencetaknya menyebabkan sistem terlalu sibuk untuk membaca 1.000 pengukuran per detik, yang menyebabkan buffer giroskop meluap, yang menyebabkan data rusak dibaca (dan dicetak). Jadi, dengan mencetak data, Anda telah merusak data, membuat Anda berpikir ada bug dalam membaca data ketika mungkin sebenarnya tidak ada. Apa yang disebut heisenbug.
sumber
Alasan yang lebih besar untuk tidak melakukan debug dengan printf () adalah bahwa biasanya tidak efisien, tidak memadai, dan tidak perlu.
Tidak efisien: printf () dan kin menggunakan banyak flash dan RAM relatif terhadap apa yang tersedia pada mikrokontroler kecil, tetapi inefisiensi yang lebih besar ada dalam debugging yang sebenarnya. Mengubah apa yang sedang dicatat membutuhkan kompilasi ulang dan pemrograman ulang target, yang memperlambat proses. Itu juga menggunakan UART yang bisa Anda gunakan untuk melakukan pekerjaan yang bermanfaat.
Tidak memadai: Hanya ada begitu banyak detail yang dapat Anda hasilkan melalui tautan serial. Jika program hang, Anda tidak tahu persis di mana, hanya output terakhir yang selesai.
Tidak Perlu: Banyak mikrokontroler dapat di-debug jarak jauh. JTAG atau protokol eksklusif dapat digunakan untuk menjeda prosesor, mengintip register dan RAM, dan bahkan mengubah keadaan prosesor yang berjalan tanpa harus mengkompilasi ulang. Inilah sebabnya mengapa debugger umumnya merupakan cara debug yang lebih baik daripada pernyataan cetak, bahkan pada PC dengan banyak ruang dan daya.
Sangat disayangkan bahwa platform mikrokontroler yang paling umum untuk pemula, Arduino, tidak memiliki debugger. AVR mendukung debugging jarak jauh, tetapi protokol debugWIRE Atmel adalah milik dan tidak berdokumen. Anda dapat menggunakan papan dev resmi untuk melakukan debug dengan GDB, tetapi jika Anda memilikinya Anda mungkin tidak terlalu khawatir tentang Arduino lagi.
sumber
printf () tidak berfungsi sendiri. Ini memanggil banyak fungsi lain, dan jika Anda memiliki sedikit ruang stack Anda mungkin tidak dapat menggunakannya sama sekali untuk men-debug masalah yang dekat dengan batas stack Anda. Bergantung pada kompiler dan mikrokontroler, format string juga dapat ditempatkan dalam memori, bukan dirujuk dari flash. Ini dapat bertambah secara signifikan jika Anda membumbui kode Anda dengan pernyataan printf. Ini adalah masalah besar di lingkungan Arduino - pemula yang menggunakan lusinan atau ratusan pernyataan printf tiba-tiba mengalami masalah yang tampaknya acak karena mereka menimpa tumpukan mereka dengan tumpukan mereka.
sumber
Bahkan jika seseorang ingin memuntahkan data ke beberapa bentuk konsol logging,
printf
fungsi ini umumnya bukan cara yang sangat baik untuk melakukan itu, karena itu perlu memeriksa string format yang dikirimkan dan menguraikannya saat runtime; bahkan jika kode tidak pernah menggunakan penentu format apa pun selain%04X
, pengontrol umumnya harus menyertakan semua kode yang akan diperlukan untuk mengurai string format sewenang-wenang. Bergantung pada pengontrol tepat yang digunakan, mungkin jauh lebih efisien untuk menggunakan kode seperti:Pada beberapa mikrokontroler PIC,
log_hexi32(l)
kemungkinan akan mengambil 9 instruksi dan mungkin mengambil 17 (jikal
ada di bank kedua), sementaralog_hexi32p(&l)
akan mengambil 2.log_hexi32p
Fungsi itu sendiri dapat ditulis menjadi sekitar 14 instruksi panjang, sehingga akan membayar sendiri jika dipanggil dua kali .sumber
Satu hal yang tidak ada jawaban lain yang disebutkan: Dalam mikro dasar (IE hanya ada loop utama () dan mungkin beberapa ISR berjalan setiap saat, bukan OS multi-ulir) jika crash / berhenti / mendapat terjebak dalam satu lingkaran, fungsi cetak Anda tidak akan terjadi .
Juga, orang-orang mengatakan "jangan gunakan printf" atau "stdio.h membutuhkan banyak ruang" tetapi tidak memberikan banyak alternatif - embedded.kyle menyebutkan alternatif yang disederhanakan, dan itu adalah hal yang seharusnya Anda lakukan. lakukan sebagai hal yang biasa pada sistem embedded dasar. Rutin dasar untuk menyemprotkan beberapa karakter dari UART dapat berupa beberapa byte kode.
sumber