第6章 嵌入式Linux文件处理与串口通信(新)2_第1页
第6章 嵌入式Linux文件处理与串口通信(新)2_第2页
第6章 嵌入式Linux文件处理与串口通信(新)2_第3页
第6章 嵌入式Linux文件处理与串口通信(新)2_第4页
第6章 嵌入式Linux文件处理与串口通信(新)2_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

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

文档简介

1、第6章 嵌入式Linux文件(wnjin)处理与串口通信 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页本章(bn zhn)要点1、文件描述符的概念2、系统调用的基本概念 3、文件读写等处理方法(fngf)4、嵌入式Linux中对串口的操作重庆大学电气工程学院嵌入式系统及其应用共一百零六页6.1嵌入式Linux的文件(wnjin)处理嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页6.1.1文件(wnjin)描述符及文件(wnjin)处理 1、文件及文件描述符由于在Linux下设备和目录都看作是文件,因此,Linux中的文件有4种类型:普通文件、目录文件、链接文件

2、和设备文件。Linux的内核利用文件描述符访问文件。文件描述符是非负整数,它是一个索引(suyn)值,并指向内核中每个进程打开文件的记录表。当打开一个现存文件或新建一个文件时,内核会向进程返回一个文件描述符。当读写文件时,也需要使用文件描述符来指定待读写的文件。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页 在Linux中对目录和设备的操作都等同于文件的操作,因此,大大简化了系统对不同(b tn)设备的处理,提高了效率。 Linux中的文件(wnjin)主要分为4种 普通文件 目录文件 链接文件 设备文件 嵌入式系统及其应用重庆大学电气工程学院共一百零六页 普通文件也称作常规(chngg

3、u)文件,包含各种长度的字节串。核心对这些数据没有进行结构化,只是作为有序的字节序列把它提交给应用程序。应用程序自己组织和解释这些数据,通常把它们归并为下述类型之一: 普通(ptng)文件文本文件,由ASCII字符构成。 数据文件,由来自应用程序的数字型和文本型数据构成。 可执行的二进制程序,由机器指令和数据构成。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页目录(ml)文件 目录是一类特殊的文件,利用它可以构成文件系统的分层树型结构。如同普通文件那样,目录文件也包含(bohn)数据;但目录文件与普通文件的差别是,核心对这些数据加以结构化,它是由成对的“I节点号/文件名”构成的列表。 I

4、节点中存放有文件的状态信息。 文件名是给一个文件分配的文本形式的字符串,用来标识该文件。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页链接(lin ji)文件 Linux具有为一个文件起多个名字的功能,称为链接。被链接的文件可以存放在相同的或不同的目录下。如果在同一目录下,二者必须(bx)有不同的文件名,而不用在硬盘上为同样的数据重复备份;如果在不同的目录下,那么被链接的文件可以与原文件同名,只要对一个目录下的该文件进行修改,就可以完成对所有目录下同名链接文件的修改。对于某文件的各个链接文件,我们可以给它们指定不同的存取权限,以控制对信息的共享和增强安全性。 文件链接分为硬链接和软链接两

5、种形式 嵌入式系统及其应用重庆大学电气工程学院共一百零六页设备(shbi)文件 在Linux系统中,所有设备都作为一种(y zhn)特别文件对待,用户像使用普通文件那样对设备进行操作,从而实现设备无关性。但是,设备文件除了存放在文件I节点中的信息外,它们不包含任何数据。系统利用它们来标识各个设备驱动器,核心使用它们与硬件设备通信。 字符设备 块设备 有两类特别设备文件,它们对应不同类型的设备 嵌入式系统及其应用重庆大学电气工程学院共一百零六页 内核如何区分和引用特定的文件呢?这里用到的就是个重要的概念文件描述符。对于Linux而言,所有对设备和文件的操作都使用文件描述符来进行的。文件描述符是一

6、个非负的整数,它是个索引(suyn)值,并指向内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页2、系统(xtng)调用 系统调用是操作系统提供给用户程序调用的一组“特殊”接口。 使用系统主要目的是使得用户可以使用操作系统提供的有关设备管理、输入/输出系统、文件系统和进程控制、通信以及存储管理等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻(jinqng)用户负担和保护系统以及提高资源利用率的作用

