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

下载本文档

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

文档简介

1、第第6章章 嵌入式嵌入式Linux文件处理与串口通信文件处理与串口通信 嵌入式系统及其应用重庆大学电气工程学院本章要点本章要点 1、文件描述符的概念、文件描述符的概念 2、系统调用的基本概念、系统调用的基本概念 3、文件读写等处理方法、文件读写等处理方法 4、嵌入式、嵌入式Linux中对串口的操作中对串口的操作重庆大学电气工程学院嵌入式系统及其应用6.1嵌入式嵌入式Linux的文件处理的文件处理嵌入式系统及其应用重庆大学电气工程学院6.1.1文件描述符及文件处理文件描述符及文件处理 1、文件及文件描述符、文件及文件描述符 由于在由于在Linux下设备和目录都看作是文件,因此,下设备和目录都看作

2、是文件,因此,Linux中的文件有中的文件有4种类型:普通文件、目录文件、种类型:普通文件、目录文件、链接文件和设备文件。链接文件和设备文件。 Linux的内核利用文件描述符访问文件。文件描的内核利用文件描述符访问文件。文件描述符是非负整数,它是一个索引值,并指向内核述符是非负整数,它是一个索引值,并指向内核中每个进程打开文件的记录表。当打开一个现存中每个进程打开文件的记录表。当打开一个现存文件或新建一个文件时,内核会向进程返回一个文件或新建一个文件时,内核会向进程返回一个文件描述符。当读写文件时,也需要使用文件描文件描述符。当读写文件时,也需要使用文件描述符来指定待读写的文件。述符来指定待读

3、写的文件。 嵌入式系统及其应用重庆大学电气工程学院 在Linux中对目录和设备的操作都等同于文件的操作,因此,大大简化了系统对不同设备的处理,提高了效率。 Linux中的文件主要分为4种 普通文件 目录文件 链接文件 设备文件 嵌入式系统及其应用重庆大学电气工程学院 普通文件普通文件也称作常规文件常规文件,包含各种长度的字节串。核心对这些数据没有进行结构化,只是作为有序的字节序列把它提交给应用程序。应用程序自己组应用程序自己组织和解释这些数据织和解释这些数据,通常把它们归并为下述类型之一: 普通文件文本文件文本文件,由ASCII字符构成。 数据文件数据文件,由来自应用程序的数字型和文本型数据构

4、成。 可执行的二进制程序可执行的二进制程序,由机器指令和数据构成。 嵌入式系统及其应用重庆大学电气工程学院目录文件 目录是一类特殊的文件目录是一类特殊的文件,利用它可以构成文件系统的分层树型结构。如同普通文件那样,目录文件也包含数据;但目录文件与普通文件的差别目录文件与普通文件的差别是,核心对这些数据核心对这些数据加以结构化加以结构化,它是由成对的“I节点号节点号/文件名文件名”构成的列表。 I节点节点中存放有文件的状态信息。 文件名文件名是给一个文件分配的文本形式的字符串,用来标识该文件。 嵌入式系统及其应用重庆大学电气工程学院链接文件 Linux具有为一个文件起多个名字的功能,称为链接链接

5、。被链接的文件可以存放在相同的或不同的目录下相同的或不同的目录下。如果在同一目录下,二者必须有不同的文件名,而不用在硬盘上为同样的数据重复备份;如果在不同的目录下,那么被链接的文件可以与原文件同名,只要对一个目录下的该文件进行修改,就可以完成对所有目录下只要对一个目录下的该文件进行修改,就可以完成对所有目录下同名链接文件的修改同名链接文件的修改。对于某文件的各个链接文件,我们可以给它们指定不同的存取权限指定不同的存取权限,以控制对信息的共享和增强安全性。 文件链接分为硬链接硬链接和软链接软链接两种形式 嵌入式系统及其应用重庆大学电气工程学院设备文件 在Linux系统中,所有设备都作为一种特别文

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

7、整数,它是个索引值,并指向内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。 嵌入式系统及其应用重庆大学电气工程学院2、系统调用、系统调用 系统调用是操作系统提供给用户程序调用系统调用是操作系统提供给用户程序调用的一组的一组“特殊特殊”接口。接口。 使用系统主要目的是使得用户可以使用操使用系统主要目的是使得用户可以使用操作系统提供的有关作系统提供的有关设备管理设备管理、输入输入/输出系输出系统统、文件系统文件系统和和进程控制进程控制、通信通信以及以及存储存储管理管理等方面的功能,而

