Chinaunix首页 | 论坛 | 博客
  • 博客访问: 324966
  • 博文数量: 145
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 1510
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-19 11:12
文章分类

全部博文(145)

文章存档

2007年(75)

2006年(70)

我的朋友

分类: LINUX

2006-06-29 15:56:05

Linux串口编程HOWTO中英文简体对照beta版

SerialProgramming HOWTO

 

Linux串口编程  中英文简体对照 beta版

 

翻译:CarolLi

原作:GaryFrerking        gary@frerking.org
PeterBaumann

ThisdocumentdescribeshowtoprogramcommunicationswithdevicesoveraserialportonaLinuxbox.

本文档记述了如何在Linux设备上通过串口进行通信的程序开发

中文简体版以英文1.01为原文,同时参考了繁体中文的串口编程HOWTO

简介

ThisistheLinuxSerialProgrammingHOWTO.Allabouthowtoprogramcommunicationswithotherdevices/computersoveraseriallineunderLinux.Differenttechniquesareexplained:CanonicalI/O(onlycompletelinesaretransmitted/received),asyncronousI/O,andwaitingforinputfrommultiplesources.

ThisisthefirstupdatetotheinitialreleaseoftheLinuxSerialProgrammingHOWTO.TheprimarypurposeofthisupdateistochangetheauthorinformationandconvertthedocumenttoDocBookformat.Intermsoftechnicalcontent,verylittleifanythinghaschangedatthistime.Sweepingchangestothetechnicalcontentaren'tgoingtohappenovernight,butI'llworkonitasmuchastimeallows.

Ifyou'vebeenwaitinginthewingsforsomeonetotakeoverthisHOWTO,you'vegottenyourwish.Pleasesendmeanyandallfeedbackyouhave,it'dbeverymuchappreciated.

Allexamplesweretestedusingai386LinuxKernel2.0.29.

本文是为Linux串口程序编写的HOWTO.主要讨论如何在Linux环境下,编写串口与其它计算机设备进行通讯的程序。文中所谈到的技术包括:标准的I/O(只具备传送/接收线的),异步I/O,以及等待来自多信号源输入的程序。

本文是初始的linuxserialprogramminghowto的第一个升级版。主要升级了一些作者信息,把文件转换为DocBook格式。就技术内容而言,几乎没什么大的改变。大规模的技术内容的改变是不可能一夜之间发生的,如果时间允许,我会尽量做一些工作。

如果你正在一边等着有谁来接管这份HOWTO,那你的心愿达成了。我会感谢你发来的任何反馈信息。

所有的示例都在i386LinuxKernel2.0.29下测试通过。

 

版权信息

Thisdocumentiscopyrighted(c)1997PeterBaumann,(c)2001GaryFrerkingandisdistributedunderthetermsoftheLinuxDocumentationProject(LDP)license,statedbelow.

Unlessotherwisestated,LinuxHOWTOdocumentsarecopyrightedbytheirrespectiveauthors.LinuxHOWTOdocumentsmaybereproducedanddistributedinwholeorinpart,inanymediumphysicalorelectronic,aslongasthiscopyrightnoticeisretainedonallcopies.Commercialredistributionisallowedandencouraged;however,theauthorwouldliketobenotifiedofanysuchdistributions.

LinuxSerial-Programming-HOWTO的版權(C)1997归PeterBaumann所有,(C)2001归GaryFrerking所有,并且以LDPlisence(附后)发布。

除非另做申明,LinuxHOWTO文件的版权归各自的作者所有。LinuxHOWTO文件可以完整或部份的以實物或電子版形式复制或者发布,只要能在所有的拷贝中保留版權申明即可。我们鼓励允许商業的发布,不過,如果以此形式发布的话,请告知作者。

 

Alltranslations,derivativeworks,oraggregateworksincorporatinganyLinuxHOWTOdocumentsmustbecoveredunderthiscopyrightnotice.Thatis,youmaynotproduceaderivativeworkfromaHOWTOandimposeadditionalrestrictionsonitsdistribution.Exceptionstotheserulesmaybegrantedundercertainconditions;pleasecontacttheLinuxHOWTOcoordinatorattheaddressgivenbelow.

Inshort,wewishtopromotedisseminationofthisinformationthroughasmanychannelsaspossible.However,wedowishtoretaincopyrightontheHOWTOdocuments,andwouldliketobenotifiedofanyplanstoredistributetheHOWTOs.

Ifyouhaveanyquestions,pleasecontact<>