7、。嵌入式系统及其应用重庆大学电气工程学院共一百零六页Linux的运行空间划分为用户空间和内核空间,它们各自运行在不同(b tn)的级别中,所以用户进程在通常情况下不允许访问内核,也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间函数。这样做的目的是为了对系统作必要的“保护”措施,但是使用系统调用可以最大程度地解决这一问题。嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页Linux系统(xtng)有200多个系统调用,这些系统调用按照功能分类大致可分为以下几个方面:进程控制 文件系统控制 系统控制 存储管理 网络管理 socket控制 用户(yngh)管理 进程间通信

8、 嵌入式系统及其应用重庆大学电气工程学院共一百零六页用户(yngh)编程接口(API) 系统调用并不是直接与程序员进行交互的,它仅仅是个通过软中断机制向内核提交请求,以获取内核服务(fw)的接口。在实际使用中程序员调用的通常是用户编程接口API。但并不是所有的函数都对应个系统调用,有时,一个API函数会需要几个系统调用来共同完成函数的功能,其至还有些API函数不需要调用相应的系统调用(因此它所完成的不是内核提供的服务)。嵌入式系统及其应用重庆大学电气工程学院共一百零六页嵌入式系统(xtng)及其应用重庆大学电气(dinq)工程学院共一百零六页3、文件(wnjin)处理Linux系统的文件处理,

9、主要是指进行打开文件、读文件、写文件及关闭文件等I/O操作。大多数情况下,只需用到5个函数:open、read、write、lseek 和close。这几个函数不需要经过缓冲就能立即执行(zhxng),因此,被称之为不带缓存的I/O操作,即每一个函数都只调用内核中的一个系统调用。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页6.1.2open函数(hnsh)和close函数 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页1、open函数(hnsh)open函数用于打开或创建文件。调用open函数所需要的头文件如下(rxi):#include #include #inclu

10、de 其函数为:int open(const char *pathname, int oflag, int perms ) ;函数返回值:若文件打开成功则返回文件描述符,若出错则返回-1。嵌入式系统及其应用重庆大学电气工程学院共一百零六页所需头文件#include#include#include函数原型int open(const char *pathname, flags, int perms)pathname被打开的文件名(可包括路径名)flag:文件打开的方式O_RDONLY:只读方式打开文件O_WRONLY:只写方式打开文件O_RDWR:读写方式打开文件O_CREAT:如果该文件不存在

11、,就创建一个新的文件,并用第三个参数为其设置权限O_EXCL:如果同时使用O_CREAT时文件存在,则返回错误消息。这一参数可测试文件是否存在O_NOCTTY:使用本参数时,如文件为终端,那么终端不可以作为调用open()系统调用的那个进程的控制终端O_TRUNC:如文件已经存在,并且以只读或只写成功打开,那么会先全部删除文件中原有数据O_APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾perms被打开文件的存取权限,为8进制表示法函数返回值成功:返回文件描述符失败:-1在open函数(hnsh)中,flag参数可通过组合构成,但前3个函数不能相互组合 共一百零六页2

12、、close函数(hnsh)close函数用于关闭一个打开(d ki)的文件,所需要的头文件为:#include 其函数为:int close(int fd);函数返回值:若成功为0,若出错为-1。关闭文件函数close的参数fd为文件描述符。嵌入式系统及其应用重庆大学电气工程学院共一百零六页open和close函数(hnsh)使用实例实例中的open函数带有3个flag参数:O_CREAT、O_TRUNC和O_WRONLY,这样就可以(ky)对不同的情况指定相应的处理方法。另外,这里对该文件的权限设置为0600 。嵌入式系统及其应用重庆大学电气工程学院共一百零六页文件(wnjin)操作所需头

13、文件(wnjin)打开(d ki)当前目录下hello.c文件文件名文件打开的方式文件的权限打开文件操作成功打印显示文件描述符关闭文件文件描述符定义变量fd用于保存文件描述符共一百零六页执行程序打开文件(wnjin)后输出信息文件(wnjin)描述的值关闭文件后打印输出信息嵌入式系统及其应用重庆大学电气工程学院共一百零六页查看(chkn)当前目录中的文件创建(chungjin)了hello.c文件文件的权限嵌入式系统及其应用重庆大学电气工程学院共一百零六页文件(wnjin)的权限共一百零六页查看(chkn)当前目录中的文件创建(chungjin)了hello.c文件嵌入式系统及其应用重庆大学电