8、不必了解系统程序等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用轻用户负担和保护系统以及提高资源利用率的作用。率的作用。嵌入式系统及其应用重庆大学电气工程学院 Linux的运行空间划分为的运行空间划分为用户空间用户空间和和内核空内核空间间,它们各自运行在不同的级别中,所以,它们各自运行在不同的级别中,所以用户进程在通常情况下不允许访问内核,用户进程在通常情况下不允许访问内核,也无法使用内核函数,它们只能在用户空也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间函数。这间操作用户数据,调用用

9、户空间函数。这样做的目的是为了对系统作必要的样做的目的是为了对系统作必要的“保护保护”措施,但是使用系统调用可以最大程度措施,但是使用系统调用可以最大程度地解决这一问题。地解决这一问题。嵌入式系统及其应用重庆大学电气工程学院 Linux系统有系统有200多个系统调用,这些系统调用按多个系统调用,这些系统调用按照功能分类大致可分为以下几个方面:照功能分类大致可分为以下几个方面:进程控制 文件系统控制 系统控制 存储管理 网络管理 socket控制 用户管理 进程间通信 嵌入式系统及其应用重庆大学电气工程学院用户编程接口(用户编程接口(API) 系统调用系统调用并不是直接与程序员进行交互的并不是直

10、接与程序员进行交互的,它仅仅是,它仅仅是个通过个通过软中断机制软中断机制向内核提向内核提交请求,以获取内核服务的接口。在实际交请求,以获取内核服务的接口。在实际使用中程序员调用的通常是使用中程序员调用的通常是用户编程接口用户编程接口API。但并不是所有的函数都对应。但并不是所有的函数都对应个个系统调用,有时,一个系统调用,有时,一个API函数会需要几个函数会需要几个系统调用来共同完成函数的功能,其至还系统调用来共同完成函数的功能,其至还有有些些API函数不需要调用相应的系统调用函数不需要调用相应的系统调用(因此它所完成的不是内核提供的服务因此它所完成的不是内核提供的服务)。嵌入式系统及其应用重

11、庆大学电气工程学院嵌入式系统及其应用重庆大学电气工程学院3、文件处理、文件处理 Linux系统的文件处理,主要是指进行打开系统的文件处理,主要是指进行打开文件、读文件、写文件及关闭文件等文件、读文件、写文件及关闭文件等I/O操操作。大多数情况下,只需用到作。大多数情况下,只需用到5个函数:个函数:open、read、write、lseek 和和close。这。这几个函数不需要经过缓冲就能立即执行,几个函数不需要经过缓冲就能立即执行,因此,被称之为不带缓存的因此,被称之为不带缓存的I/O操作,即每操作,即每一个函数都只调用内核中的一个系统调用。一个函数都只调用内核中的一个系统调用。 嵌入式系统及

12、其应用重庆大学电气工程学院6.1.2open函数和函数和close函数函数 嵌入式系统及其应用重庆大学电气工程学院1、open函数函数 open函数用于打开或创建文件。函数用于打开或创建文件。 调用调用open函数所需要的头文件如下:函数所需要的头文件如下:#include #include #include 其函数为:其函数为: int open(const char *pathname, int oflag, int perms ) ; 函数返回值:若文件打开成功则返回文件描述符,函数返回值:若文件打开成功则返回文件描述符,若出错则返回若出错则返回-1。嵌入式系统及其应用重庆大学电气工程学

13、院所需头文件#include#include#include函数原型int open(const char *pathname, flags, int perms)pathname被打开的文件名(可包括路径名)flag:文:文件打开的件打开的方式方式O_RDONLY:只读方式打开文件O_WRONLY:只写方式打开文件O_RDWR:读写方式打开文件O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三个参数为其设置权限O_EXCL:如果同时使用O_CREAT时文件存在,则返回错误消息。这一参数可测试文件是否存在O_NOCTTY:使用本参数时,如文件为终端,那么终端不可以作为调用open(

14、)系统调用的那个进程的控制终端O_TRUNC:如文件已经存在,并且以只读或只写成功打开,那么会先全部删除文件中原有数据O_APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾perms被打开文件的存取权限,为8进制表示法函数返回值成功成功:返回文件描述符失败失败:-1在open函数中,flag参数可通过组合构成,但但前前3个函数个函数不能相互组不能相互组合合 2、close函数函数 close函数用于关闭一个打开的文件,所需函数用于关闭一个打开的文件,所需要的头文件为:要的头文件为: #include 其函数为:其函数为: int close(int fd); 函数返回值

