Sériový port v neblokovaném režimu

V případě blokového načítání ze souboru, například getc() nebo read() je voláním načtení požadovaného počtu bytů předáno operačnímu systému a vykonávání programu je pozastaveno do doby než jsou požadovaná data k dispozici. V případě čtení dat ze sériového portu v samostatném vlákně můžeme vyžadovat takové načítání ukončit, např. z důvodu požadavku na ukončení programu. Kromě volání exit(), které ukončí celý program, můžeme využít neblokovaného čtení dat ze souboru. V takovém případě funkce read() vrací

  • -1 pokud se stala chyba při čtení
  • 0 pokud nejsou žádná data k dispozici
  • počet načtených bytů, který může být nižší než požadovaný

Nastavení neblokovaného režimu soubor odkazovaného file deskriptorem fd lze realizovat např.

   int flags = fcntl(fd, F_GETFL);
   flags &= ~O_NONBLOCK;
   assert(fcntl(fd, F_SETFL, flags) >= 0);

Pak můžeme v programu aktivně vyčítát data ze sériového portu až do doby, než jsou načtena všechna data. Volání funkce read() proběhne okamžitě a můžeme tak testovat, zdali nastal požadavek na ukončení načítání. Takové řešení je funkční, ale cyklus načítání spotřebuje mnoho zdrojů (CPU čas), proto můžeme po volání pokusu načtení vlákno uspat, např. funkcí usleep(). Takové řešení je také funkční a bude méně výpočetně náročné, ale není přiliš elegantní neboť, zpožďujeme načítání. Výhodnější je použít funkce poll() pro monitorování množiny události nad množinou file deskritorů. Implementace načtení znaku ze seriového portu modulu prg_serial (viz serial pak může vypadat například:

int serial_getc_timeout(int fd, int timeout_ms, char *c)
{
   struct pollfd ufdr[1];
   int r = 0;
   ufdr[0].fd = fd;
   ufdr[0].events = POLLIN | POLLRDNORM;
   if ((poll(&ufdr[0], 1, timeout_ms) > 0) && (ufdr[0].revents & (POLLIN | POLLRDNORM))) {
      r = read(fd, c, 1);
   }
   return r;
}

kde pro jednoduchost vytváříme a inicializujeme proměnou typu struct pollfd, čemuž se lze vyhnout a uspořit tak další zdroje.

Příslušné funkce pro otevření a čtení znaku v neblokovaném režimu jsou dostupné prg_serial_nonblock.

courses/b3b36prg/tutorials/serial_nonblock.txt · Last modified: 2018/02/06 17:18 (external edit)