14、气工程学院共一百零六页注意:open函数返回的又件描述符一定是最小的未用文件描述符。由于一个进程在启动时自动打开了0、1、2三个文件描述符,因此,该文件运行结果中返回的文件描述符为3。可以尝试在调用open函数之前,加一句close(0),则此后(c hu)在open函数时返回的文件描述符为0(若关闭文件描述符1,则在执行时会由于没有标准输出文件而无法输出)。 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页关闭标准输入(shr)文件打印文件描述符文件(wnjin)描述符共一百零六页执行程序文件打开成功(chnggng)后输出的信息文件(wnjin)描述符嵌入式系统及其应用重庆大

15、学电气工程学院共一百零六页关闭标准(biozhn)输出文件前,输出一个信息关闭(gunb)标准输出文件共一百零六页查看(chkn)当前目录中的文件只输出了关闭标准(biozhn)输出文件以前的输出信息嵌入式系统及其应用重庆大学电气工程学院共一百零六页6.1.3read函数(hnsh)、write函数和lseek函数嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页1、read函数(hnsh) read函数从打开(d ki)的文件中读取数据。 调用read函数所需要的头文件: # include 其函数原型为:ssize_t read(int fd, void *buf, size_

16、t count);函数返回值为读到数据的字节数,若返回值为0,则已经到达文件尾,若返回-1则为出错。嵌入式系统及其应用重庆大学电气工程学院共一百零六页read函数(hnsh)语法要点 所需头文件#include 函数原型ssize_t read(int fd, void *buf, size_t count)函数输入值fd:文件描述符buf:指定读出数据的存储缓冲区指针count:指定读出的字节数函数返回值成功:读出数据的字节数0:已到达文件尾部-1:出错在读普通文件(wnjin)时,若读到要求的字节数之前己到达文件(wnjin)的尾部,则返回的字节数会小于希望读出的字节数。 嵌入式系统及其应

17、用重庆大学电气工程学院共一百零六页2、write函数(hnsh)write函数用于向打开的文件(wnjin)实现写入数据的操作。写操作的位置从文件(wnjin)的当前位移量处开始。若磁盘已满或超出该文件(wnjin)的长度,则write函数返回错误值。调用write函数所需要的头文件:#include 其函数原型为:ssize_t write(int fd, void *buf, size_t count);函数返回值为已写入数据的字节数,若返回-1则出错。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页write函数(hnsh)语法要点 所需头文件#include 函数原型ssize_t

18、 write(int fd, void *buf, size_t count)函数输入值fd:文件描述符buf:指定写入数据的存储缓冲区指针count:指定写入的字节数函数返回值成功:写入数据的字节数-1:出错在写普通文件(wnjin)时,写操作从文件(wnjin)的当前位移处开始。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页3、lseek函数(hnsh) lseek函数用于在由指定的文件描述符的文件中将文件指针定位到相应的位置,以进行读写操作。 调用lseek函数所需要的头文件:#include #include 其函数原型为:off_t lseek(int fd, off_t of

19、fset, int whence);函数返回值为文件的当前位移(wiy),若返回-1则出错。嵌入式系统及其应用重庆大学电气工程学院共一百零六页lseek函数语法(yf)要点 所需头文件#include #include 函数原型off_t lseek(int fd, off_t offset, int whence)函数输入值fd:文件描述符offset:偏移量,每次读写操作所需要移动的距离,单位是字节数,可正可负(向前或向后移)whence:当前位置的基点SEEK_SET:当前位置为文件的开头,新位置为相对于文件头的偏移量SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量

20、SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量函数返回值成功:文件的当前位移-1:出错嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页函数(hnsh)使用实例 该示例程序首先(shuxin)打开上一节中创建的文件,然后对此文件进行读写操作(注意要将文件打开属性改为可读写,将文件权限也做相应更改)。接着,写入“Hello! Im writing to this file!”,此时文件指针位于文件尾部。接着再使用lseek函数将文件指针移到文件开始处,并读出10个字节并将其打印出来。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页文件(wnjin)读写操作函