15、:若成功为函数返回值:若成功为0,若出错为,若出错为-1。 关闭文件函数关闭文件函数close的参数的参数fd为文件描述符。为文件描述符。嵌入式系统及其应用重庆大学电气工程学院open和和close函数使用实例函数使用实例 实例中的实例中的open函数带有函数带有3个个flag参数参数:O_CREAT、O_TRUNC和和O_WRONLY,这样就可以对不同的情况指定相应的处理这样就可以对不同的情况指定相应的处理方法。另外,这里对该文件的权限设置为方法。另外,这里对该文件的权限设置为0600 。嵌入式系统及其应用重庆大学电气工程学院文件操作所需头文件打开当前目录下hello.c文件文件名文件打开的

16、方式文件的权限打开文件操作成功打印显示文件描述符关闭文件文件描述符定义变量fd用于保存文件描述符执行程序打开文件后输出信息文件描述的值关闭文件后打印输出信息嵌入式系统及其应用重庆大学电气工程学院查看当前目录中的文件创建了hello.c文件文件的权限嵌入式系统及其应用重庆大学电气工程学院文件的权限查看当前目录中的文件创建了hello.c文件嵌入式系统及其应用重庆大学电气工程学院注意:注意:open函数返回的又件描述符一定是函数返回的又件描述符一定是最最小的未用文件描述符小的未用文件描述符。由于一个进程在启。由于一个进程在启动时自动打开了动时自动打开了0、1、2三个文件描述符,三个文件描述符,因此

17、,该文件运行结果中返回的因此,该文件运行结果中返回的文件描述文件描述符为符为3。可以尝试在调用。可以尝试在调用open函数之前,函数之前,加一句加一句close(0),则此后在,则此后在open函数时返函数时返回的文件描述符为回的文件描述符为0(若关闭文件描述符若关闭文件描述符1,则在执行时会由于没有标准输出文件而无则在执行时会由于没有标准输出文件而无法输出法输出)。 嵌入式系统及其应用重庆大学电气工程学院关闭标准输入文件打印文件描述符文件描述符执行程序文件打开成功后输出的信息文件描述符嵌入式系统及其应用重庆大学电气工程学院关闭标准输出文件前,输出一个信息关闭标准输出文件查看当前目录中的文件只

18、输出了关闭标准输出文件以前的输出信息嵌入式系统及其应用重庆大学电气工程学院6.1.3read函数、函数、write函数和函数和lseek函数函数嵌入式系统及其应用重庆大学电气工程学院1、read函数函数 read函数从打开的文件中读取数据。函数从打开的文件中读取数据。 调用调用read函数所需要的头文件:函数所需要的头文件: # include 其函数原型为:其函数原型为: ssize_t read(int fd, void *buf, size_t count); 函数返回值为读到数据的字节数,若返回函数返回值为读到数据的字节数,若返回值为值为0,则已经到达文件尾,若返回,则已经到达文件尾,

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

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

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

22、读写操作。 调用调用lseek函数所需要的头文件:函数所需要的头文件: #include #include 其函数原型为:其函数原型为: off_t lseek(int fd, off_t offset, int whence); 函数返回值为文件的当前位移,若返回函数返回值为文件的当前位移,若返回-1则出错。则出错。嵌入式系统及其应用重庆大学电气工程学院lseek函数语法要点函数语法要点 所需头文件所需头文件#include #include 函数原型函数原型off_t lseek(int fd, off_t offset, int whence)函数输入值函数输入值fd:文件描述符offs

