Linux串口和网络编程.ppt_第1页
Linux串口和网络编程.ppt_第2页
Linux串口和网络编程.ppt_第3页
Linux串口和网络编程.ppt_第4页
Linux串口和网络编程.ppt_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

,272020.,教学内容,第一章嵌入式系统概述第二章学习板硬件及开发环境的建立第三章构建嵌入式Linux系统第四章嵌入式Linux设备驱动第五章嵌入式Linux串口和网络编程第六章嵌入式Linux图形编程,272020.,第五章Linux串口和网络编程,5.1嵌入式Linux应用程序开发方法5.2嵌入式Linux串口编程5.3嵌入式Linux网络编程,272020.,本章目标,掌握嵌入式Linux应用程序开发方法交叉编译调试方法掌握Linux串口和网络应用程序开发串口的设置串口数据收发处理阻塞型I/O和非阻塞型I/OSOCKET套接字Server和Client端程序设计,272020.,5.1嵌入式Linux应用程序开发方法,交叉编译:arm-linux-gccoexecfilefile.c,查看依赖的库:arm-linux-readelfaexecfile|grepNEEDED,调试方法:nfs/tftptargetprintf或GDB,272020.,5.2linux串口应用开发,串口概述串口设置串口使用详解,272020.,5.2.1串口概述,用户常见的数据通信的基本方式有两种:并行通信;串行通信;串行通信是计算机常用的接口,如:RS-232-C接口。该标准规定采用一个DB25芯引脚连接器或DB9芯引脚连接器。芯片内部常具有UART控制器,其可工作于Interrupt(中断模式)或DMA(直接内存访问)模式。,272020.,UART的操作主要包括以下几个部分:数据发送;数据接收;产生中断;产生波特率;Loopback模式;红外模式;自动流控模式;串口参数的配置主要包括:波特率、数据位、停止位、流控协议。,272020.,linux中的串口设备文件存放于/dev目录下,其中串口一,串口二对应设备名依次为“/dev/ttyS0”、“/dev/ttyS1”。在linux下操作串口与操作文件相同。,272020.,5.2.2串口设置,在使用串口之前必须设置相关配置,包括:波特率、数据位、校验位、停止位等。串口设置由下面结构体实现:,272020.,该结构中c_cflag最为重要,可设置波特率、数据位、校验位、停止位。在设置波特率时需在数字前加上B,如B9600。B19200。使用其需通过“与”“或”操作方式。,272020.,输入模式c_iflag成员控制接收端的字符输入处理。,272020.,串口控制函数,Tcgetattr取属性(termios结构)Tcsetattr设置属性(termios结构)cfgetispeed得到输入速度Cfgetospeed得到输出速度Cfsetispeed设置输入速度Cfsetospeed设置输出速度Tcdrain等待所有输出都被传输tcflow挂起传输或接收tcflush刷清未决输入和/或输出Tcsendbreak送BREAK字符tcgetpgrp得到前台进程组IDtcsetpgrp设置前台进程组ID,272020.,串口配置流程,保存原先串口配置使用tcgetattr(fd,272020.,设置数据位,需使用掩码设置。newtio.c_cflag,272020.,6.设置停止位,通过激活c_cflag中的CSTOPB实现。若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。newtio.c_cflag/最少接收字符数,272020.,8.处理要写入的引用对象tcflush函数刷清(抛弃)输入缓存(终端驱动程序已接收到,但用户程序尚未读)或输出缓存(用户程序已经写,但尚未发送)。inttcflush(intfiledes,intqueue)queue数应当是下列三个常数之一:TCIFLUSH刷清输入队列。TCOFLUSH刷清输出队列。TCIOFLUSH刷清输入、输出队列。如:tcflush(fd,TCIFLUSH);,272020.,9激活配置。在完成配置后,需激活配置使其生效。使用tsettattr()函数。原型:inttcgetattr(intfiledes,structtermios*termptr);inttcsetattr(intfiledes,intopt,conststructtermios*termptr);tcsetattr的参数opt使我们可以指定在什么时候新的终端属性才起作用。opt可以指定为下列常数中的一个:TCSANOW更改立即发生。TCSADRAIN发送了所有输出后更改才发生。若更改输出参数则应使用此选择项。TCSAFLUSH发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入数据都被删除(刷清)使用如:tcsetattr(fd,TCSANOW,Open函数中除普通参数外,另有两个参数O_NOCTTY和O_NDELAY。O_NOCTTY:通知linux系统,这个程序不会成为这个端口的控制终端。O_NDELAY:通知linux系统不关心DCD信号线所处的状态(端口的另一端是否激活或者停止)。,272020.,然后,恢复串口的状态为阻塞状态,用于等待串口数据的读入。用fcntl函数:fcntl(fd,F_SETFL,0);接着,测试打开的文件描述府是否引用一个终端设备,以进一步确认串口是否正确打开。isatty(STDIN_FILENO);/可选操作,272020.,读写串口,串口的读写与普通文件一样,使用read,write函数。read(fd,buff,8);write(fd,buff,8);,272020.,5.3linux网络Socket编程,Socket编程LinuxSocket常用函数举例,272020.,SocketAPIARPAUCBerkeleyBSDunix/BerkeleyunixDefactostandardExampleServerClient,一个本地主机建立或拥有的应用程序,操作系统控制下的,与其它(远程)应用进程之间发送和接收数据的接口,通信协议应用程序接口(APIs)-依赖于操作系统和编程语言UNIX:BerkeleySockets(C语言)SystemVTransportLayerInterface(TLI)(C语言)WINDOWS:WINSOCK,socket(套接字),272020.,客户端,socket是进行程序间通讯(IPC)的BSD方法。客户将插头插入一个服务器端口建立一个双向的连接管道,服务器,插口(port),socket的抽象表示,272020.,一些Socket编程的概念,流(Stream)连接(Connection)阻塞(Block)、非阻塞(Non-block)同步(Synchronous)、异步(asynchronous)IP地址(IPAddress)字节顺序(BytesOrder)带外数据(OutbandData),272020.,需要用到的头文件,数据类型:#include函数定义:#include,272020.,BerkeleySocket常用函数列表,网络连接函数获取/设置socket的参数或信息转换函数,272020.,网络连接函数,socketbindconnectlistenacceptselectrecv,recvfromsend,sendtoclose,shutdown,272020.,获取/设置socket的参数或信息,gethostbyaddr,gethostbynamegethostnamegetpeernamegetprotobyname,getprotobynumbergetservbyname,getservbyportgetsocknamegetsockopt,setsockoptioctl,272020.,转换函数,IP地址转换inet_addr()inet_ntoa()字节顺序转换htons()-HosttoNetworkShorthtonl()-HosttoNetworkLongntohs()-NetworktoHostShortntohl()-NetworktoHostLong,272020.,socketaddressstructuresforInternet,XNSandUnixfamilies,Structsockaddr_inStructsockaddr_us,structsockaddr_un,272020.,socketaddress,ThefamilyisoneofAF_UNIXUnixinternalprotocolsAF_INETInternetprotocolsAF_NSXeroxNSprotocolsAF_IMPLINKIMPlinklayer其中,AF_代表“addressfamily”Socket地址的数据部分根据不同的地址类型来解释,常见的地址类型是internet、XNS和UNIX。对于使用最多的INTERNET簇,其网络地址主要包括两大部分:端口号、IP地址,它的地址结构在中定义,272020.,数据结构:sockaddr_in,Internet地址structsockaddr_inshortintsin_family;/*Addressfamily*/unsignedshortintsin_port;/*Portnumber*/*16-bitportnumber,networkbyteordered*/structin_addrsin_addr;/*Internetaddress*/*32-bitnetid/hostid(IP)地址,networkbyteordered*/unsignedcharsin_zero8;/*unused*/;该结构与sockaddr兼容,供用户填入参数,272020.,程序中实际只填写sockaddr_in结构,structsockaddr_inmy_addr;my_addr.sin_family=AF_INET;my_addr.sin_port=htons(3490);/*short,NBO*/my_addr.sin_addr.s_addr=inet_addr(0);bzero(注意:sin_addr.s_addr填本机IP地址,如果此项填INADDR_ANY时,表示自动取本机IP填入该项(仅用于Server),272020.,创建一个socketSocket描述符与Linux中的文件描述符类似,也是一个int型的变量函数调用:intsocket(intfamily,inttype,intprotocol);函数返回Socket描述符,返回-1表示出错family参数一般取AF_INET,protocol参数一般取0应用示例:TCP:sockfd=socket(AF_INET,SOCK_STREAM,0);UDP:sockfd=socket(AF_INET,SOCK_DGRAM,0);,socket()调用,272020.,“协议”与“family”及“type”域的可能组合,272020.,在服务器上运行,给socket指定一个众所周知的(well-known)端口地址intbind(intsockfd,conststructsockaddr*myaddr,socklen_taddrlen),bind()调用,如果调用成功,则返回值为0,如果调用失败返回值为-1,并设定相应的错误代码errno。最常见的错误是该端口已经被其他程序绑定。需要注意的一点:在Linux系统中,1024以下的端口(即众所周知的端口)只有拥有root权限的程序才能绑定,272020.,bind()调用,bind()系统调用主要用处:A)服务员(Server)向系统注册它的众所周知的地址,它告诉系统:“这是我的地址(服务),所有以这个地址接收的报文都交给我,由我来服务。”面向连接和无连接的服务员在接受顾客的请求之前都必须做这一步。B)顾客(Client)可为它自己注册一个特定的地址,以便通信的对方(服务员)可以用这个有效的地址送回响应,这就像在信封上要写明回信地址的道理一样。,272020.,开始监听已经绑定的端口需要在此前调用bind()函数,否则由系统指定一个随机的端口intlisten(intsockfd,intqueue_length);接收队列一个新的Client的连接请求先被放在接收队列中,等待Server程序调用accept函数接受该连接请求queue_length用于指定接收队列的长度,也就是在Server程序调用accept函数之前最大允许进入的连接请求数,多余的连接请求将被拒绝,典型取值为5,listen()调用,272020.,操作系统,Web服务器,服务器初始化,272020.,建立与服务器的连接(Client端使用)intconnect(intsockfd,conststructsockaddr*servaddr,socklen_taddrlen)servaddr是事先填写好的结构,用于指定所要连接的服务器的地址(Server的IP地址和端口号)。,connect()调用,272020.,OS,1.socket(),Web服务器,2.bind(80),3.listen(),80,Listenqueue,客户,connect(),Requestfrom(IP,port),建立与服务器的连接,272020.,操作系统,Web服务器,80,Listen队列,客户1,客户3,客户2,客户请求在listen队列中获取先进先出服务(排队),服务器忙,272020.,accept(),accept()函数用于响应客户的连接请求,建立与客户端的连接(Server端使用)产生一个新的socket描述符来描述该连接这个连接用来与发起该连接请求的Client交换信息intaccept(intsockfd,structsockaddr*addr,socklen_t*addrlen);addr将在函数调用后被填入连接对方(客户端)的地址信息,如对方的IP、端口等。accept缺省是阻塞函数,如果队列中没有连接请求等待,那么就会使调用方阻塞,直到有一个连接请求到达。,272020.,操作系统,Web服务器,80,Listen队列,客户1,客户3,客户2,客户请求在listen队列中夺取先进先出服务,accept(),已连接的socket,accept()调用,272020.,accept()的使用,#include#include#include#defineMYPORT80/*theportuserswillbeconnectingto*/#defineBACKLOG5/*howmanypendingconnectionsqueuewillhold*/main()intsockfd,new_fd;/*listenonsock_fd,newconnectiononnew_fd*/structsockaddr_inmy_addr;/*myaddressinformation*/structsockaddr_intheir_addr;/*connectorsaddressinformation*/intsin_size;sockfd=socket(AF_INET,SOCK_STREAM,0);/*dosomeerrorchecking!*/,272020.,accept(),my_addr.sin_family=AF_INET;/*hostbyteorder*/my_addr.sin_port=htons(MYPORT);/*short,networkbyteorder*/my_addr.sin_addr.s_addr=INADDR_ANY;/*auto-fillwithmyIP*/bzero(,272020.,服务器都可工作在两种不同的方式:循环方式(iterativemode)在计算机中一次只运行一个服务器进程。当有多个客户进程请求服务时,服务器进程就按请求的先后顺序依次做出响应。并发方式(concurrent)在计算机中同时运行多个服务器进程,每一个服务器进程对某个特定的客户进程做出响应。,服务器的两种工作方式,272020.,循环型服务员代码,intsockfd,newsockfd;if(sockfd=socket()0)err_sys(“socketerror”);if(bind(sockfd,)0)err_sys(“binderror”);if(listen(sockfd,5)0)err_sys(“listenerror”);for(;)newsockfd=accept(sockfd,);/*blocks*/if(newsockfd0)err_sys(“accepterror”);doit(newsockfd);/*processtherequest*/close(newsockfd);,272020.,并发型服务员代码,intsockfd,newsockfd;if(sockfd=socket()0)err_sys(“socketerror”);if(bind(sockfd,)0)err_sys(“binderror”);if(listen(sockfd,5)0)err_sys(“listenerror”);for(;)newsockfd=accept(sockfd,);/*blocks*/if(newsockfd0)err_sys(“accepterror”);if(fork()=0)/*child*/close(sockfd);doit(newsockfd);/*processtherequest*/exit(0);close(newsockfd);/*parent*/,272020.,发送和接收,在完成了上述的初始化工作后,就可以开始传输数据了。面向连接的发送和接收:send()andrecv()无连接协议的发送和接收:sendto()和recvfrom(),272020.,recv,用于TCP协议中接收信息intrecv(intsockfd,void*buf,intlen,intflags);Buf:指向容纳接收信息的缓冲区的指针Len:接收缓冲区的大小Flags:接收标志(其含义将在后面介绍)函数返回实际接收到的字节数,返回-1表示出错recv缺省是阻塞函数,直到接收到信息或出错才返回,272020.,send,用于TCP协议中发送信息intsend(intsockfd,constvoid*msg,intlen,intflags);Msg:指向待发送信息的指针Len:待发送的字节数Flags:发送标志(其含义将在后面介绍)函数返回已发送的字节数,返回-1表示出错send缺省是阻塞函数,直到发送完毕或出错注意:如果函数返回值与参数len不相等,则剩余的未发送信息需要再次发送,272020.,recvfrom,用于UDP协议中接收信息intrecvfrom(intsockfd,void*buf,intlen,unsignedintflagsstructsockaddr*from,int*fromlen);Buf:指向容纳接收信息的缓冲区的指针Len:缓冲区的大小Flags:接收标志(其含义将在后面介绍)From:指明接收数据的来源Fromlen:地址长度函数返回实际接收的字节数,返回-1表示出错recvfrom是阻塞函数,直到接收到信息或出错,272020.,sendto,用于UDP协议中发送信息intsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,conststructsockaddr*to,inttolen);Buf:指向容纳发送报文的缓冲区的指针Len:缓冲区的大小Flags:发送标志To:指明发送数据的目的地tolen:地址长度函数返回已发送的字节数,返回-1表示出错sendto缺省是阻塞函数,直到发送完毕或出错注意:如果函数返回值与参数len不相等,则剩余的未发送信息需要再次发送,272020.,send,sendto,recv,recvfrom函数调用的参数:flags,Flags一般情况下设置为0。但可以选择下列设置MSG_DONTROUTE对send,sendto有效表示不使用路由(一般不使用)MSG_PEEK对recv,recvfrom有效表示读出网络数据后不清除已读的数据MSG_OOB对发送接收都有效表示读/写带外数据(out-of-banddata),272020.,close,关闭特定的socket连接调用函数:intclose(intsockfd);关闭连接将中断对该socket的读写操作。关闭用于listen()函数的socket将禁止其他Client的连接请求,272020.,shutdown,Shutdown()函数可以单方面的中断连接,即禁止某个方向的信息传递。函数调用intshutdown(intsockfd,inthow);参数how:0-禁止接收信息1-禁止发送信息2-接收和发送都被禁止,与close()函数效果相同返回0表示调用成功,返回-1表示出错,272020.,select,应用于多路同步I/O模式,实现非阻塞的同步I/Ointselect(intnumfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);numfds是要多路选择的socket的最大值其中readfds,writefds,exceptfds都是socket事件集合,分别代表有数据可读、有数据要写、发生异常的socket集合。timeout是select的时间限制返回值:在socket集合中准备好的socket个数,272020.,socket集合,集合变量类型:fd_set集合变量运算宏:FD_ZERO(*set)清空socket集合FD_SET(s,*set)将s加入socket集合FD_CLR(s,*set)从socket集合去掉sFD_ISSET(s,*set)判断s是否在socket集合中常数FD_SETSIZE:集合元素的最多个数,272020.,Select应用举例,fd_setrset;/*可读的socket集合*/FD_ZERO(/*maxfd是已知的最大的socket*/*只考虑数据可读事件*/if(FD_ISSET(sockfd,-其中,参数peer是一个指向structsockaddr或者structsockaddr_in的指针。如果执行成功,我们就得到了对方的地址和端口号,然后用inet_ntoa()和gethostbyaddr()来得到对方更多的信息。,272020.,其他基本的系统调用,getsockname该系统调用返回和一个管套相联系的本地名字-#include#includeintgetsockname(intsockfd,structsockaddr*addr,int*addrlen);-addr用来存放返回的本地地址;addrlen存放的是返回的地址的长度。,272020.,其他基本的系统调用,系统调用gethostname()-#includeintgethostname(char*hostname,size_tsize);-hostname是一个存放主机名字(域名)的字符数组返回的hostname可以作为gethostbyname()的参数,调用该系统调用,这样又可以得到自己的IP地址了。,272020.,其他基本的系统调用,字节排序在字节顺序不一致时可以用下列的4中函数来进行转换。#include#includeu_longhtonl(u_longhostlong);/*主机网络转换,长整数*/u_shorthtons(u_longhostlong);/*主机网络转换,短整数*/u_longntohl(u_longhostlong);/*网络主机转换,长整数*/u_chortntohs(u_longhostlong);/*网络主机转换,短整数*/这些函数是为internet协议集而设计的,XNS协议集采用的字节顺序与internet相同,故可以借用。值得注意的是,这里的长整数为32位,短整数为16位。,272020.,其他基本的系统调用,字节操作Bcopy(char*src,char*dest,intnbytes);字符串拷贝Bzero(char*dest,intnbytes);把指定数量的空字节写入指定的目的地址。Intbcmp(char*ptr1,char*ptr2,intnbytes);对任意两个字符串进行比较。返回值(与标准I/O函数strcmp的返回值不同):0-相同非零-不相同。,272020.,其他基本的系统调用,IP地址格式转换下

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论