21、数所需头文件(wnjin)定义一个(y )字符串,用以写入文件定义一个数组,有11个元素,用作读缓冲区获取字符串的长度写文件操作写入数据的存储缓冲区指针写入数据字节数共一百零六页将文件(wnjin)指针移到文件(wnjin)头部当前(dngqin)位置的基准点读文件操作共一百零六页嵌入式系统(xtng)及其应用重庆大学电气(dinq)工程学院共一百零六页嵌入式系统(xtng)及其应用重庆大学电气(dinq)工程学院共一百零六页6.2 嵌入式Linux串口通信(tng xn)技术 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页6.2.1 嵌入式Linux串口通信(tng xn)基

22、础嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页1、串口通信的工作(gngzu)原理所谓“串口通信”是指外设和计算机间使用一根数据信号线(另外需要地线),数据在一根数据信号线上一位一位地进行传输,每一位数据都占据一个固定的时间长度。在串口传输中,发送方为了告诉接收方,新的数据字节分组到达,在每一个数据字节分组前面有一个起始位(通常是0),为了让接收方知道字节已经结束,在每一个数据字节分组后面(hu mian)有一个停止位(通常是1)。接收方一旦检测到停止位,接收方会一直等待,直到下一个开始位。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页图6.1 串行传输数据的工作(gn

23、gzu)原理嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页嵌入式系统串行通信采用(ciyng)EIA RS-232C标准,为单向不平衡传输方式,信号电平标准12V,负逻辑,即逻辑1(MARKING)表示为信号电平-12V,逻辑0(SPACING)表示为信号电平+12V,最大传送距离15米,最大传送速率19.6K波特,其传送序列如图6.1,平时线路保持为1,传送数据开始时,先发送起始位(其数据值是0),然后传8(或7,6,5)个数据位(其数据值是0,1),接着可传1位奇偶校验位,最后为12个停止位(其数据值是1),由此可见,传送一个ASCII字符(7位),加上同步信号最少需9位数

24、据位。 重庆大学电气(dinq)工程学院嵌入式系统及其应用共一百零六页2、常用信号(xnho)引脚与串口通信接线 图6.2 串口的连接线嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页6.2.2 嵌入式Linux串口设置(shzh)详解嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页1、起始(q sh)位 通信线路上没有(mi yu)数据被传送时,处于逻辑“1”的状态。当发送设备要发送字符数据时,首先发送一个逻辑“0”信号,这个逻辑低电平就是起始位。起始位通过通信线路传输到接收端,接收端检测到这个低电平后,就开始准备接收数据位信号。起始位所起的作用就是使通信双方同步

25、。 重庆大学电气工程学院嵌入式系统及其应用共一百零六页2、数据位 当接收端收到起始位后,开始接收数据位。数据位的个数可以是58位。在数据(shj)传送过程中,数据(shj)位从最低有效位开始传送,接收端收到数据(shj)后,依次将其转换成并行数据(shj)。 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页3、奇偶校验位数据位发送完后,为了保证数据的可靠性,还要再传送(chun sn)一个奇偶校验位。奇偶校验用于差错检测。如果选择偶校验,则数据位和奇偶位的逻辑“1”的个数必须为偶数,相反,如果是奇校验,数据位和奇偶位的逻辑“1”的个数为奇数。嵌入式系统(xtng)及其应用重庆大学

26、电气工程学院共一百零六页4、停止(tngzh)位在奇偶位或数据位(当无奇偶校验时)之后发送停止位。停止位表示一个数据的结束。它可以是12位的“1”。接收端收到停止位后,通信线路便恢复逻辑“1”的状态(zhungti),直到下一个数据的起始位到来。嵌入式系统及其应用重庆大学电气工程学院共一百零六页5、波特率设置(shzh) 通信线路上传输的位(码元)信号都必须保持一致的信号持续时间,单位时间内传送码元的数目称为波特率。 对于(duy)大多数嵌入式设备来说,其波特率都设置为115200。在Linux中,所有的设备文件一般都位于“/dev”下,其中串口一、串口二所对应的设备名依次为“/dev/tty