23、et:偏移量,每次读写操作所需要移动的距离,单位是字节数,可正可负(向前或向后移)whence:当前位当前位置的基置的基点点SEEK_SET:当前位置为文件的开头,新位置为相对于文件头的偏移量SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量函数返回值函数返回值成功成功:文件的当前位移-1:出错嵌入式系统及其应用重庆大学电气工程学院函数使用实例函数使用实例 该示例程序首先打开上一节中创建的文件,该示例程序首先打开上一节中创建的文件,然后对此文件进行读写操作然后对此文件进行读写操作(注意要将文件注意要将文件打

24、开属性改为可读写,将文件权限也做相打开属性改为可读写,将文件权限也做相应更改应更改)。接着,写入。接着,写入“Hello! Im writing to this file!”,此时文件指针位于文件尾部。此时文件指针位于文件尾部。接着再使用接着再使用lseek函数将文件指针移到文件函数将文件指针移到文件开始处,并读出开始处,并读出10个字节并将其打印出来。个字节并将其打印出来。 嵌入式系统及其应用重庆大学电气工程学院文件读写操作函数所需头文件定义一个字符串,用以写入文件定义一个数组,有11个元素,用作读缓冲区获取字符串的长度写文件操作写入数据的存储缓冲区指针写入数据字节数将文件指针移到文件头部当

25、前位置的基准点读文件操作嵌入式系统及其应用重庆大学电气工程学院嵌入式系统及其应用重庆大学电气工程学院6.2 嵌入式嵌入式Linux串口通信技术串口通信技术 嵌入式系统及其应用重庆大学电气工程学院6.2.1 嵌入式嵌入式Linux串口通信基础串口通信基础嵌入式系统及其应用重庆大学电气工程学院1、串口通信的工作原理、串口通信的工作原理 所谓所谓“串口通信串口通信”是指外设和计算机间使是指外设和计算机间使用一根数据信号线用一根数据信号线(另外需要地线另外需要地线),数据在数据在一根数据信号线上一位一位地进行传输,一根数据信号线上一位一位地进行传输,每一位数据都占据一个固定的时间长度。每一位数据都占据

26、一个固定的时间长度。 在串口传输中,发送方为了告诉接收方,在串口传输中,发送方为了告诉接收方,新的数据字节分组到达,在每一个数据字新的数据字节分组到达,在每一个数据字节分组前面有一个起始位(通常是节分组前面有一个起始位(通常是0),为),为了让接收方知道字节已经结束,在每一个了让接收方知道字节已经结束,在每一个数据字节分组后面有一个停止位(通常是数据字节分组后面有一个停止位(通常是1)。接收方一旦检测到停止位,接收方会)。接收方一旦检测到停止位,接收方会一直等待,直到下一个开始位。一直等待,直到下一个开始位。 嵌入式系统及其应用重庆大学电气工程学院 图图6.1 串行传输数据的工作原理串行传输数

27、据的工作原理嵌入式系统及其应用重庆大学电气工程学院 嵌入式系统串行通信采用嵌入式系统串行通信采用EIA RS-232C标准,标准,为单向不平衡传输方式,信号电平标准为单向不平衡传输方式,信号电平标准12V,负逻辑,即逻辑,负逻辑,即逻辑1(MARKING)表示表示为信号电平为信号电平-12V,逻辑,逻辑0(SPACING)表示为表示为信号电平信号电平+12V,最大传送距离,最大传送距离15米,最大米,最大传送速率传送速率19.6K波特,其传送序列如图波特,其传送序列如图6.1,平时线路保持为平时线路保持为1,传送数据开始时,先发,传送数据开始时,先发送起始位送起始位(其数据值是其数据值是0),

28、然后传然后传8(或或7,6,5)个数据位个数据位(其数据值是其数据值是0,1),接着可传,接着可传1位位奇偶校验位,最后为奇偶校验位,最后为12个停止位个停止位(其数据其数据值是值是1),由此可见,传送一个,由此可见,传送一个ASCII字符字符(7位位),加上同步信号最少需,加上同步信号最少需9位数据位。位数据位。 重庆大学电气工程学院嵌入式系统及其应用2、常用信号引脚与串口通信接线、常用信号引脚与串口通信接线 图图6.2 串口的连接线串口的连接线嵌入式系统及其应用重庆大学电气工程学院6.2.2 嵌入式嵌入式Linux串口设置详解串口设置详解嵌入式系统及其应用重庆大学电气工程学院1、起始位、起

