\documentclass[letterpaper]{article}
\nonstopmode
\akai
\usepackage{linuxdoc-sgml}
\usepackage{qwertz}
\usepackage{url}
\usepackage[latin1]{inputenc}
\usepackage{t1enc}
\usepackage[english]{babel}
\usepackage{epsfig}
\usepackage{null}
\def\addbibtoc{
\addcontentsline{toc}{section}{\numberline{\mbox{}}\relax\bibname}
}%end-preamble
\setcounter{page}{1}
\title{The Linux Serial Programming HOWTO}
\author{by Peter H. Baumann, {\ttfamily \onlynameurl{Peter.Baumann@dlr.de}}\\ 
Ä¶ªÌ: ´¿¤¸¦ö {\ttfamily \onlynameurl{yytseng@ms16.hinet.net}}}
\date{v1.0, 22 ¤@¤ë 1998}
\abstract{¥»¤å¥ó±N±Ô­z¦p¦ó¦b Linux Àô¹Ò¤U¼¶¼g§Ç¦C°ðªº³q°Tµ{¦¡.}


\begin{document}
\maketitle
\tableofcontents

\section{Â²¤¶}

¥»¤å¬O Linux §Ç¦C°ðµ{¦¡¼¶¼gªº HOWTO. ¥þ½g³£¦b°Q½×¦p¦ó¦b Linux Àô¹Ò¤U,
¥H§Ç¦C°ð»P¨ä¥L ¸Ë¸m/¹q¸£ ³q°Tªºµ{¦¡¼gªk. ©Ò¸ÑÄÀªº§Þ³N¥]§t: ¼Ð·Çªº I/O
(¥u¨ã³Æ ¶Ç°e/±µ¦¬ ½uªº), «D¦P¨B I/O, ¤Î µ¥«Ý¨Ó¦Û¦h«H¸¹·½ªº¿é¤J°T¸¹ ªº¼gªk.

¥»¤å¤£·|±Ô­z¦p¦ó³]©w§Ç¦C°ð, ¦]¬°³o¦b Greg Hankins ªº Serial-HOWTO ¤w¸g¦³»¡©ú¤F.