27、S0”、“/dev/ttyS1”,可以查看在“/dev”下的文件以确认。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页6.2.3RS232C标准(biozhn) 嵌入式系统(xtng)及其应用重庆大学电气工程学院由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串口通讯的标准,它的全称是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”。该标准规定采用一个DB25芯引脚的连接器或DB9芯引脚的连接器共一百零六页1、电气(dinq)特性2、引脚定义嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页嵌入式系

28、统(xtng)及其应用重庆大学电气(dinq)工程学院共一百零六页嵌入式系统(xtng)及其应用重庆大学电气(dinq)工程学院共一百零六页3、字符(z f)(帧)格式 RS232C采用起止式异步通信协议,其特点是一个字符接着一个字符进行传输,并且传送一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。其传输格式如图6.1所示,每一个字符的前面都有一位起始位(低电平,逻辑值“0”),字符本身有58位数据位,接着字符后面是一位校验码(也可以没有校验码),最后是停止位。停止位后面是不定长度(chngd)的空闲位。停止位和空闲位都规定为高电平(逻辑值“1”),这样就能保证起始位开

29、始处一定有一个下跳沿,便于接收方识别。嵌入式系统及其应用重庆大学电气工程学院共一百零六页用奇偶校验位将所传字符(z f)中为“1”的位数凑成奇数个或偶数个数据位可设为5,6,7,8位嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页4、握手(w shu)协议 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页5、双机互连方式(fngsh) (1)无硬件握手(w shu)情况嵌入式系统及其应用重庆大学电气工程学院共一百零六页(2)DTR和DSR握手(w shu)情况嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页(3)RTS和CTS握手(w shu)情况重庆

30、大学电气(dinq)工程学院嵌入式系统及其应用共一百零六页6.2.4串口驱动程序的编写(binxi) 一个串口驱动程序,通常包括打开串口、设置串口参数(cnsh)、对串口进行读写操作等内容。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页S3C2410X内部具有2个独立的UART控制器,每个控制器都可以工作在Interrupt(中断)模式或者DMA(直接内存访问)模式。另外,每个UART均具有16字节的FIFO(先进先出寄存器),支持的最高波特率可达到230.4Kbps。UART的操作主要可分为以下几个(j )部分:信息发送、信息接收、产生中断、产生波特率、Loopback模式、红外模式以

31、及自动流程模式。 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页1、串口操作(cozu)需要的头文件#include /*标准输入输出定义(dngy)*/#include /*标准函数库定义*/#include /*Unix 标准函数定义*/#include #include #include /*文件控制定义*/#include /*终端控制定义*/#include /*错误号定义*/嵌入式系统及其应用重庆大学电气工程学院共一百零六页2、打开(d ki)串口 通常嵌入式 Linux 系统下的串口文件是位于 /dev 下: 串口一 为 /dev/ttyS0; 串口二 为 /de

32、v/ttyS1。打开串口是通过打开函数(hnsh)open( ) 进行的 。int fd;/文件描述符fd = open( “/dev/ttyS0”, O_RDWR);/以读写方式打开串口嵌入式系统及其应用重庆大学电气工程学院共一百零六页3、设置(shzh)串口参数 最基本的串口参数设置(shzh)包括波特率设置(shzh),校验位和停止位设置(shzh)。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页嵌入式系统(xtng)及其应用重庆大学电气(dinq)工程学院#include struct termio unsigned short c_iflag; /*输入模式标志*/ unsig

33、ned short c_oflag; /*输出模式标志*/ unsigned short c_cflag; /*控制模式标志*/ unsigned short c_lflag; /*本地模式标志*/ unsigned char c_line; /*线路规范*/ unsigned char c_ccNCC; /*控制特征值*/;在这个结构中最为重要的是c_cflag,通过对它的赋值,用户可以设置波特率、数据位、停止位、奇偶校验位和硬件流控等。另外c_iflag和c_cc也是比较常用的标志。在此主要对这3个成员进行详细说明。 串口的设置主要是设置struct termios结构体的各成员值,如下所