29、始位 通信线路上没有数据被传送时,处于逻辑通信线路上没有数据被传送时,处于逻辑“1”的状态。当发送设备要发送字符数据的状态。当发送设备要发送字符数据时,首先发送一个逻辑时,首先发送一个逻辑“0”信号,这个逻信号,这个逻辑低电平就是起始位。起始位通过通信线辑低电平就是起始位。起始位通过通信线路传输到接收端,接收端检测到这个低电路传输到接收端,接收端检测到这个低电平后,就开始准备接收数据位信号。起始平后,就开始准备接收数据位信号。起始位所起的作用就是使通信双方同步。位所起的作用就是使通信双方同步。 重庆大学电气工程学院嵌入式系统及其应用2、数据位、数据位 当接收端收到起始位后,开始接收数据位。当接

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

31、个数必须为偶数,相反,如果是奇校验,数据位和奇偶位的相反,如果是奇校验,数据位和奇偶位的逻辑逻辑“1”的个数为奇数。的个数为奇数。嵌入式系统及其应用重庆大学电气工程学院4、停止位、停止位 在奇偶位或数据位(当无奇偶校验时)之在奇偶位或数据位(当无奇偶校验时)之后发送停止位。停止位表示一个数据的结后发送停止位。停止位表示一个数据的结束。它可以是束。它可以是12位的位的“1”。接收端收到。接收端收到停止位后,通信线路便恢复逻辑停止位后,通信线路便恢复逻辑“1”的状的状态,直到下一个数据的起始位到来。态,直到下一个数据的起始位到来。嵌入式系统及其应用重庆大学电气工程学院5、波特率设置、波特率设置 通

32、信线路上传输的位(码元)信号都必须保通信线路上传输的位(码元)信号都必须保持一致的信号持续时间,单位时间内传送码持一致的信号持续时间,单位时间内传送码元的数目称为波特率。元的数目称为波特率。 对于大多数嵌入式设备来说,其波特率都设对于大多数嵌入式设备来说,其波特率都设置为置为115200。 在在Linux中,所有的设备文件一般都位于中,所有的设备文件一般都位于“/dev”下,其中串口一、串口二所对应的下,其中串口一、串口二所对应的设备名依次为设备名依次为“/dev/ttyS0”、“/dev/ttyS1”,可以查看在可以查看在“/dev”下的文件以确认。下的文件以确认。 嵌入式系统及其应用重庆大

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

34、定义、引脚定义嵌入式系统及其应用重庆大学电气工程学院嵌入式系统及其应用重庆大学电气工程学院嵌入式系统及其应用重庆大学电气工程学院3、字符(帧)格式、字符(帧)格式 RS232C采用起止式异步通信协议,其特点是一采用起止式异步通信协议,其特点是一个字符接着一个字符进行传输,并且传送一个字个字符接着一个字符进行传输,并且传送一个字符总是以起始位开始,以停止位结束,字符之间符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。其传输格式如图没有固定的时间间隔要求。其传输格式如图6.1所所示,每一个字符的前面都有一位起始位(低电平,示,每一个字符的前面都有一位起始位(低电平,逻辑值逻辑值“

35、0”),字符本身有),字符本身有58位数据位,接着位数据位,接着字符后面是一位校验码(也可以没有校验码),字符后面是一位校验码(也可以没有校验码),最后是停止位。停止位后面是不定长度的空闲位。最后是停止位。停止位后面是不定长度的空闲位。停止位和空闲位都规定为高电平(逻辑值停止位和空闲位都规定为高电平(逻辑值“1”),),这样就能保证起始位开始处一定有一个下跳沿,这样就能保证起始位开始处一定有一个下跳沿,便于接收方识别。便于接收方识别。嵌入式系统及其应用重庆大学电气工程学院用奇偶校验位将所传字符中为“1”的位数凑成奇数个或偶数个数据位可设为5,6,7,8位嵌入式系统及其应用重庆大学电气工程学院4

36、、握手协议、握手协议 嵌入式系统及其应用重庆大学电气工程学院5、双机互连方式、双机互连方式 (1)无硬件握手情况)无硬件握手情况嵌入式系统及其应用重庆大学电气工程学院 (2)DTR和和DSR握手情况握手情况嵌入式系统及其应用重庆大学电气工程学院 (3)RTS和和CTS握手情况握手情况重庆大学电气工程学院嵌入式系统及其应用6.2.4串口驱动程序的编写串口驱动程序的编写 一个串口驱动程序,通常包括打一个串口驱动程序,通常包括打开串口、设置串口参数、对串口开串口、设置串口参数、对串口进行读写操作等内容。进行读写操作等内容。 嵌入式系统及其应用重庆大学电气工程学院S3C2410X内部具有2个独立的个独

