GNU/Linux >> Znalost Linux >  >> Linux

Sériová komunikace s nízkou latencí na Linuxu

Schémata požadavků / odpovědí bývají neefektivní a na sériovém portu se rychle objevují. Pokud vás zajímá propustnost, podívejte se na protokol v okně, jako je protokol pro odesílání souborů kermit.

Nyní, pokud se chcete držet svého protokolu a snížit latenci, výběr, dotazování, čtení vám poskytne zhruba stejnou latenci, protože jak naznačil Andy Ross, skutečná latence je v hardwarovém zpracování FIFO.

Pokud budete mít štěstí, můžete chování ovladače vyladit bez záplatování, ale stále se musíte podívat na kód ovladače. Nicméně, když ARM zvládne přerušovací frekvenci 10 kHz, nebude to určitě dobré pro celkový výkon systému...

Další možností je vyplnění paketu tak, abyste pokaždé dosáhli prahu FIFO. Také potvrdí, zda se jedná nebo nejedná o problém prahu FIFO.

10 ms @ 115200 stačí k přenosu 100 bajtů (za předpokladu 8N1), takže to, co vidíte, je pravděpodobně proto, že low_latency příznak není nastaven. Zkuste

setserial /dev/<tty_name> low_latency

Nastaví příznak low_latency, který používá jádro při přesunu dat nahoru ve vrstvě 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 hovor může být zodpovědný za latenci 10 ms, kterou pozorujete.


Sériové porty na linuxu jsou „zabaleny“ do konstrukcí terminálů ve stylu unixu, což vás zasáhne 1 tick lag, tj. 10 ms. Zkuste, zda stty -F /dev/ttySx raw low_latency pomáhá, ale žádné záruky.

Na PC můžete přejít na hardcore a komunikovat přímo se standardními sériovými porty, problém setserial /dev/ttySx uart none odpojit linuxový ovladač od hw sériového portu a ovládat port přes inb/outb do přístavních registrů. Zkoušel jsem to, funguje to skvěle.

Nevýhodou je, že nedochází k přerušení při příchodu dat a musíte se dotazovat registru. často.

Měli byste být schopni udělat totéž na straně zařízení paže, může to být mnohem těžší na exotickém hw sériového portu.


Po rozhovoru s dalšími inženýry na toto téma jsem dospěl k závěru, že tento problém není řešitelný v uživatelském prostoru. Protože potřebujeme přejít most do jádra jádra, plánujeme implementovat modul jádra, který mluví s naším protokolem a dává nám latence <1 ms.

--- upravit ---

Ukázalo se, že jsem se úplně mýlil. Vše, co bylo nutné, bylo zvýšit rychlost tikání jádra. Výchozích 100 tiků přidalo zpoždění 10 ms. 1000 Hz a záporná hodnota nice pro sériový proces mi dává časové chování, kterého jsem chtěl dosáhnout.


Zde je setserial nastaví nízkou latenci na deskriptoru souboru portu:

ioctl(fd, TIOCGSERIAL, &serial);
serial.flags |= ASYNC_LOW_LATENCY;
ioctl(fd, TIOCSSERIAL, &serial);

Linux
  1. Představení průvodce meziprocesovou komunikací v Linuxu

  2. Meziprocesová komunikace v Linuxu:Sokety a signály

  3. Meziprocesová komunikace v Linuxu:Sdílené úložiště

  1. Linux – sériový port Raspberrypi?

  2. Linux – Jak najít procesy pomocí sériového portu?

  3. Odstraňování problémů s nedostatkem místa na disku pro cloudový server Linux

  1. Odstraňování problémů s pomalou síťovou komunikací nebo časovými limity připojení v Linuxu

  2. Virtuální sériový port pro Linux

  3. Nejnižší latence oznamovací metoda mezi procesy pod Linuxem