34、示: 共一百零六页B00波特率(放弃DTR)B96009600波特率B1920019200波特率B3840038400波特率B5760057600波特率B115200115200波特率EXTA外部时钟率EXTB外部时钟率CS55个数据位CS66个数据位CS77个数据位CS88个数据位CSTOPB2个停止位(不设则是1个停止位)CREAD接收使能PARENB校验位使能PARODD使用奇校验而不使用偶校验HUPCL最后关闭时挂线(放弃DTR)CLOCAL本地连接(不改变端口所有者)LOBLK块作业控制输出CNET_CTSRTS硬件流控制使能c_cflag支持(zhch)的常量名称 波特率设置(sh

35、zh)为相应的波特率值前加上B 字符长度 CBAUD波特率的位掩码CSIZE数据位的位掩码在这里,对于c_cflag成员不能直接对其初始化,而要将其通过“与”、“或”操作使用其中的某些选项。 共一百零六页INPCK奇偶校验使能IGNPAR忽略奇偶校验错误PARMRK奇偶校验错误掩码ISTRIP除去奇偶校验位IXON启动出口硬件流控IXOFF启动入口软件流控IXANY允许字符重新启动流控IGNBRK忽略中断情况BRKINT当发生中断时发送SIGINT信号INLCR将NL映射到CRIGNCR忽略CRICRNL将CR映射到NLIUCLC将高位情况映射到低位情况IMAXBEL当输入太长时回复ECHOc

36、_iflag支持的常量(chngling)名称 奇偶校验控制(kngzh)共一百零六页c_cc支持(zhch)的常量名称 VINTR中断控制,对应键为CTRL+CVQUIT退出操作,对应键为CTRL+ZVERAST删除操作,对应键为Backspace(BS)VKILL删除行,对应键为CTRL+UVEOF位于文件结尾,对应键为CTRL+DVEOL位于行尾,对应键为Carriage return(CR)VEOL2位于第二行尾,对应键为Line feed(LF)VMIN指定了最少读取的字符数VTIME指定了读取每个字符的等待时间嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页设置(sh

37、zh)串口属性的基本流程保存原先串口配置首先,为了安全(nqun)起见和以后调试程序方便,可以先保存原先串口的配置,在这里可以使用函数tcgetattr (fd, oldtio)。该函数得到与fd指向对象的相关参数,并将它们保存于oldtio引用的termios结构中。该函数还可以测试配置是否正确、该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为-1。 重庆大学电气工程学院嵌入式系统及其应用共一百零六页使用(shyng)如下所示: if ( tcgetattr ( fd, &oldtio ) != 0 ) perror ( “Setup Serial 1” ); retu

38、rn -1;指向一个(y )对象保存原来的配置参数重庆大学电气工程学院嵌入式系统及其应用共一百零六页激活(j hu)选项有CLOCAL和CREAD CLOCAL和CREAD分别用于本地连接和接受使能,因此,首先(shuxin)要通过位掩码的方式激话这两个选项。 newtio.c_cflag |= CLOCAL | CREAD; 嵌入式系统及其应用重庆大学电气工程学院共一百零六页设置(shzh)波特率设置波特率有专门的函数,用户不能直接通过(tnggu)位掩码来操作。设置波特率的主要函数有cfsetispeed和cfsetospeed。这两个函数的使用很简单,如下所示: cfsetispeed

39、( &newtio, B115200 );cfsetospeed ( &newtio, B115200 );一般情况下,用户需将输入输出函数的波特率设置成一样的。这几个函数在成功时返回0,失败时返回-1。 波特率决定了串口通讯 的速率,每一个数据位 的宽度等于传送波特率 的倒数嵌入式系统及其应用重庆大学电气工程学院共一百零六页设置(shzh)数据位数与设置波特率不同(b tn),设置数据位数并没有现成可用的函数,需要用位掩码。一般首先去除数据位中的位掩码,再重新按要求设置。如下所示: options.c_cflag &= CSIZE; options. c_cflag |= CS8;嵌入式系统