37、立的UART控制器控制器,每个控制器都可以工作在Interrupt(中断中断)模式模式或者DMA(直接内存访问直接内存访问)模式模式。另外,每个UART均具有16字节的FIFO(先进先出寄存器),支持的最高波特率可达到230.4Kbps。UART的操作主要可分为以下几个部分:信息发送、信息接收、产生中断、产生波特率、Loopback模式、红外模式以及自动流程模式。 嵌入式系统及其应用重庆大学电气工程学院1、串口操作需要的头文件、串口操作需要的头文件 #include /*标准输入输出定义标准输入输出定义*/ #include /*标准函数库定义标准函数库定义*/ #include /*Unix

38、 标准函数定义标准函数定义*/ #include #include #include /*文件控制定义文件控制定义*/ #include /*终端控制定义终端控制定义*/ #include /*错误号定义错误号定义*/嵌入式系统及其应用重庆大学电气工程学院2、打开串口、打开串口 通常嵌入式通常嵌入式 Linux 系统下的串口文件是位系统下的串口文件是位于于 /dev 下:下: 串口一串口一 为为 /dev/ttyS0; 串口二串口二 为为 /dev/ttyS1。打开串口是通过打开函数打开串口是通过打开函数open( ) 进行的进行的 。 int fd;/文件描述符文件描述符 fd = open

39、( “/dev/ttyS0”, O_RDWR);/以读写方式打开串口以读写方式打开串口嵌入式系统及其应用重庆大学电气工程学院3、设置串口参数、设置串口参数 最基本的串口参数设置包括波特率设置,最基本的串口参数设置包括波特率设置,校验位和停止位设置。校验位和停止位设置。 嵌入式系统及其应用重庆大学电气工程学院嵌入式系统及其应用重庆大学电气工程学院#include struct termio unsigned short c_iflag; /*输入模式标志*/ unsigned short c_oflag; /*输出模式标志*/ unsigned short c_cflag; /*控制模式标志*/

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

41、00波特率B5760057600波特率B115200115200波特率EXTA外部时钟率EXTB外部时钟率CS55个数据位CS66个数据位CS77个数据位CS88个数据位CSTOPB2个停止位(不设则是1个停止位)CREAD接收使能PARENB校验位使能PARODD使用奇校验而不使用偶校验HUPCL最后关闭时挂线(放弃DTR)CLOCAL本地连接(不改变端口所有者)LOBLK块作业控制输出CNET_CTSRTS硬件流控制使能c_cflag支持的常量名称支持的常量名称 波特率设置为相应的波特率值前加上B 字符长度 CBAUD波特率的位掩码CSIZE数据位的位掩码在这里,对于c_cflag成员不能

42、直接对其初始化,而要将其通过“与与”、“或或”操作使用其中的某些选项。 INPCK奇偶校验使能IGNPAR忽略奇偶校验错误PARMRK奇偶校验错误掩码ISTRIP除去奇偶校验位IXON启动出口硬件流控IXOFF启动入口软件流控IXANY允许字符重新启动流控IGNBRK忽略中断情况BRKINT当发生中断时发送SIGINT信号INLCR将NL映射到CRIGNCR忽略CRICRNL将CR映射到NLIUCLC将高位情况映射到低位情况IMAXBEL当输入太长时回复ECHOc_iflag支持的常量名称支持的常量名称 奇偶校验控制c_cc支持的常量名称支持的常量名称 VINTR中断控制,对应键为CTRL+C

43、VQUIT退出操作,对应键为CTRL+ZVERAST删除操作,对应键为Backspace(BS)VKILL删除行,对应键为CTRL+UVEOF位于文件结尾,对应键为CTRL+DVEOL位于行尾,对应键为Carriage return(CR)VEOL2位于第二行尾,对应键为Line feed(LF)VMIN指定了最少读取的字符数VTIME指定了读取每个字符的等待时间嵌入式系统及其应用重庆大学电气工程学院设置串口属性的基本流程设置串口属性的基本流程 保存原先串口配置保存原先串口配置首先首先,为了安全起见和以后调试程序方便,为了安全起见和以后调试程序方便,可以先保存原先串口的配置可以先保存原先串口的