所有的翻譯,以及其他派生的工作,或整合合併任何LinuxHOWTO文件都必須在此版權申明的規範下进行.也就是说,你不可以在从HOWTO所衍生的工作中,散佈的文件上附加額外的限制條款。除了這些規則,都可获得某種條件的授與;請见后面的地址来聯絡LinuxHOWTO協調員。

簡而言之,我們希望儘可能得透過各種渠道来促進這份资料的流通,不過,我们強烈希望將此版權宣告置於HOWTO的文件上,并且希望任何重新发佈HOWTO的人可以通知我們一下。

如果你有問題,請通过email进行联系.

 

申明

Noliabilityforthecontentsofthisdocumentscanbeaccepted.Usetheconcepts,examplesandothercontentatyourownrisk.Asthisisaneweditionofthisdocument,theremaybeerrorsandinaccuracies,thatmayofcoursebedamagingtoyoursystem.Proceedwithcaution,andalthoughthisishighlyunlikely,theauthor(s)donottakeanyresponsibilityforthat.

Allcopyrightsareheldbytheirbytheirrespectiveowners,unlessspecificallynotedotherwise.Useofaterminthisdocumentshouldnotberegardedasaffectingthevalidityofanytrademarkorservicemark.

Namingofparticularproductsorbrandsshouldnotbeseenasendorsements.

Youarestronglyrecommendedtotakeabackupofyoursystembeforemajorinstallationandbackupsatregularintervals.

使用本文的概念,例子及其他内容的风险由您自己承担,我们对此造成的后果不负责任。由于这是份新的文档,可能存在着错误或误差,而有可能导致对您的系统的损害。请小心操作,虽然这是几乎不可能发生的,作者不对此承担任何责任。

 

除非特别标注,所有的版权归其各自的作者。使用此文档不可标住任何商标或服务标记。

特定的产品或品牌的命名不可被理解为是认可的。(晕,这一段应该请律师来翻)。

 

强烈推荐您在重大的安装前备份系统,并且做到定期备份。

版本更新

Aspreviouslymentioned,notmuchisnewintermsoftechnicalcontentyet.

如前面所提到的,此版本在技术内容上较前一版本并没有什么大的更新。

感谢

TheoriginalauthorthankedMr.Strudthoff,MichaelCarter,PeterWaltenberg,AntoninoIanella,GregHankins,DavePfaltzgraff,SeanLincolne,MichaelWiedmann,andAdreyBonar.

原作者感谢Strudthoff,MichaelCarter,PeterWaltenberg,AntoninoIanella,GregHankins,DavePfaltzgraff,SeanLincolne,MichaelWiedmann,andAdreyBonar诸位先生。

意见反馈

Feedbackismostcertainlywelcomeforthisdocument.Withoutyoursubmissionsandinput,thisdocumentwouldn'texist.Pleasesendyouradditions,commentsandcriticismstothefollowingemailaddress:<>.

非常欢迎对此文档提出反馈意见。有任何补充,评论,批评请发信到:

入门

调试