§Ú¥²»Ý±j½Õ§Ú¨Ã«D¦¹»â°ì¤¤ªº±M®a, ¦Ó¬O¦b±M®×¤¤´¿¹J¨ì¹L³oÃþªº³q°T°ÝÃD.
¦b³o©Ò´£¨ìªº½d¨Òµ{¦¡¬O­l¥Í¦Û miniterm ªºµ{¦¡½X. ¥i¦b LDP µ{¦¡³]­p®v«ü«n¨ú±o
({\ttfamily ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.tar.gz}
¤Î¨ä¥L¬M®g¯¸)
¦b½d¨Ò¨º­Ó¥Ø¿ý¤U.

§Ú¶}©l¼g³o¥÷¤å¥ó¬O¦b 1997 ¦~ ¤»¤ë, ²{¦b§Ú¤w¸g²¾Âà¨ì WinNT ¥Hº¡¨¬«È¤áªº»Ý¨D,
¥H­P©ó§Ú¨S¯à¾Ç±o§ó²`¤Jªºª¾ÃÑ. ¦pªG¥ô¦ó¤H¦³¤°»ò·N¨£, §Ú«Ü¼Ö·N§â¥¦Â\¶i³o¥÷¤å¥ó¤¤
(°Ñ¦Ò ¦^õX ¨º¤@¸`). ¦pªG¦³¤H¯à±µ¤â³o¥÷¤u§@¨Ã¥[¥H§ï¶i, ½Ð e-mail µ¹§Ú.

©Ò¦³ªº½d¨Ò³£¦b i386 Linux Kernel 2.0.29 ¤U´ú¸Õ¹L. 




\subsection{ª©Åv}

Linux Serial-Programming-HOWTO ªºª©Åv(C) 1997 ¬O Peter Baumann ©Ò¦³.
Linux HOWTO ¤å¥ó¥i¥H§¹¾ã©Î³¡¥÷¥H¹ê»Ú©Î¹q¤l«¬¦¡­«»s©Î´²§G, ¥u­nª©Åv«Å§i¯à«O¯d¦b©Ò¦³´²§Gªº°Æ¥»¤¤. °Ó·~©Êªº­«»s´²§G¬O³\¥i¨Ã³Q¹ªÀyªº; ¤£¹L, ¦pªG¥H¦¹«¬¦¡ªº´²§G {\itshape À³¸Ó\/} §iª¾§@ªÌ.

©Ò¦³¦³ÃöªºÂ½Ä¶, ­l¥Íªº¤u§@, ©Î¾ã¦X¦X¨Ö¥ô¦ó Linux HOWTO ¤å¥ó¬Ò¥²¶·¦b¦¹ª©Åv«Å§i³W½d¤§¤U. ¤]´N¬O, §A¤£¥i¥H¦Û HOWTO ©Ò­l¥Íªº¤u§@¤¤, ´²§Gªº¤å¥ó¤Wªþ¥[ÃB¥~ªº­­¨î±ø´Ú.
°£¤F³o¨Ç³W«h¤§¥~¬Ò¥i¦b¬YºØ±ø¥óªº±Â»P; ½ÐÁpµ¸ Linux HOWTO ¨ó½Õ­û: ¦p¥H¤U©Òµ¹ªº¦ì§}.

Â²¦Ó¨¥¤§, §Ú­Ì§Æ±æ¾¨¥i¯à±o³z¹L¦UºØºÞ¹D«P¶i³o¥÷¸ê°Tªº¬y³q, ¤£¹L, §Ú±j¯Pªº§Æ±æ±Nª©Åv«Å§i¸m©ó HOWTO ªº¤å¥ó¤W, ¥ô¦ó {\itshape ·Q\/} ­«·s´²§G HOWTO ªº¤H, §¡§Æ±æ±z¯àª¾·|§Ú­Ì¤@¤U.

¦pªG§A¦³°ÝÃD, ½Ð¸g¥Ñ email »P Tim Bynum, Linux HOWTO ¨ó½Õ­û³sµ¸, {\ttfamily \onlynameurl{linux-howto@sunsite.unc.edu}}.




\subsection{¥»¤å³Ì·sªºª©¥»}

Serial-Programming-HOWTO ³Ì·sªºª©¥»±N©ñ¦b\\ 
{\ttfamily \onlynameurl{ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/Serial-Programming-HOWTO}}
¤Î¨ä¥L¬M³]¯¸¥x. ¦³³\¦hªº®æ¦¡, ¦p PostScript ¤Î DVI
ªºª©¥»©ñ¦b {\ttfamily other-formats} ¥Ø¿ý¤U.
Serial-Programming-HOWTO ¤]©ñ¦b {\ttfamily \onlynameurl{http://sunsite.unc.edu/LDP/HOWTO/Serial-Programming-HOWTO.html}}
¨Ã·|¨C­Ó¤ëÂ\¤@¥÷¨ì {\ttfamily \onlynameurl{comp.os.linux.answers}}.




\subsection{¦^õX}

½Ð§â¥ô¦ó­×¥¿, °ÝÃD, ·N¨£, «ØÄ³, ©Î¨ä¥¦ªþ¥[ªºÃD§÷¶Ç°eµ¹§Ú. ¥HÅý§Ú§ï¶i³o¥÷ HOWTO!
¨Ã¸Ô²Ó§i¶D§Ú­þ­Ó³¡¥÷¬O±z¤£¯à¤F¸Ñ, ©Î¤£°÷²M·¡ªº. §A¥i¥H¥Î email ³sµ¸§Ú
{\ttfamily \onlynameurl{Peter.Baumann@dlr.de}}.
½Ð§â Serial-Programming-HOWTO ªºª©¥»¸¹½Xªþ¤W, ¥»¤åª©¥»¸¹½X¬O 0.3.






\section{¶}©l}




\subsection{°»¿ù}

³Ì¦nªº°»¿ù§Aµ{¦¡½Xªº¤èªk¬O«Øºc¥t¤@¥x Linux box, ¨Ã§â¨â¥x¹q¸£¥Î null-modem Æl½u³s±µ. ¥Î miniterm
(¥i¦b LDP µ{¦¡³]­p®v«ü«n¨ú±o
({\ttfamily ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.tar.gz} ¦b½d¨Ò¨º­Ó¥Ø¿ý¤U) ¥H¶Ç°e¦r¤¸¨ì§Aªº Linux box.
Miniterm «Ü®e©ö½sÄ¶¦Ó¥¦·|§â©Ò¦³¿é¤J¨ìÁä½Lªº¦r¤¸³z¹L§Ç¦C°ð¶Ç°e.
¥u¦³³o­Ó«Å§i©w¸q·|³QÀË¬d
{\ttfamily \#define MODEMDEVICE "/dev/ttyS0"}.
¦pªG¬O COM1 ³]©w¬° {\ttfamily ttyS0}, ¦pªG¬O COM2 ³]©w¬° {\ttfamily ttyS1} µ¥µ¥..
¥ý«eªº´ú¸Õ¬O¥²­nªº, {\itshape ©Ò¦³ªº\/} ¦r¤¸³£±N¥H raw ¤è¦¡ (¤£¸g¥ô¦ó³B²z) ª½±µ¶Ç°e. ´ú¸Õ¬O§_³s±µ¥¿½T, ¦b¨â¥x¹q¸£¤W³£±Ò°Ê miniterm µM«áÀH«K¦bÁä½L¤W¶Ã«ö. ¦b¨ä¤¤¤@¥x¤W¿é¤Jªº¦r¤¸À³¸Ó·|Åã¥Ü¦b¥t¤@¥x¹q¸£¤W¤Ï¤§¥ç¦P. ¦ý¿é¤Jªº¦r¤¸¤£·|¦^À³¨ì»P¤§¬Û³sªº¿Ã¹õ¤W.

­n¦Û»s null-modem ªº¹qÆl, §A¥²»Ý­n§â TxD (¶Ç°e) ¤Î
RxD (±µ¦¬) ¨â½u¹ï½Õ. ¸Ô²Óªº»¡©ú¦b Serial-HOWTO ªº²Ä 7 ¬q.

·íµM¤]¥i¥H¥u¥Î¤@¥x¹q¸£¨Ó§@¬Û¦Pªº´ú¸Õ, ¥u­n¹q¸£¤W¦³¨â­Ó¥¼¨Ï¥Îªº§Ç¦C°ð. ·íµM§A¤]´N­n°õ¦æ¨â­Ó miniterm ¨Ó·íµêÀÀ±±¨î¥x. ¦pªG§A¬OÂÇ¥Ñ©Þ¥h·Æ¹«¨Ó¨ú±o¥t¤@­Ó§Ç¦C°ð, °O±o­n§â {\ttfamily /dev/mouse} ¸Ë¸m­«·s¾É¦V, ¦pªG¥¦¦s¦bªº¸Ü. ¦pªG§A¨Ï¥Î¦h°ðªº§Ç¦C°ð±±¨î¥d, ½Ð½T©w¥¦¤w³]©w¥¿½T. ·í§Ú¦b§Úªº¹q¸£¤W´ú¸Õ®É¤]´¿¸g¦]¬°³]©w¿ù»~¦Ó¥X¹Lºl. ·í§Ú³s¨ì¥t¤@¥x¹q¸£, ³q°T°ð¶}©l¶Ç°e¦r¤¸. ´N¦]¬°­è¦n³o¤£¬O§¹¾ãªº«D¦P¨B¦¡¶Ç¿é, ©Ò¥H¥i¦b¦P¤@¥x¹q¸£¤W°õ¦æ¨â­Óµ{¦¡.




\subsection{³s±µ°ð³]©w}