44、配置,在这里可以使用函数tcgetattr (fd, oldtio)。该函数得到与fd指向对象指向对象的相关参数,并将它们保存于oldtio引用的引用的termios结构中。该函该函数还可以测试配置是否正确、该串口是否数还可以测试配置是否正确、该串口是否可用等。可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为-1。 重庆大学电气工程学院嵌入式系统及其应用使用如下所示:使用如下所示: if ( tcgetattr ( fd, &oldtio ) != 0 ) perror ( “Setup Serial 1” ); return -1;指向一个对象保存原来的配置参数重庆大学电

45、气工程学院嵌入式系统及其应用激活选项有激活选项有CLOCAL和和CREAD CLOCAL和CREAD分别用于本地连接本地连接和接受使能接受使能,因此,首先要通过位掩码位掩码的方式激话这两个选项。 newtio.c_cflag |= CLOCAL | CREAD; 嵌入式系统及其应用重庆大学电气工程学院设置波特率设置波特率设置波特率有专门的函数,用户不能直接通过位掩不能直接通过位掩码来操作码来操作。设置波特率的主要函数有cfsetispeed和cfsetospeed。这两个函数的使用很简单,如下所示: cfsetispeed ( &newtio, B115200 );cfsetospee

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

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

48、);而使能偶校验时,代码为:而使能偶校验时,代码为: newtio.c_cflag |= PARENB;newtio.c_cflag &= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);newtio.c_cflag &= PARENB; 无校验,代码为无校验,代码为: 嵌入式系统及其应用重庆大学电气工程学院设置停止位设置停止位设置停止位设置停止位是通过激活激活c_cflag中的CSTOPB而实现的。若停止位为停止位为1,则清除清除CSTOPB,若停止位为停止位为2,则激激活活CSTOPB。下面是停止位是1时的代码: newtio.c_cfl

49、ag &= CSTOPB; 嵌入式系统及其应用重庆大学电气工程学院设置最少字符和等待时间设置最少字符和等待时间在对接收字符接收字符和等待时间等待时间没有特别要求的情况下,可以将其设置为0,如下所示: newtio.c_ccVTIME = 0;newtio.c_ccVMIN = 0;嵌入式系统及其应用重庆大学电气工程学院处理要写入的引用对象处理要写入的引用对象由于串口在重新设置之后,在此之前要写入的引用对象要要写入的引用对象要重新处理重新处理,这时就可调用函数tcflush(fd, queue_selector)来处理要写入引用的对象。对于尚未传输的数据,或者收到尚未传输的数据,或者收到