ThebestwaytodebugyourcodeistosetupanotherLinuxbox,andconnectthetwocomputersviaanull-modemcable.Useminiterm(availablefromtheLDPprogrammersguide(ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.tar.gzintheexamplesdirectory)totransmitcharacterstoyourLinuxbox.Minitermcanbecompiledveryeasilyandwilltransmitallkeyboardinputrawovertheserialport.Onlythedefinestatement#defineMODEMDEVICE"/dev/ttyS0"hastobechecked.SetittottyS0forCOM1,ttyS1forCOM2,etc..Itisessentialfortesting,thatallcharactersaretransmittedraw(withoutoutputprocessing)overtheline.Totestyourconnection,startminitermonbothcomputersandjusttypeaway.Thecharactersinputononecomputershouldappearontheothercomputerandviceversa.Theinputwillnotbeechoedtotheattachedscreen.

调试代码最好的方法,是另外建立一台Linux主机(Linuxbox),采用非调制解调器的串口线(null-modem)连接两台机器。还可以使用minicom(可以从LDP编程指南上获得:ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.tar.gz里的examples目录)来传输字符到你的Linux主机。Miniterm很容易编译而且会直接把键盘的输入不做处理(raw方式)地传到串口。只需要把定义申明#defineMODEMDIVICE“/dev/ttyS0”改一下。COM1口就设置成ttyS0,COM2口就是ttyS1,以此类推测试是必需的,所有的字符直接通过缆线传输,不进行任何输出处理。为了测试你的连接,在你的两台机器上开启minicom,然后随意输入一些字符。从一台电脑中输入的字符应该能显示在另一台设备上,反之亦然。输入的字符不会回显(echo)在本地的屏幕上.

Tomakeanull-modemcableyouhavetocrosstheTxD(transmit)andRxD(receive)lines.Foradescriptionofacableseesect.7oftheSerial-HOWTO.

 

自制非调制解调器的串口连接线(null-modemcable)时,你需要将一端的传送端(TxD)与另一端的接收端(RxD)连接,一端的接收端与另外一端的传送端连接,详情见Serial-HOWTO第七节。

Itisalsopossibletoperformthistestingwithonlyonecomputer,ifyouhavetwounusedserialports.Youcanthenruntwominitermsofftwovirtualconsoles.Ifyoufreeaserialportbydisconnectingthemouse,remembertoredirect/dev/mouseifitexists.Ifyouuseamultiportserialcard,besuretoconfigureitcorrectly.IhadmineconfiguredwrongandeverythingworkedfineaslongasIwastestingonlyonmycomputer.WhenIconnectedtoanothercomputer,theportstartedloosingcharacters.Executingtwoprogramsononecomputerjustisn'tfullyasynchronous.

如果你的电脑有两个空闲的串口端口的话,那么只要使用一台机器就可以做这些试验了,你可以在两个虚拟控制台上各运行一个miniterm,分别用来发送和接收结果。如果你使用串口鼠标,记得在试验前将/dev/mouse重定向。如果你使用多端口的串口卡(multiportserialcard,一定要确保此设备配置正确,我的电脑就曾因为配置错误,而出现这样的问题:当我在自己的机器上测试的时候一切正常,而连接到其他电脑上的时候,端口开始丢失数据。注意,在一台机器上运行两个串口应用程序,并不是完全异步的。

端口设置

Thedevices/dev/ttyS*areintendedtohookupterminalstoyourLinuxbox,andareconfiguredforthisuseafterstartup.Thishastobekeptinmindwhenprogrammingcommunicationwitharawdevice.E.g.theportsareconfiguredtoechocharacterssentfromthedevicebacktoit,whichnormallyhastobechangedfordatatransmission.

设备/dev/ttyS*会被当作连接到你的Linux机器的终端设备,而且在系统启动后就已经配置好了。這一点是在你寫raw设备的串口通信程式時必需牢記的.举例来说,這個串口被設定為回显(echo)所有自此设备送出的字符,通常在做数据传输时,需要改變這種工作模式。

Allparameterscanbeeasilyconfiguredfromwithinaprogram.Theconfigurationisstoredinastructurestructtermios,whichisdefinedin:

#defineNCCS19
       structtermios{
               tcflag_tc_iflag;        /*inputmodeflags*/
              tcflag_tc_oflag;       /*outputmodeflags*/
              tcflag_tc_cflag;       /*controlmodeflags*/
              tcflag_tc_lflag;       /*localmodeflags*/
              cc_tc_line;            /*linediscipline*/
              cc_tc_cc[NCCS];        /*controlcharacters*/
}

所有的参数都可以在程序中轻松配置。配置保存在结构体structtermios中,这个结构是在中定义的

#defineNCCS19
       structtermios{
               tcflag_tc_iflag;        /*输入模式标志*/
             tcflag_tc_oflag;       /*输出模式标志*/
              tcflag_tc_cflag;       /*控制模式标志*/
              tcflag_tc_lflag;       /*本地模式标志*/
              cc_tc_line;            /*行控制linediscipline*/
              cc_tc_cc[NCCS];        /*控制字符controlcharacters*/
       }

Thisfilealsoincludesallflagdefinitions.Theinputmodeflagsinc_iflaghandleallinputprocessing,whichmeansthatthecharacterssentfromthedevicecanbeprocessedbeforetheyarereadwithread.Similarlyc_oflaghandlestheoutputprocessing.c_cflagcontainsthesettingsfortheport,asthebaudrate,bitspercharacter,stopbits,etc..Thelocalmodeflagsstoredinc_lflagdetermineifcharactersareechoed,signalsaresenttoyourprogram,etc..Finallythearrayc_ccdefinesthecontrolcharactersforendoffile,stop,etc..Defaultvaluesforthecontrolcharactersaredefinedin.Theflagsaredescribedinthemanualpagetermios(3).Thestructuretermioscontainsthec_line(linediscipline)element,whichisnotusedinPOSIXcompliantsystems.

这个文件也包括了所有标志(flag)的定义。c_iflag中的输入模式标志,进行所有的输入处理,也就是说从其他设备传来的字符,在被read函数读入之前,会先按照标志进行预处理。同样的,c_oflag定义了所有的输出处理。c_cflag包括了对端口的设置,比如波特率,停止符号等等。c_lflag包括了,决定了字符是否回显,信号是否发送到你的程序,等等所有的本地工作方式。c_cc定义了所有的控制符号,例如文件结束符和停止符等等,所有的这些参数的默认值都定义在中,man手册页termios(3)中有这些参数的具体描述。termio结构体中还包括在不能在POSIX系统中使用的c_line参数(行控制)

串口设备的输入概念

Herethreedifferentinputconceptswillbepresented.Theappropriateconcepthastobechosenfortheintendedapplication.Wheneverpossible,donotloopreadingsinglecharacterstogetacompletestring.WhenIdidthis,Ilostcharacters,whereasareadforthewholestringdidnotshowanyerrors.

这里将介绍串行设备三种不同的输入方式,你需要为你的程序选择合适的工作方式。任何可能的情况下,不要采用循环读取单字符的方式来获取一个字符串。我以前这样做的时候,就丢失了字符,而读取整个字符串的read方法,则没有这种错误。

标准输入模式

Thisisthenormalprocessingmodeforterminals,butcanalsobeusefulforcommunicatingwithotherdlinputisprocessedinunitsoflines,whichmeansthatareadwillonlyreturnafulllineofinput.AlineisbydefaultterminatedbyaNL(ASCIILF),anendoffile,oranendoflinecharacter.ACR(theDOS/Windowsdefaultend-of-line)willnotterminatealinewiththedefaultsettings.

Canonicalinputprocessingcanalsohandletheerase,deleteword,andreprintcharacters,translateCRtoNL,etc..

这是终端设备的标准处理模式,在与其它dl的以行为单位的输入通讯中也很有用。这种方式中,read会传回一整行完整的输入.一行的结束,默认是以NL(ASCII值LF),文件结束符,或是一个行结束字符。默认设置中,CR(DOS/Windows里的默认行结束符)并不是行结束标志。

标准的输入处理还可以处理清除,删除字,重画字符,转换CRNL等等功能。

非标准输入模式

Non-CanonicalInputProcessingwillhandleafixedamountofcharactersperread,andallowsforacharactertimer.Thismodeshouldbeusedifyourapplicationwillalwaysreadafixednumberofcharacters,oriftheconnecteddevicesendsburstsofcharacters.

非标准输入处理可以用于需要每次读取固定数量字符的情况下,并允许使用字符接收时间的定时器。这种模式可以用在每次读取固定长度字符串的程序中,或者所连接的设备会突然送出大量字符的情况下。

异步输入模式

Thetwomodesdescribedabovecanbeusedinsynchronousandasynchronousmode.Synchronousisthedefault,whereareadstatementwillblock,untilthereadissatisfied.Inasynchronousmodethereadstatementwillreturnimmediatlyandsendasignaltothecallingprogramuponcompletion.Thissignalcanbereceivedbyasignalhandler.

前面敘述的兩種模式都可以用在同步與异步的傳輸模式。默认是在同步的模式下工作的,也就是在尚未讀完数据之前,read的狀態會被阻塞(block)。而在异步模式下,read的狀態會立即返回並送出一个信号到所调用的程式直到完成工作。這個信号可以由信号处理程式handler來接收。

等待来自多信号源的输入

Thisisnotadifferentinputmode,butmightbeuseful,ifyouarehandlingmultipledevices.InmyapplicationIwashandlinginputoveraTCP/IPsocketandinputoveraserialconnectionfromanothercomputerquasi-simultaneously.Theprogramexamplegivenbelowwillwaitforinputfromtwodifferentinputsources.Ifinputfromonesourcebecomesavailable,itwillbeprocessed,andtheprogramwillthenwaitfornewinput.

Theapproachpresentedbelowseemsrathercomplex,butitisimportanttokeepinmindthatLinuxisamulti-processingoperatingsystem.TheselectsystemcallwillnotloadtheCPUwhilewaitingforinput,whereasloopinguntilinputbecomesavailablewouldslowdownotherprocessesexecutingatthesametime.

本节介绍的不是另一个输入模式,不过如果你要处理来自多个设备的数据的话,可能会很有用。在我的应用程序中,我需要同时通过一个TCP/IPsocket和一个串口来处理其它计算机传来的输入。下面给出的示例程序将等待来自两个不同输入源的输入。如果其中一个信号源出现,程序就会进行相应处理,同时程序会继续等待新的输入。

后面提出的方法看起来相当覆杂,但请记住Linux是一个多进程的操作系统。系统调用select并不会在等待输入信号时增加CPU的负担,而如果使用轮询方式来等待输入信号的话,则将拖慢其它正在执行的进程。
阅读(1022) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~