{\ttfamily /dev/ttyS*} ¸Ë¸m·|³Q·í¦¨³s±µ¨ì§Aªº Linux box ªº²×ºÝ¾÷, ¨Ã¥B¦b±Ò°Ê«á´N³]©w¦n¤F. ³o­ÓÆ[©À¦b§A¼g raw ¸Ë¸mªº³q°Tµ{¦¡®É¥²»Ý°O¦í. ¤]´N¬O»¡³o­Ó³s±µ°ð³Q³]©w¬°¦^À³©Ò¦³¦Û³o­Ó¸Ë¸m°e¥Xªº¦r¤¸, ¦Ó¥Î¦b¸ê®Æ¶Ç¿é®É³q±`³oºØ­n§ïÅÜ³oºØ¤u§@¼Ò¦¡.

©Ò¦³ªº°Ñ¼Æ¥i¥H¥Ñ¤@­Ó¤pµ{¦¡Â²³æªº§¹¦¨. ³]©w°Ñ¼Æ³Q©ñ¦b¤@­Óµ²ºcÅé¤º {\ttfamily struct termios}, ¥Lªº©w¸qÀÉ¦b {\ttfamily $<$asm/termbits.h$>$}:
\begin{tscreen}
\begin{verbatim}
#define NCCS 19
struct termios {
        tcflag_t c_iflag;               /* ¿é¤J¼Ò¦¡ºX¼Ð */
        tcflag_t c_oflag;               /* ¿é¥X¼Ò¦¡ºX¼Ð */
        tcflag_t c_cflag;               /* ±±¨î¼Ò¦¡ºX¼Ð */
        tcflag_t c_lflag;               /* °Ï°ì¼Ò¦¡ºX¼Ð */
        cc_t c_line;                    /* ¦æ±±¨î (line discipline) */
        cc_t c_cc[NCCS];                /* ±±¨î¯S©Ê */
};
\end{verbatim}
\end{tscreen}


³o­ÓÀÉ®×¤]¥]§t©Ò¦³ªººX¼Ð©w¸q. ¿é¤J¼Ò¦¡ºX¼Ð¦b
{\ttfamily c\_iflag} ´xºÞ©Ò¦³ªº¿é¤J³B²z, ³o´N·N¿×µÛ¥Ñ¸Ë¸m¤W¶Ç¨Óªº¦r¤¸¦bÁÙ¨S¥Î {\ttfamily read} ¥\¯àÅª¨ú«e¥i¥H¥ý³B²z¹L. ¦P²z {\ttfamily c\_oflag} ´xºÞ©Ò¦³ªº¿é¥X³B²z. {\ttfamily c\_cflag} ¥]§t³s±µ°ðªº³]©w, ¦p Àj²v, ¨C¦r¤¸¦h¤Ö¦ì¤¸, °±¤î¦ì¤¸, µ¥µ¥.. °Ï°ì¼Ò¦¡ºX¼Ð©ñ¦b {\ttfamily c\_lflag} ¥Î¨Ó°»´ú¦r¤¸¬O§_¦^À³, ¦Ó°T¸¹·|°e¨ì§Aªºµ{¦¡, µ¥µ¥.. ³Ì«á
{\ttfamily c\_cc} °}¦C©w¸q¤FÀÉ®×²×¤Fªº±±¨î¦r¤¸, °±¤î,
µ¥µ¥..  ¹w³]ªº±±¨î¦r¤¸­È©ñ¦b
{\ttfamily $<$asm/termios.h$>$}. ¦³ÃöºX¼Ðªº²Ó¸`Â\¦b¨Ï¥Î¤â¥U {\ttfamily termios(3)}. {\ttfamily termios} µ²ºcÅé¤ºªº
{\ttfamily c\_line} ¦æ±±¨î (line discipline) ¤¸¯À, ¤£¯à¦b POSIX ¬Û®eªº¨t²Î¤U¨Ï¥Î
Ä¶ªÌµù:³o¸Ì©Ò»¡ªº line discipline ÁöµM§ÚÂ½¦¨ ¦æ±±¨î ¦ýÁÙ¬O«ÜÃø»¡¥X¨º¬OªÙ. ¦pªG·Qª¾¹D½Ð¬Ý¬Ý kernel :( .






\subsection{§Ç¦C¸Ë¸mªº¿é¤JÆ[©À}

¦³¤T­Ó¿é¤JªºÆ[©À­n»¡©ú. «ö·Ó©Ò­n¼gªºÀ³¥Îµ{¦¡¿ï¥Î¾A¦XªºÆ[©À. ¾¨¶qÁ×§K¨Ï¥Î°j°é¨ÓÅª¨ú³æ¤@ªº¦r¤¸¦A²Õ¦¨¦r¦ê. §Ú´¿³o¼Ë°µ¹L, ·|±¼¦r¤¸, ¥B¹ï {\ttfamily read} ¦Ó¨¥¤£·|Åã¥Ü¥ô¦ó¿ù»~.




\subsubsection{¼Ð·Ç¿é¤Jµ{§Ç}

³o¬O²×ºÝ¾÷ªº¼Ð·Ç³B²zµ{§Ç, ¦ý¥Î¨Ó»P¨ä¥L dl «¬¦¡ªº¥H¦æ¬°³æ¦ìªº¿é¤J³q°T¤]«Ü¦³¥Î, ¤]´N¬O {\ttfamily read} ·|¶Ç¦^¤@¾ã¦æ§¹¾ãªº¿é¤J¸ê®Æ. ¦æ¹w³]ªº²×¤î¦r¤¸¬O {\ttfamily NL}
(ASCII {\ttfamily LF}), ÀÉ®×µ²§ô²Å, ©Î¦æ²×¤î¦r¤¸. ¹w³]Àô¹Ò¤U, {\ttfamily CR} (¬O DOS/Windows ¹w³]ªº¦æ²×¤î²Å) ¤£·|²×¤î¤@¦æªº±Ô­z.

¼Ð·Çªº¿é¤J³B²zµ{§ÇÁÙ¥i¥H³B²z ²M°£, §R°£¦r, ­«¦L¦r¤¸, ¤ÎÂà´« {\ttfamily CR} ¬° {\ttfamily NL} µ¥µ¥¥\¯à..




\subsubsection{«D¼Ð·Ç¿é¤Jµ{§Ç}

«D¼Ð·Ç¿é¤Jµ{§Ç¥i¥H¥Î¦b»Ý­n¨C¦¸Åª¨ú©T©w¼Æ¶q¦r¤¸ªº±¡ªp, ¨Ã¤¹³\¨Ï¥Î¦r¤¸¿é¤J®É¶¡ªº­p®É¾¹. ³oºØ¼Ò¦¡¥i¥H¥Î¦bÅª¨ú©T©w¦r¤¸¼Æ¶qªºÀ³¥Îµ{¦¡, ©ÎªÌ©Ò³s±µªº¸Ë¸m·|¬ðµM°e¥X¤j¶q¦r¤¸ªºª¬ªp.






\subsubsection{«D¦P¨B¦¡¿é¤J}

¥H¤W©Ò±Ô­zªº¨âºØ¼Ò¦¡³£¥i¥H¥Î¦b«D¦P¨B»P¦P¨Bªº¶Ç¿é¼Ò¦¡. ¹w³]¬O¦b¦P¨Bªº¼Ò¦¡¤U¤u§@, ¤]´N¬O¦b©|¥¼Åª¨ú§¹¤§«e, {\ttfamily read} ªºª¬ºA·|³QªýÂ_. ¦Ó«D¦P¨B¼Ò¦¡¤U {\ttfamily read} ªºª¬ºA·|ª½±µªð¦^¨Ã°e¥X°T¸¹¨ì©Ò¥s¥Îªºµ{¦¡ª½¨ì§¹¦¨¤u§@. ³o­Ó°T¸¹¥i¥H¥Ñ°T¸¹ªº³B²zµ{¦¡ handler...¨Ó±µ¦¬.




\subsubsection{µ¥«Ý¨Ó¦Û¦h­Ó°T¸¹¨Ó·½ªº¿é¤J}

³o¨Ã¤£¬O¤@­Ó¤£¤@¼Ëªº¿é¤J¼Ò¦¡. ¦pªG§A­n³z¹L§Ç¦C°ð³s±µ¨Ã³B²z¦h­Ó¸Ë¸mªº¸Ü, ¥¦¬Oº¡¦³¥Îªº. ¦b§ÚªºÀ³¥Îµ{¦¡¤¤§Ú¥²»Ý¦b´X¥G¦P¤@®É¶¡¤º, ³z¹L TCP/IP socket ¤Î§Ç¦C°ð³B²z¨Ó¦Û¨ä¥L¹q¸£ªº¿é¤J°T¸¹. ¤U­±³o­Ó½d¨Òµ{¦¡±Nµ¥«Ý¨Ó¦Û¨â­Ó¤£¦P¿é¤J·½ªº°T¸¹. ¦pªG¨ä¤¤¤@­Ó«H¸¹·½¥X²{, ¥L´N·|³Q³B²z, ¦Óµ{¦¡·|Ä~Äòµ¥«Ý·sªº¿é¤J°T¸¹.

¥H¤U³o­Ó¤èªk¬Ý°_¨Ó¬Û·íÂÐÂø, ¦ý½Ð°O¦í Linux ¬O¤@­Ó¦h¤uªº§@·~¨t²Î. {\ttfamily select} ³o­Ó¨t²Î©I¥s¨Ã¤£·|¦bµ¥«Ý¿é¤J°T¸¹®É§â CPU ­t¸ü¥[­«, ¦Ó¦pªG§A¥Î°j°é¤è¦¡¨Óµ¥«Ý¿é¤J°T¸¹±N¨Ï±o¨ä¥¦¦P®É°õ¦æªº¦æµ{³Q©ìºC.






\section{µ{¦¡½d¨Ò}

©Ò¦³ªº½d¨Ò¨Ó·½¦Û {\ttfamily miniterm.c}. The type ahead ¼È¦s¾¹³Q­­¨î¦b 255 ­Ó¦r¤¸,  ´N¸ò¼Ð·Ç¿é¤Jµ{§Çªº³Ì¤j¦r¦êªø«×¬Û¦P ({\ttfamily $<$linux/limits.h$>$} ©Î {\ttfamily $<$posix1\_lim.h$>$}).

°Ñ¦Òµ{¦¡½X¤¤ªºµù¸Ñ¥¦·|¸ÑÄÀ¤£¦P¿é¤J¼Ò¦¡ªº¨Ï¥Î. §Ú§Æ±æ³o¨Çµ{¦¡½X³£¯à³Q¤F¸Ñ. ¼Ð·Ç¿é¤Jµ{§Çªºµ{¦¡½d¨Òªºµù¸Ñ¼g±o³Ì¦n, ¨ä¥¦ªº½d¨Ò³£¥u¦b¤£¦P©ó¨ä¥¦½d¨Òªº¦a¤è°µµù¸Ñ.

±Ô­z¤£¬O«Ü§¹¾ã, ¦ý¥i¥H¿EÀy§A¹ï³o½d¨Ò°µ¹êÅç, ¥H©µ¥Í¥X¦X©ó§A©Ò»ÝÀ³¥Îµ{¦¡ªº³Ì¨Î¸Ñ.

§O§Ñ°O­n§â§Ç¦C°ðªºÅv­­³]©w¥¿½T (¤]´N¬O: {\ttfamily chmod a+rw /dev/ttyS1})!






\subsection{¼Ð·Ç¿é¤Jµ{§Ç}

\begin{tscreen}
\begin{verbatim}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

/* Àj²v³]©w³Q©w¸q¦b <asm/termbits.h>, ³o¦b <termios.h> ³Q¤Þ¤J */
#define BAUDRATE B38400            
/* ©w¸q¥¿½Tªº§Ç¦C°ð */
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX ¨t²Î¬Û®e */

#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE; 

main()
{
  int fd,c, res;
  struct termios oldtio,newtio;
  char buf[255];
/* 
  ¶}±Ò¼Æ¾Ú¾÷¸Ë¸m¥HÅª¨ú¨Ã¼g¤J¦Ó¤£¥H±±¨î tty ªº¼Ò¦¡
  ¦]¬°§Ú­Ì¤£·Qµ{¦¡¦b°e¥X CTRL-C «á´N³Q±þ±¼.
*/
 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); 
 if (fd <0) {perror(MODEMDEVICE); exit(-1); }

 tcgetattr(fd,&oldtio); /* Àx¦s¥Ø«eªº§Ç¦C°ð³]©w */
 bzero(&newtio, sizeof(newtio)); /* ²M°£µ²ºcÅé¥H©ñ¤J·sªº§Ç¦C°ð³]©w­È */

/* 
  BAUDRATE: ³]©w bps ªº³t«×. §A¤]¥i¥H¥Î cfsetispeed ¤Î cfsetospeed ¨Ó³]©w.
  CRTSCTS : ¿é¥X¸ê®ÆªºµwÅé¬y¶q±±¨î (¥u¯à¦b¨ã§¹¾ã½u¸ôªºÆl½u¤U¤u§@
            °Ñ¦Ò Serial-HOWTO ²Ä¤C¸`)
  CS8     : 8n1 (8 ¦ì¤¸, ¤£°µ¦P¦ì¤¸ÀË¬d,1 ­Ó²×¤î¦ì¤¸)
  CLOCAL  : ¥»¦a³s½u, ¤£¨ã¼Æ¾Ú¾÷±±¨î¥\¯à
  CREAD   : ­P¯à±µ¦¬¦r¤¸
*/
 newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
 
/*
  IGNPAR  : ©¿²¤¸g¦P¦ì¤¸ÀË¬d«á, ¿ù»~ªº¦ì¤¸²Õ
  ICRNL   : ¤ñ CR ¹ïÀ³¦¨ NL (§_«h·í¿é¤J°T¸¹¦³ CR ®É¤£·|²×¤î¿é¤J)
            ¦b¤£µM§â¸Ë¸m³]©w¦¨ raw ¼Ò¦¡(¨S¦³¨ä¥¦ªº¿é¤J³B²z)
*/
 newtio.c_iflag = IGNPAR | ICRNL;
 
/*
 Raw ¼Ò¦¡¿é¥X.
*/
 newtio.c_oflag = 0;
 
/*
  ICANON  : ­P¯à¼Ð·Ç¿é¤J, ¨Ï©Ò¦³¦^À³¾÷¯à°±¥Î, ¨Ã¤£°e¥X«H¸¹¥H¥s¥Îµ{¦¡
*/
 newtio.c_lflag = ICANON;
 
/* 
  ªì©l¤Æ©Ò¦³ªº±±¨î¯S©Ê
  ¹w³]­È¥i¥H¦b /usr/include/termios.h §ä¨ì, ¦bµù¸Ñ¤¤¤]¦³,
  ¦ý§Ú­Ì¦b³o¤£»Ý­n¬Ý¥¦­Ì
*/
 newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */ 
 newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
 newtio.c_cc[VERASE]   = 0;     /* del */
 newtio.c_cc[VKILL]    = 0;     /* @ */
 newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
 newtio.c_cc[VTIME]    = 0;     /* ¤£¨Ï¥Î¤À³Î¦r¤¸²Õªº­p®É¾¹ */
 newtio.c_cc[VMIN]     = 1;     /* ¦bÅª¨ú¨ì 1 ­Ó¦r¤¸«e¥ý°±¤î */
 newtio.c_cc[VSWTC]    = 0;     /* '\0' */
 newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */ 
 newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
 newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
 newtio.c_cc[VEOL]     = 0;     /* '\0' */
 newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
 newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
 newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
 newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
 newtio.c_cc[VEOL2]    = 0;     /* '\0' */

/* 
  ²{¦b²M°£¼Æ¾Ú¾÷½u¨Ã±Ò°Ê§Ç¦C°ðªº³]©w
*/
 tcflush(fd, TCIFLUSH);
 tcsetattr(fd,TCSANOW,&newtio);

/*
  ²×ºÝ¾÷³]©w§¹¦¨, ²{¦b³B²z¿é¤J°T¸¹
  ¦b³o­Ó½d¨Ò, ¦b¤@¦æªº¶}©l³B¿é¤J 'z' ·|°h¥X¦¹µ{¦¡.
*/
 while (STOP==FALSE) {     /* °j°é·|¦b§Ú­Ìµo¥X²×¤îªº°T¸¹«á¸õ¥X */
 /* §Y¨Ï¿é¤J¶W¹L 255 ­Ó¦r¤¸, Åª¨úªºµ{¦¡¬qÁÙ¬O·|¤@ª½µ¥¨ì¦æ²×µ²²Å¥X²{¤~°±¤î.
    ¦pªGÅª¨ìªº¦r¤¸²Õ§C©ó¥¿½T¦s¦bªº¦r¤¸²Õ, «h©Ò³Ñªº¦r¤¸·|¦b¤U¤@¦¸Åª¨ú®É¨ú±o.
    res ¥Î¨Ó¦s©ñ¯u¥¿Åª¨ìªº¦r¤¸²Õ­Ó¼Æ */
    res = read(fd,buf,255); 
    buf[res]=0;             /* ³]©w¦r¦ê²×¤î¦r¤¸, ©Ò¥H§Ú­Ì¯à¥Î printf */
    printf(":%s:%d\n", buf, res);
    if (buf[0]=='z') STOP=TRUE;
 }
 /* ¦^¦sÂÂªº§Ç¦C°ð³]©w­È */
 tcsetattr(fd,TCSANOW,&oldtio);
}

\end{verbatim}
\end{tscreen}





\subsection{«D¼Ð·Ç¿é¤Jµ{§Ç}

¦b«D¼Ð·Çªº¿é¤Jµ{§Ç¼Ò¦¡¤U, ¿é¤Jªº¸ê®Æ¤£·|³Q²Õ¦X¦¨¤@¦æ¦Ó¿é¤J«áªº³B²z¥\¯à (²M°£, ±þ±¼, §R°£, µ¥µ¥.) ³£¤£¯à¨Ï¥Î. ³o­Ó¼Ò¦¡¦³¨â­Ó¥\¯à±±¨î°Ñ¼Æ:
{\ttfamily c\_cc[VTIME]} ³]©w¦r¤¸¿é¤J®É¶¡­p®É¾¹, ¤Î {\ttfamily c\_cc[VMIN]}
³]©wº¡¨¬Åª¨ú¥\¯àªº³Ì§C¦r¤¸±µ¦¬­Ó¼Æ.

¦pªG MIN $>$ 0 ¥B TIME = 0, MIN ³]©w¬°º¡¨¬Åª¨ú¥\¯àªº³Ì§C¦r¤¸±µ¦¬­Ó¼Æ. ¥Ñ©ó TIME ¬O ¹s, ©Ò¥H­p®É¾¹±N¤£³Q¨Ï¥Î.

¦pªG MIN = 0 ¥B TIME $>$ 0, TIME ±N³Q·í°µ¹O®É³]©w­È. º¡¨¬Åª¨ú¥\¯àªº±¡ªp¬°Åª¨ú¨ì³æ¤@¦r¤¸, ©ÎªÌ¶W¹L TIME ©Ò©w¸qªº®É¶¡ (t = TIME *0.1 s). ¦pªG¶W¹L TIME ©Ò©w¸qªº®É¶¡, «h¤£·|¶Ç¦^¥ô¦ó¦r¤¸.

¦pªG MIN $>$ 0 ¥B TIME $>$ 0, TIME ±N³Q·í°µ¤@­Ó¤À³Î¦r¤¸²Õªº­p®É¾¹. º¡¨¬Åª¨ú¥\¯àªº±ø¥ó¬° ±µ¦¬¨ì MIN ­Ó¼Æªº¦r¤¸, ©Î¨â­Ó¦r¤¸ªº¶¡¹j®É¶¡¶W¹L TIME ©Ò©w¸qªº­È. ­p®É¾¹·|¦b¨CÅª¨ì¤@­Ó¦r¤¸«á­«·s­p®É, ¥B¥u·|¦b²Ä¤@­Ó¦r¤¸¦¬¨ì«á¤~·|±Ò°Ê.

¦pªG MIN = 0 ¥B TIME = 0, Åª¨ú¥\¯à´N°¨¤W³Qº¡¨¬. ¥Ø«e©Ò¦s¦bªº¦r¤¸²Õ­Ó¼Æ, ©ÎªÌ ±N¦^¶Çªº¦r¤¸²Õ­Ó¼Æ. ®Ú¾Ú Antonino (°Ñ¦Ò °^Äm) ©Ò»¡, §A¥i¥H¥Î {\ttfamily fcntl(fd, F\_SETFL, FNDELAY);} ¦bÅª¨ú«e±o¨ì¬Û¦Pªºµ²ªG.

ÂÇ¥Ñ­×§ï {\ttfamily newtio.c\_cc[VTIME]} ¤Î {\ttfamily newtio.c\_cc[VMIN]} ¤W­zªº¼Ò¦¡´N¥i¥H´ú¸Õ¤F.

\begin{tscreen}
\begin{verbatim}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX ¨t²Î¬Û®e */
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE; 

main()
{
  int fd,c, res;
  struct termios oldtio,newtio;
  char buf[255];

 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); 
 if (fd <0) {perror(MODEMDEVICE); exit(-1); }

 tcgetattr(fd,&oldtio); /* Àx¦s¥Ø«eªº§Ç¦C°ð³]©w */

 bzero(&newtio, sizeof(newtio));
 newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
 newtio.c_iflag = IGNPAR;
 newtio.c_oflag = 0;

 /* ³]©w¿é¤J¼Ò¦¡ («D¼Ð·Ç«¬, ¤£¦^À³,...) */
 newtio.c_lflag = 0;
 
 newtio.c_cc[VTIME]    = 0;   /* ¤£¨Ï¥Î¤À³Î¦r¤¸²Õ­p®É¾¹ */
 newtio.c_cc[VMIN]     = 5;   /* ¦bÅª¨ú¨ì 5 ­Ó¦r¤¸«e¥ý°±¤î */

 tcflush(fd, TCIFLUSH);
 tcsetattr(fd,TCSANOW,&newtio);


 while (STOP==FALSE) {       /* ¿é¤J°j°é */
   res = read(fd,buf,255);   /* ¦b¿é¤J 5 ­Ó¦r¤¸«á§Yªð°j */
   buf[res]=0;               /* ©Ò¥H§Ú­Ì¯à¥Î printf... */
   printf(":%s:%d\n", buf, res);
   if (buf[0]=='z') STOP=TRUE;
 }
 tcsetattr(fd,TCSANOW,&oldtio);
}
\end{verbatim}
\end{tscreen}





\subsection{«D¦P¨B¦¡¿é¤J}

\begin{tscreen}
\begin{verbatim}
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX ¨t²Î¬Û®e */
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE; 

void signal_handler_IO (int status);   /* ©w¸q°T¸¹³B²zµ{§Ç */
int wait_flag=TRUE;                    /* ¨S¦¬¨ì°T¸¹ªº¸Ü´N·|¬O TRUE */

main()
{
  int fd,c, res;
  struct termios oldtio,newtio;
  struct sigaction saio;           /* definition of signal action */
  char buf[255];

  /* ¶}±Ò¸Ë¸m¬° non-blocking (Åª¨ú¥\¯à·|°¨¤Wµ²§ôªð¦^) */
  fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fd <0) {perror(MODEMDEVICE); exit(-1); }

  /* ¦b¨Ï¸Ë¸m«D¦P¨B¤Æ«e, ¦w¸Ë°T¸¹³B²zµ{§Ç */
  saio.sa_handler = signal_handler_IO;
  saio.sa_mask = 0;
  saio.sa_flags = 0;
  saio.sa_restorer = NULL;
  sigaction(SIGIO,&saio,NULL);
  
  /* ¤¹³\¦æµ{¥h±µ¦¬ SIGIO °T¸¹*/
  fcntl(fd, F_SETOWN, getpid());
  /* ¨ÏÀÉ®×ake the file descriptor «D¦P¨B (¨Ï¥Î¤â¥U¤W»¡¥u¦³ O_APPEND ¤Î
  O_NONBLOCK, ¦Ó F_SETFL ¤]¥i¥H¥Î...) */
  fcntl(fd, F_SETFL, FASYNC);

  tcgetattr(fd,&oldtio); /* Àx¦s¥Ø«eªº§Ç¦C°ð³]©w­È */
  /* ³]©w·sªº§Ç¦C°ð¬°¼Ð·Ç¿é¤Jµ{§Ç */
  newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR | ICRNL;
  newtio.c_oflag = 0;
  newtio.c_lflag = ICANON;
  newtio.c_cc[VMIN]=1;
  newtio.c_cc[VTIME]=0;
  tcflush(fd, TCIFLUSH);
  tcsetattr(fd,TCSANOW,&newtio);
 
  /* µ¥«Ý¿é¤J°T¸¹ªº°j°é. «Ü¦h¦³¥Îªº¨Æ§Ú­Ì±N¦b³o°µ */ 
  while (STOP==FALSE) {
    printf(".\n");usleep(100000);
    /* ¦b¦¬¨ì SIGIO «á, wait_flag = FALSE, ¿é¤J°T¸¹¦s¦b«h¥i¥H³QÅª¨ú */
    if (wait_flag==FALSE) { 
      res = read(fd,buf,255);
      buf[res]=0;
      printf(":%s:%d\n", buf, res);
      if (res==1) STOP=TRUE; /* ¦pªG¥u¿é¤J CR «h°±¤î°j°é */
      wait_flag = TRUE;      /* µ¥«Ý·sªº¿é¤J°T¸¹ */
    }
  }
  /* ¦^¦sÂÂªº§Ç¦C°ð³]©w­È */
  tcsetattr(fd,TCSANOW,&oldtio);
}

/***************************************************************************
* °T¸¹³B²zµ{§Ç. ³]©w wait_flag ¬° FALSE, ¥H¨Ï¤W­zªº°j°é¯à±µ¦¬¦r¤¸          *
***************************************************************************/

void signal_handler_IO (int status)
{
  printf("received SIGIO signal.\n");
  wait_flag = FALSE;
}
\end{verbatim}
\end{tscreen}





\subsection{µ¥«Ý¨Ó¦Û¦h­Ó°T¸¹¨Ó·½ªº¿é¤J}

³o¤@¬q«Üµu. ¥¦¥u¯à³Q®³¨Ó·í¦¨¼gµ{¦¡®Éªº´£¥Ü, ¬G½d¨Òµ{¦¡¤]«ÜÂ²µu. ¦ý³o­Ó½d¨Ò¤£¥u¯à¥Î¦b§Ç¦C°ð¤W, ÁÙ¥i¥H¥Î¦b³Q·í¦¨ÀÉ®×¨Ó¨Ï¥Îªº¸Ë¸m¤W.

select ©I¥s¤Î¦ñÀH¥¦©Ò¤Þµoªº¥¨¶°¦@¥Î {\ttfamily fd\_set}. {\ttfamily fd\_set} «h¬O¤@­Ó
¦ì¤¸°}¦C, ¦Ó¨ä¤¤¨C¤@­Ó¦ì¤¸¥Nªí¤@­Ó¦³®ÄªºÀÉ®×±Ô­zµ²ºc. {\ttfamily select} ©I¥s±µ¨ü¤@­Ó¦³®ÄªºÀÉ®×±Ô­zµ²ºc¨Ã¶Ç¦^ {\ttfamily fd\_set} ¦ì¤¸°}¦C, ¦Ó¸Ó¦ì¤¸°}¦C¤¤­Y¦³¬Y¤@­Ó¦ì¤¸¬° 1, ´Nªí¥Ü¬Û¹ï¬MªºÀÉ®×±Ô­zµ²ºcªºÀÉ®×µo¥Í¤F¿é¤J, ¿é¥X©Î¦³¨Ò¥~¨Æ¥ó. ¦Ó³o¨Ç¥¨¶°´£¨Ñ¤F©Ò¦³³B²z {\ttfamily fd\_set} ªº¥\¯à. ¥ç¥i°Ñ¦Ò¤â¥U select(2).

\begin{tscreen}
\begin{verbatim}
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

main()
{
   int    fd1, fd2;  /* ¿é¤J·½ 1 ¤Î 2 */
   fd_set readfs;    /* ÀÉ®×±Ô­zµ²ºc³]©w */
   int    maxfd;     /* ³Ì¤j¥i¥ÎªºÀÉ®×±Ô­zµ²ºc */
   int    loop=1;    /* °j°é¦b TRUE ®É¦¨¥ß */ 

   /* open_input_source ¶}±Ò¤@­Ó¸Ë¸m, ¥¿½Tªº³]©w¦n§Ç¦C°ð,
      ¨Ã¦^¶Ç¦^¦¹ÀÉ®×±Ô­zµ²ºcÅé */
   fd1 = open_input_source("/dev/ttyS1");   /* COM2 */
   if (fd1<0) exit(0);
   fd2 = open_input_source("/dev/ttyS2");   /* COM3 */
   if (fd2<0) exit(0);
   maxfd = MAX (fd1, fd2)+1;  /* ´ú¸Õ³Ì¤j¦ì¤¸¿é¤J (fd) */

   /* ¿é¤J°j°é */
   while (loop) {
     FD_SET(fd1, &readfs);  /* ´ú¸Õ¿é¤J·½ 1 */
     FD_SET(fd2, &readfs);  /* ´ú¸Õ¿é¤J·½ 2 */
     /* block until input becomes available */
     select(maxfd, &readfs, NULL, NULL, NULL);
     if (FD_ISSET(fd1))         /* ¦pªG¿é¤J·½ 1 ¦³°T¸¹ */
       handle_input_from_source1();
     if (FD_ISSET(fd2))         /* ¦pªG¿é¤J·½ 2 ¦³°T¸¹ */
       handle_input_from_source2();
   }

}   
\end{verbatim}
\end{tscreen}


³o­Ó½d¨Òµ{¦¡¦bµ¥«Ý¿é¤J°T¸¹¥X²{«e, ¤£¯à½T©w¥¦·|°±¹y¤U¨Ó. ¦pªG§A»Ý­n¦b¿é¤J®É¥[¤J¹O®É¥\¯à, ¥u»Ý§â select ©I¥s´«¦¨:
\begin{tscreen}
\begin{verbatim}
int res;
struct timeval Timeout;

/* ³]©w¿é¤J°j°éªº¹O®É­È */
Timeout.tv_usec = 0;  /* ²@¬í */
Timeout.tv_sec  = 1;  /* ¬í */
res = select(maxfd, &readfs, NULL, NULL, &Timeout);
if (res==0)
/* ÀÉ®×±Ô­zµ²ºc¼Æ¦b input = 0 ®É, ·|µo¥Í¿é¤J¹O®É. */ 
\end{verbatim}
\end{tscreen}


³o­Óµ{¦¡·|¦b 1 ¬íÄÁ«á¹O®É. ¦pªG¶W¹L®É¶¡, select ·|¶Ç¦^ 0, ¦ý¬OÀ³¸Ó¯d·N {\ttfamily Timeout} ªº®É¶¡»¼´î¬O¥Ñ {\ttfamily select} ©Òµ¥«Ý¿é¤J°T¸¹ªº®É¶¡¬°°ò·Ç. ¦pªG¹O®Éªº­È¬O 0, select ·|°¨¤Wµ²§ôªð¦^.






\section{¨ä¥¦¸ê·½}



\begin{itemize}
\item Linux Serial-HOWTO ±Ô­z¦p¦ó³]©w§Ç¦C°ð¤Î©Ò¦³¬ÛÃöªºµwÅé¸ê°T.
\item ¥Ñ Michael Sweet ©Ò¼gªº \nameurl{http://www.easysw.com/~mike/serial}{Serial Programming Guide for POSIX Compliant Operating Systems}. ³o­Ó³sµ²¤w¸g¯î¼o¤F¦ý§Ú§ä¤£¨ì¥¦ªº·s¦ì§}. ¦³¤Hª¾¹D¯à¦b­þ§ä¨ì¥¦¶Ü? ¥¦¬O«Ü´Îªº¤å¥ó!
\item {\ttfamily termios(3)} ªº¨Ï¥Î¤â¥U. ±Ô­z©Ò¦³¦³Ãö {\ttfamily termios} µ²ºcÅéªººX¼Ð.
\end{itemize}





\section{°^Äm}

        
´N¸òÂ²¤¶©Ò»¡ªº¤@¼Ë, §Ú¨Ã«D¦b³o»â°ì¦³©Ò±Mºë, ¦ý§Ú¦Û¤v¹J¨ì°ÝÃD, ¨Ã³z¹L¥L¤HªºÀ°§U§ä¨ìµª®×. ·PÁÂ¨Ó¦Û European Transonic Windtunnel ªº Strudthoff ¥ý¥Í, Cologne,  Michael Carter ({\ttfamily mcarter@rocke.electro.swri.edu}), ¤Î Peter Waltenberg ({\ttfamily p.waltenberg@karaka.chch.cri.nz})



»P§Ú¦P®É·Ç³Æ³o¥÷¤å¥óªº Antonino Ianella ({\ttfamily antonino@usa.net} ©Ò½f¼gªº Serial-Port-Programming Mini HOWTO. Greg Hankins ­n¨D§Ú§â Antonino's Mini-HOWTO
¤@¨Ö©ñ¤J³o¥÷¤å¥ó.

        
³o¥÷¤å¥óªºµ²ºc¤Î SGML ªº®æ¦¡¬O·½¦Û Greg Hankins ªº Serial-HOWTO. ·PÁÂ Dave Pfaltzgraff ({\ttfamily Dave\_Pfaltzgraff@patapsco.com}),
Sean Lincolne ({\ttfamily slincol@tpgi.com.au}), Michael Wiedmann
({\ttfamily mw@miwie.in-berlin.de}), ¤Î Adrey Bonar ({\ttfamily andy@tipas.lt}) ¦U¤è­±ªº¨ó§U.



\end{document}