40、及其应用重庆大学电气工程学院共一百零六页 设置(shzh)奇偶校验位设置奇偶校验位需要用到两个termio中的成员:c_cflag和c_iflag。首先要激活(j hu)c_cflag中的检验位使能标志PARENB和是否要进行偶校验标志,同时还要激活c_iflag中的奇偶校验使能。嵌入式系统及其应用重庆大学电气工程学院共一百零六页如使能奇校验(xio yn)时,代码如下所示: newtio.c_cflag |= PARENB;newtio.c_cflag |= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);而使能偶校验(xio yn)时,代码为: newt

41、io.c_cflag |= PARENB;newtio.c_cflag &= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);newtio.c_cflag &= PARENB; 无校验,代码为: 嵌入式系统及其应用重庆大学电气工程学院共一百零六页设置(shzh)停止位设置停止(tngzh)位是通过激活c_cflag中的CSTOPB而实现的。若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。下面是停止位是1时的代码: newtio.c_cflag &= CSTOPB; 嵌入式系统及其应用重庆大学电气工程学院共一百零六页设置(shzh)最少字符

42、和等待时间在对接收字符和等待时间没有特别要求的情况下,可以将其设置(shzh)为0,如下所示: newtio.c_ccVTIME = 0;newtio.c_ccVMIN = 0;嵌入式系统及其应用重庆大学电气工程学院共一百零六页处理要写入的引用(ynyng)对象由于串口在重新设置(shzh)之后,在此之前要写入的引用对象要重新处理,这时就可调用函数tcflush(fd, queue_selector)来处理要写入引用的对象。对于尚未传输的数据,或者收到的但是尚未读取的数据,其处理方法取决于queue_selector的值。 这里,queue_selector可能的取值有以下几种。TCIFLUS

43、H:刷新收到的数据但是不读;TCOFLUSH:刷新写入的数据但是不传送;TCIOFLUSH:同时刷新收到的数据但是不读,刷新写入的数据但是不传送。 tcflush(fd, TCIFLUSH); 嵌入式系统及其应用重庆大学电气工程学院共一百零六页激活(j hu)配置在完成全部串口配置之后(zhhu),要撤活刚才的配置并使配置生效。这里用到的函数是tcsetattr,它的函数原型是: tcsetattr(fd, OPTION, &newtio) 嵌入式系统及其应用重庆大学电气工程学院共一百零六页TCSANOW:改变的配置立即生效。TCSADRAIN:改变的配置在所有(suyu)写入fd的输出都结束

