Skema permintaan / jawaban cenderung tidak efisien, dan muncul dengan cepat di port serial. Jika Anda tertarik dengan throughput, lihat protokol berjendela, seperti protokol pengiriman file kermit.
Sekarang jika Anda ingin tetap menggunakan protokol Anda dan mengurangi latensi, pilih, jajak pendapat, baca semuanya akan memberi Anda latensi yang kira-kira sama, karena seperti yang ditunjukkan Andy Ross, latensi sebenarnya ada dalam penanganan FIFO perangkat keras.
Jika Anda beruntung, Anda dapat men-tweak perilaku driver tanpa menambal, tetapi Anda masih perlu melihat kode drivernya. Namun, memiliki ARM yang menangani kecepatan interupsi 10 kHz tentu saja tidak baik untuk kinerja sistem secara keseluruhan...
Opsi lainnya adalah melapisi paket Anda sehingga Anda mencapai ambang batas FIFO setiap saat. Ini juga akan mengonfirmasi apakah itu masalah ambang batas FIFO atau bukan.
10 msec @ 115200 cukup untuk mengirimkan 100 byte (dengan asumsi 8N1), jadi yang Anda lihat mungkin karena low_latency
bendera tidak diatur. Coba
setserial /dev/<tty_name> low_latency
Ini akan menyetel flag low_latency, yang digunakan oleh kernel saat memindahkan data ke atas di lapisan tty:
void tty_flip_buffer_push(struct tty_struct *tty)
{
unsigned long flags;
spin_lock_irqsave(&tty->buf.lock, flags);
if (tty->buf.tail != NULL)
tty->buf.tail->commit = tty->buf.tail->used;
spin_unlock_irqrestore(&tty->buf.lock, flags);
if (tty->low_latency)
flush_to_ldisc(&tty->buf.work);
else
schedule_work(&tty->buf.work);
}
schedule_work
panggilan mungkin bertanggung jawab atas latensi 10 mdtk yang Anda amati.
Port serial di linux "dibungkus" ke dalam konstruksi terminal bergaya unix, yang memberi Anda 1 tick lag, yaitu 10ms. Coba jika stty -F /dev/ttySx raw low_latency
membantu, meskipun tidak ada jaminan.
Di PC, Anda dapat menjadi hardcore dan berbicara langsung ke port serial standar, keluarkan setserial /dev/ttySx uart none
untuk melepaskan driver linux dari port serial hw dan mengontrol port melalui inb/outb
ke port register. Saya sudah mencobanya, itu bekerja dengan baik.
Sisi negatifnya adalah Anda tidak mendapatkan interupsi saat data tiba dan Anda harus melakukan polling pada register. sering.
Anda harus dapat melakukan hal yang sama di sisi perangkat lengan, mungkin jauh lebih sulit pada port serial eksotik hw.
Setelah berbicara dengan beberapa insinyur lagi tentang topik tersebut, saya sampai pada kesimpulan bahwa masalah ini tidak dapat diselesaikan di ruang pengguna. Karena kami perlu menyeberangi jembatan ke tanah kernel, kami berencana untuk mengimplementasikan modul kernel yang membahas protokol kami dan memberi kami latensi <1 md.
--- edit ---
Ternyata saya salah total. Yang diperlukan hanyalah meningkatkan laju kutu kernel. 100 tick default menambahkan penundaan 10 ms. 1000Hz dan nilai nice negatif untuk proses serial memberi saya perilaku waktu yang ingin saya capai.
Inilah setserial
lakukan untuk menyetel latensi rendah pada deskriptor file port:
ioctl(fd, TIOCGSERIAL, &serial);
serial.flags |= ASYNC_LOW_LATENCY;
ioctl(fd, TIOCSSERIAL, &serial);