Saya mencoba mencari cara untuk menggunakan fungsi printf untuk mencetak ke port serial.
Pengaturan saya saat ini adalah kode yang dihasilkan STM32CubeMX dan SystemWorkbench32 dengan papan penemuan STM32F407 .
Saya melihat di stdio.h bahwa prototipe printf didefinisikan sebagai:
int _EXFUN(printf, (const char *__restrict, ...)
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
Apa artinya? Di mana lokasi pasti dari definisi fungsi ini? Apa yang menjadi poin umum untuk mengetahui bagaimana menggunakan fungsi semacam ini untuk menghasilkan?
microcontroller
c
stm32
stm32f4
stm32cubemx
pengguna505160
sumber
sumber
_write()
fungsi adalah apa yang saya lakukan. Rincian dalam jawaban saya di bawah.Jawaban:
Aku punya metode pertama dari halaman ini bekerja pada STM32F072 saya.
http://www.openstm32.org/forumthread1055
Sebagaimana dinyatakan di sana,
Saya menggunakan STM32CubeMX untuk mengatur USART1 (
huart1
) sebagai port serial. Karena saya hanya inginprintf()
, saya hanya perlu mengisi_write()
fungsi, yang saya lakukan sebagai berikut. Ini terkandung secara konvensional dalamsyscalls.c
.sumber
_EXFUN adalah makro, mungkin berisi beberapa arahan menarik yang memberi tahu kompiler bahwa ia harus memeriksa format-string agar kompatibel dengan printf dan memastikan bahwa argumen untuk printf cocok dengan string format.
Untuk mempelajari cara menggunakan printf, saya sarankan halaman manual dan lebih banyak googling. Tulis beberapa program C sederhana yang menggunakan printf dan jalankan di komputer Anda sebelum Anda mencoba beralih ke menggunakannya di mikro.
Pertanyaan yang menarik adalah "kemana teks yang dicetak pergi?". Pada sistem seperti unix, ia pergi ke "keluar standar", tetapi mikrokontroler tidak memiliki hal seperti itu. Perpustakaan debug CMSIS dapat mengirim teks printf ke port debug lengan semihosting, yaitu ke sesi gdb atau openocd Anda, tetapi saya tidak tahu apa yang akan dilakukan SystemWorkbench32.
Jika Anda tidak bekerja dalam debugger, mungkin lebih masuk akal untuk menggunakan sprintf untuk memformat string yang ingin Anda cetak dan kemudian mengirim string itu melalui port serial atau ke tampilan apa pun yang mungkin telah Anda pasang.
Hati-hati: printf dan kode yang terkait sangat besar. Itu mungkin tidak terlalu menjadi masalah pada 32F407, tetapi ini adalah masalah nyata pada perangkat dengan sedikit flash.
sumber
__cdecl
untuk menghindari kesalahan. Setidaknya pada newlib / cygwin, _EXFUN hanya digunakan untuk mengatur__cdecl
.@ AdamHaun menjawab semua yang Anda butuhkan, dengan
sprintf()
mudah membuat string lalu mengirimkannya. Tetapi jika Anda benar-benar menginginkanprintf()
fungsi Anda sendiri, maka Variable Argument Functions (va_list) adalah caranya.Dengan
va_list
fungsi cetak khusus tampak seperti berikut:Contoh penggunaan:
Perhatikan bahwa sementara solusi ini memberi Anda fungsi yang nyaman untuk digunakan, tetapi lebih lambat daripada mengirim data mentah atau bahkan menggunakan
sprintf()
. Dengan flatates tinggi saya pikir itu tidak akan cukup.Opsi lain, dan mungkin opsi yang lebih baik adalah menggunakan ST-Link, SWD debugger bersama dengan ST-Link Utility. Dan gunakan Printf via SWO viewer , di sini adalah manual ST-Link Utility , bagian yang relevan dimulai pada halaman 31.
sumber
printf () adalah (biasanya) bagian dari perpustakaan standar C. Jika versi perpustakaan Anda dilengkapi dengan kode sumber, Anda mungkin menemukan implementasi di sana.
Mungkin akan lebih mudah menggunakan sprintf () untuk menghasilkan string, kemudian menggunakan fungsi lain untuk mengirim string melalui port serial. Dengan begitu semua pemformatan yang sulit dilakukan untuk Anda dan Anda tidak perlu meretas pustaka standar.
sumber
Bagi yang kesulitan, tambahkan yang berikut ke syscalls.c:
Hubungkan ke port COM Anda melalui dempul dan Anda harus baik.
sumber
Jika Anda menginginkan pendekatan yang berbeda dan tidak ingin menimpa fungsi atau mendeklarasikan sendiri, Anda dapat menggunakannya
snprintf
untuk mengarsipkan tujuan yang sama. Tapi itu tidak elegan.sumber