Saya adalah anggota sarjana dari tim peneliti yang mengerjakan proyek yang melibatkan ASIC pemancar RF, dan penerima nirkabelnya yang pada akhirnya harus mengirim data ke PC.
Receiver mengeluarkan sinyal serial non-standar yang cepat , kontinu, asinkron, dan tidak standar (mis. Bukan SPI, I2C, UART, dll.) Sehingga tugas saya adalah menulis perangkat lunak mikrokontroler untuk menghubungkan penerima ke komputer. Saat ini pendekatan saya adalah menggunakan interupsi terpicu tepi untuk menempatkan data dalam buffer melingkar dan melakukan seluruh proses decoding bit-by-bit dalam loop utama. Mikrokontroler harus secara bersamaan menampilkan data ini menggunakan USB (virtual com port) ke komputer.
Ini adalah masalah yang saya alami, dan satu yang saya antisipasi:
Saya tidak dapat memproses data yang disangga cukup cepat bahkan dengan prosesor ARM Cortex M3 72 MHz saya yang cukup kuat. Bitrate adalah 400 Kbps (2,5 us / bit). Untuk referensi yang hanya menyisakan 180 siklus per bit (termasuk decoding DAN ISR, yang memiliki ~ 30 siklus overhead aduh!). MCU juga harus menangani banyak tugas lain yang akan dipilihnya dalam loop utama.
Driver port virtual USB virtual juga berbasis interupsi. Ini membuat saya hampir yakin bahwa driver pada akhirnya akan memiliki prosesor terganggu begitu lama sehingga melewatkan jendela 2,5 mikrodetik (180 siklus) di mana sedikit dapat ditransmisikan. Saya tidak yakin bagaimana interupsi konflik / ras seperti ini biasanya diselesaikan.
Jadi pertanyaannya adalah sederhana, apa yang mungkin dilakukan seseorang untuk menyelesaikan masalah ini atau apakah ini bukan pendekatan yang benar? Saya bersedia mempertimbangkan lebih sedikit pendekatan yang berfokus pada perangkat lunak. Misalnya, menggunakan chip USB khusus dengan semacam mesin keadaan perangkat keras untuk decoding, tetapi ini adalah wilayah yang tidak dikenal.
Jawaban:
Jawaban lain: Berhenti menggunakan interupsi.
Orang-orang melompat untuk menggunakan interupsi terlalu mudah. Secara pribadi, saya jarang menggunakannya karena mereka sebenarnya menghabiskan banyak waktu, seperti yang Anda temukan.
Seringkali mungkin untuk menulis loop utama yang mensurvei segalanya dengan sangat cepat sehingga latensinya masih dalam spesifikasi, dan sangat sedikit waktu yang terbuang.
Mungkin ada beberapa hal dalam loop yang terjadi jauh lebih sering daripada yang lain. Mungkin bit yang masuk misalnya, dalam hal ini, tambahkan lebih dari tes tersebut, sehingga lebih banyak prosesor didedikasikan untuk tugas itu.
Mungkin ada beberapa peristiwa di mana latensi pendekatan ini terlalu tinggi. Misalnya, Anda mungkin memerlukan acara dengan waktu yang sangat akurat. Dalam hal ini, buat acara itu di interupsi, dan miliki semua yang lainnya di loop.
sumber
Anda mungkin bisa menggunakan FPGA dan bukannya Mikrokontroler untuk memecahkan kode dan buffer datastream nirkabel. Kemudian gunakan prosesor ARM untuk menyiram buffer FPGA (misalnya menggunakan antarmuka SPI) dan mengirimkan konten keluar dari port USB Comm. Ini bekerja, tetapi FPGA harus dapat menjaga dengan mudah selama Anda bisa sering memperbaikinya untuk memastikan bahwa buffer perangkat kerasnya tidak dibanjiri (atau jika Anda dapat menangani data yang terjatuh di tingkat protokol yang lebih tinggi) ).
sumber
Mudah: Gunakan Mikrokontroler PSoC5 .
Anda memiliki semua kemudahan penggunaan mikrokontroler, plus itu berisi CPLD, sehingga Anda dapat menulis periferal perangkat keras Anda sendiri di Verilog. Cukup tulis dekoder data serial Anda di Verilog, dan gunakan DMA untuk mengalirkannya ke port USB.
Sementara itu, inti ARM 32-bit yang kuat dapat memutar-mutar instruksinya.
sumber
Saya pikir Anda memiliki pilihan rekayasa klasik untuk dibuat: cepat, murah, bekerja: pilih dua.
Solusi @ vicatcu tentu saja bagus, tetapi jika Anda tidak dapat atau tidak akan menambahkan lebih banyak perangkat keras ke dalamnya (dan ini termasuk prosesor yang lebih cepat) maka Anda harus membuat pilihan. Jika tautan serial ini adalah yang paling penting daripada Anda harus duduk di ISR sampai semua bit telah dikumpulkan. 180 instruksi per bit sebenarnya tidak buruk sama sekali, tetapi jangan mencoba melakukan semuanya. Saat Anda mendeteksi awal transfer, putar hingga transfer selesai. Masukkan hasilnya ke dalam FIFO dan lanjutkan pemrosesan normal.
Anda tidak mengatakan berapa lama masing-masing transmisi tetapi jika mereka pendek dan meledak ini akan menjadi solusi yang layak. Saya berani bertaruh bahwa implementasi port COM virtual Anda memiliki beberapa buffering perangkat keras juga, jadi layanan interupsi "laggy" untuk itu seharusnya tidak menimbulkan terlalu banyak masalah. Sejauh apa yang perlu dilakukan MCU ... Anda memiliki beberapa keputusan desain untuk dibuat.
sumber
Pertama-tama, saya sudah menyukai beberapa jawaban di sini, dan beberapa sudah mendapatkan suara saya.
Tetapi hanya dengan melemparkan solusi lain yang mungkin: mengingat kendala dari proyek Anda, apakah menambahkan mikrokontroler kedua akan menjadi buruk (akankah itu melibatkan board run lain)? Mungkin mikrokontroler 8-bit sederhana yang terhubung ke Cortex-M3 Anda melalui perangkat cepat seperti SPI. Pengontrol 8-bit pilihan Anda akan mengumpulkan bit dan membentuk byte seperti pada jawaban yang dipilih, tetapi ketika itu memiliki byte, itu bisa membuangnya ke register data SPI untuk mentransfer.
Sisi korteks-M3 hanya akan mengganggu data SPI yang diterima. Yang memotong interupsi dipicu tepi eksternal 400 KHz Anda sebelumnya menjadi 50 KHz.
Dua alasan mengapa saya menyarankan ini adalah karena beberapa metode lain (PSoC atau menambahkan FPGA) agak mahal (walaupun ini mungkin tidak masalah untuk proyek akademik volume rendah) dan karena mungkin memungkinkan Anda untuk melestarikan beberapa struktur kode Anda saat ini.
Selain itu, saya pikir ide PSoC mengagumkan dengan perangkat kustom Anda sendiri mentransfer melalui DMA ke USB.
sumber
Jika format data Anda mirip dengan UART, tetapi pada kecepatan baud yang tidak dapat diprediksi-namun-konsisten, kecenderungan saya adalah menggunakan CPLD untuk mengubah setiap kata dari data yang masuk menjadi format SPI atau standar-async. Saya tidak berpikir ada kebutuhan untuk mendorong sepenuhnya ke ranah CPLD. Sebenarnya, bahkan logika diskrit mungkin hampir bisa diterapkan. Jika Anda bisa menghasilkan jam yang smidgin lebih dari 5x kecepatan data yang Anda inginkan, Anda bisa menggunakan penghitung dibagi lima dan pembagian 16 dengan beberapa gerbang. Atur penghitung divide-by-lima sehingga akan disimpan di reset setiap kali input idle dan penghitung divide-by-16 adalah nol. Kalau tidak, hasilkan pulsa clock SPI dan tumbuk penghitung divide-by-16 kapan saja penghitung divide-by-five mencapai 2.
Mengingat jam 5x, orang dapat menghasilkan jam SPI menggunakan 16V8 (perangkat logika diprogram yang terkecil dan termurah yang tersedia saat ini). 16V8 atau 22V10 kedua dapat digunakan sebagai pembagi tingkat fraksional untuk menghasilkan jam 5x, atau orang dapat menggunakan chip yang sedikit lebih besar (CPLD) dan melakukan semuanya dalam satu.
Edit / Addendum
Atas pertimbangan lebih lanjut, jika seseorang akan menggunakan CPLD, orang dapat dengan mudah menambahkan beberapa perangkat tambahan ke sirkuit. Sebagai contoh, seseorang dapat dengan mudah menambahkan logika untuk memiliki rangkaian stall sampai ia menerima setidaknya 1,5 bit kali stop bit, diikuti oleh 3,5 bit kali bit mulai; jika menerima bit start yang terlalu pendek, ia harus kembali mencari bit stop. Juga, jika seseorang menggunakan SPI, seseorang dapat menggunakan sinyal / CS untuk memastikan bahwa perangkat penerima akan melihat data yang dibingkai dengan benar. Jika perangkat yang menerima data SPI dapat menangani frame 10-bit, orang dapat mengirim frame tersebut secara langsung. Jika tidak, setiap frame sepuluh-bit dapat dikirim sebagai frame 8-bit dengan set LSB (7 bit data), dan sebuah frame dengan semua LSB's clear (3 bit data); jam SPI akan dipercepat selama bit-bit berhenti sehingga semua data akan dikirim.
Beberapa mikrokontroler memiliki modul pembangkitan PWM yang agak serba guna yang mencakup hal-hal seperti kemampuan untuk diatur ulang oleh sinyal eksternal, dan menyinkronkan pengaturan waktunya dengan pelepasan sinyal semacam itu. Jika mikrokontroler Anda dapat melakukannya, tergantung pada fitur tepatnya, yang mungkin sangat menyederhanakan CPLD atau sirkuit penghasil waktu.
Pendekatan lain yang agak disentuh Rocketmagnet, adalah memiliki mikro kecil yang tujuan utamanya adalah untuk memecahkan kode data serial dan mengubahnya menjadi format yang dapat digunakan oleh mikro utama. Kecepatan data 400KHz Anda cukup cepat untuk decoding perangkat lunak, tetapi sesuatu seperti PIC bisa menanganinya jika tidak harus melakukan hal lain pada saat yang sama. Bergantung pada perangkat apa yang Anda kenal, ini bisa lebih mudah atau lebih sulit daripada menggunakan CPLD.
sumber