50、的但是尚未读取的数据的但是尚未读取的数据,其处理方法取决于queue_selector的值。 这里,queue_selector可能的取值有以下几种。TCIFLUSH:刷新收到的数据但是不读;TCOFLUSH:刷新写入的数据但是不传送;TCIOFLUSH:同时刷新收到的数据但是不读,刷新写入的数据但是不传送。 tcflush(fd, TCIFLUSH); 嵌入式系统及其应用重庆大学电气工程学院激活配置激活配置在完成全部串口配置之后,要撤活刚才的配置并使配要撤活刚才的配置并使配置生效置生效。这里用到的函数是tcsetattr,它的函数原型是: tcsetattr(fd, OPTION, &

51、;newtio) 嵌入式系统及其应用重庆大学电气工程学院TCSANOW:改变的配置立即生效立即生效。TCSADRAIN:改变的配置在所有写入所有写入fd的输出都结束后生效的输出都结束后生效。TCSAFLUSH:改变的配置在所有写入所有写入fd引用对象的输出都被结束引用对象的输出都被结束 后生效后生效,所有已接受但未读入的输入都在改变发生前 丢弃。这里的newtio就是termios类型的变量,OPTION可能的取值有以下三种:该函数若调用成功成功则返回0,若失败失败则返回-1。if(tcsetattr(fd,TCSANOW, &newtio) != 0) perror(“com set

52、 error”); return -1;嵌入式系统及其应用重庆大学电气工程学院程序示例程序示例下面给出了串口配置的完整的函数串口配置的完整的函数。为了函数的通用性,将常用的选项都在函数中列出,这样可以方便调试使用。 嵌入式系统及其应用重庆大学电气工程学院int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop) struct termios newtio, oldtio/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/ if ( tcgetattr ( fd, &oldtio ) !=

53、0 ) perror ( “Setup Serial 1” ); return -1; bzero(&newtio, sizeof(newtio);/*步骤一,设置字符大小*/ newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= CSIZE/*设置数据位*/ switch(nBits) case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; /*设置奇偶校验位*/switch(nEvent) case O: /奇校验 newtio.

54、c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case 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 ( &a

55、mp;newtio, B2400 ); cfsetospeed ( &newtio, B2400 ); break; case 4800: cfsetispeed ( &newtio, B4800 ); cfsetospeed ( &newtio, B4800 ); break; case 9600: cfsetispeed ( &newtio, B9600 ); cfsetospeed ( &newtio, B9600 ); break; case 115200: cfsetispeed ( &newtio, B115200 ); cfseto

56、speed ( &newtio, B115200 ); break; case 460800: cfsetispeed ( &newtio, B460800 ); cfsetospeed ( &newtio, B460800 ); break; default: cfsetispeed ( &newtio, B9600 ); cfsetospeed ( &newtio, B9600 ); break;/*设置停止位*/ if(nStop = = 1) newtio.c_cflag &= CSTOPB; else if(nStop = = 2) n

57、ewtio.c_cflag |= CSTOPB;/*设置等待时间和最小接收字符*/ newtio.c_ccVTIME = 0; newtio.c_ccVMIN = 0;/*处理未接收字符*/ tcflush(fd, TCIFLUSH);/*激活新配置*/ if(tcsetattr(fd,TCSANOW, &newtio) != 0) perror(“com set error”); return -1; printf(“set done!n”); return 0;串口使用详解串口使用详解 在配置完串口的相关属性配置完串口的相关属性后,就可以对串口进行打开、就可以对串口进行打开、读写操

58、作了读写操作了。它所使用的函数和普通文件读写的函数一样,都是open、write和read。它们相区别的只是串口是只是串口是一个终端设备一个终端设备,因此在函数具体参数的选择时会有一些区别。另外,这里会用到一些附加的函数,用于测试终端设备的连接情况等。下面将对其进行具体讲解。 嵌入式系统及其应用重庆大学电气工程学院打开串口打开串口在Linux 下串口文件位于/dev 下,一般在老版本的内核中串口一串口一为/dev/ttyS0 ,串口二串口二为 /dev/ttyS1, 在我们的实验箱中串口设备位于/dev/tts/下,因为实验箱中没有ttyS0这个设备,所以我们要建立一个连接建立一个连接,如下听

59、示: /mnt/yaffs cd /dev/dev ln sf /dev/tts/0 ttyS0嵌入式系统及其应用重庆大学电气工程学院打开串口和打开普通文件一样,使用的函数都是open函数。 int fd;fd = open( /dev/ttyS0, O_RDWR | O_NOCTTY | O_NDELAY); if (-1 = = fd) /* 不能打开串口一*/ perror( 提示错误!);嵌入式系统及其应用重庆大学电气工程学院读写串口读写串口读写串口操作和读写普通文件一样读写串口操作和读写普通文件一样,使用read、write函数即可。 嵌入式系统及其应用重庆大学电气工程学院写串口(发

60、送数据)写串口(发送数据)char buffer1024;int Length1024;int nByte;nByte = write(fd, buffer ,Length)嵌入式系统及其应用重庆大学电气工程学院 读串口(接收数据)读串口(接收数据)使用文件操作read 函数函数读取数据, read 函数返回的字符数是实际串口收到的字符数。char buff1024;int Len1024;int readByte = read(fd, buff, Len);嵌入式系统及其应用重庆大学电气工程学院关闭串口关闭串口关闭串口关闭串口就是关闭文件关闭文件。 close(fd);嵌入式系统及其应用重庆大学电气工程学院#include /*PPSIX 终端控制定义*/#include /*标准输入输出定义*/#include /*linux 标准函数定义*/#include /*文件控制定义*/#include #include /*线程库定义*/#define BAUDRATE B115200#defin

温馨提示

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

最新文档

评论

0/150

提交评论