44、后生效。TCSAFLUSH:改变的配置在所有写入fd引用对象的输出都被结束 后生效,所有已接受但未读入的输入都在改变发生前 丢弃。这里的newtio就是termios类型的变量(binling),OPTION可能的取值有以下三种:该函数若调用成功则返回0,若失败则返回-1。if(tcsetattr(fd,TCSANOW, &newtio) != 0) perror(“com set error”); return -1;嵌入式系统及其应用重庆大学电气工程学院共一百零六页程序(chngx)示例下面给出了串口配置的完整的函数。为了函数的通用性,将常用的选项都在函数中列出,这样可以方便调试(dio

45、sh)使用。 嵌入式系统及其应用重庆大学电气工程学院共一百零六页int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop) struct termios newtio, oldtio/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息(xnx)*/ if ( tcgetattr ( fd, &oldtio ) != 0 ) perror ( “Setup Serial 1” ); return -1; bzero(&newtio, sizeof(newtio);/*步骤一,设置字符大小*/ newti

46、o.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= CSIZE/*设置数据位*/ switch(nBits) case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; 共一百零六页/*设置(shzh)奇偶校验位*/switch(nEvent) case O: /奇校验 newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; ca

47、se E: /偶校验 newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= PARODD; break; case N: /无校验 newtio.c_cflag &= PARENB; break;/*设置波特率*/switch(nSpeed) case 2400: cfsetispeed ( &newtio, B2400 ); cfsetospeed ( &newtio, B2400 ); break;共一百零六页 case 4800: cfsetispeed ( &newtio, B48

48、00 ); cfsetospeed ( &newtio, B4800 ); break; case 9600: cfsetispeed ( &newtio, B9600 ); cfsetospeed ( &newtio, B9600 ); break; case 115200: cfsetispeed ( &newtio, B115200 ); cfsetospeed ( &newtio, B115200 ); break; case 460800: cfsetispeed ( &newtio, B460800 ); cfsetospeed ( &newtio, B460800 ); brea

49、k; default: cfsetispeed ( &newtio, B9600 ); cfsetospeed ( &newtio, B9600 ); break;共一百零六页/*设置停止位*/ if(nStop = = 1) newtio.c_cflag &= CSTOPB; else if(nStop = = 2) newtio.c_cflag |= CSTOPB;/*设置等待时间和最小接收(jishu)字符*/ newtio.c_ccVTIME = 0; newtio.c_ccVMIN = 0;/*处理未接收字符*/ tcflush(fd, TCIFLUSH);/*激活新配置*/ if(

50、tcsetattr(fd,TCSANOW, &newtio) != 0) perror(“com set error”); return -1; printf(“set done!n”); return 0;共一百零六页串口使用(shyng)详解 在配置完串口的相关属性后,就可以对串口进行打开、读写操作了。它所使用的函数和普通文件读写的函数一样,都是open、write和read。它们相区别的只是串口是一个终端设备,因此在函数具体参数的选择时会有一些区别。另外,这里(zhl)会用到一些附加的函数,用于测试终端设备的连接情况等。下面将对其进行具体讲解。 嵌入式系统及其应用重庆大学电气工程学院共一

51、百零六页打开(d ki)串口在Linux 下串口文件位于/dev 下,一般在老版本(bnbn)的内核中串口一为/dev/ttyS0 ,串口二为 /dev/ttyS1, 在我们的实验箱中串口设备位于/dev/tts/下,因为实验箱中没有ttyS0这个设备,所以我们要建立一个连接,如下听示: /mnt/yaffs cd /dev/dev ln sf /dev/tts/0 ttyS0嵌入式系统及其应用重庆大学电气工程学院共一百零六页打开串口和打开普通(ptng)文件一样,使用的函数都是open函数。 int fd;fd = open( /dev/ttyS0, O_RDWR | O_NOCTTY |

52、O_NDELAY); if (-1 = = fd) /* 不能打开(d ki)串口一*/ perror( 提示错误!);嵌入式系统及其应用重庆大学电气工程学院共一百零六页读写串口读写串口操作和读写普通文件一样(yyng),使用read、write函数即可。 嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页写串口(发送数据)char buffer1024;int Length1024;int nByte;nByte = write(fd, buffer ,Length)嵌入式系统(xtng)及其应用重庆大学电气(dinq)工程学院共一百零六页 读串口(接收数据)使用(shyng)文

53、件操作read 函数读取数据, read 函数返回的字符数是实际串口收到的字符数。char buff1024;int Len1024;int readByte = read(fd, buff, Len);嵌入式系统(xtng)及其应用重庆大学电气工程学院共一百零六页关闭(gunb)串口关闭串口就是(jish)关闭文件。 close(fd);嵌入式系统及其应用重庆大学电气工程学院共一百零六页共一百零六页#include /*PPSIX 终端控制定义(dngy)*/#include /*标准输入输出定义*/#include /*linux 标准函数定义*/#include /*文件控制定义*/#i

54、nclude #include /*线程库定义*/#define BAUDRATE B115200#define COM1 /dev/ttyS0#define COM2 /dev/ttyS1#define ENDMINITERM 27 /* ESC to quit miniterm */#define FALSE 0#define TRUE 1volatile int STOP=FALSE;volatile int fd;void child_handler(int s) printf(stop!n); STOP=TRUE;/*-*/struct termio 等所需的头文件波特率的宏定义(d

55、ngy)串口1和串口2的宏定义ESC键的ASCII值的宏定义定义变量是“易变”的信号处理函数共一百零六页void* keyboard(void * data) int c; for (;) c=getchar(); if( c= ENDMINITERM) STOP=TRUE; break ; return NULL;/*-*/* modem input handler */void* receive(void * data) int c; printf(read modemn); while (STOP=FALSE) read(fd,&c,1); /* com port */ write(1,&c,1); /* stdout */ 键盘处理(chl)线程函数获取一个(y )字符串口接收处理线程函数读串口函数,从串口读取一个数据将接收到的数据打印显示出来共一百零六页 printf(exit from reading modemn)

温馨提示

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

评论

0/150

提交评论