Warning
This page is located in archive.

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

courses:b3b36prg:tutorials:serial_nonblock [2018/02/06 17:18] (current)
Line 1: Line 1:
 +{{indexmenu_n>​4120}}
 +===== 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ř.
 +<code c>
 +   int flags = fcntl(fd, F_GETFL);
 +   flags &= ~O_NONBLOCK;​
 +   ​assert(fcntl(fd,​ F_SETFL, flags) >= 0);
 +</​code>​
 +
 +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 [[courses:​b3b36prg:​tutorials:​serial|]] pak může vypadat například:​
 +
 +
 +<code c>
 +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;
 +}
 +</​code>​
 +
 +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é ​ {{:​courses:​b3b36prg:​tutorials:​prg_serial_nonblock.zip|prg_serial_nonblock}}.
  
courses/b3b36prg/tutorials/serial_nonblock.txt · Last modified: 2018/02/06 17:18 (external edit)