《最新微处理器系统结构与嵌入式系统设计PPT课件》由会员分享,可在线阅读,更多相关《最新微处理器系统结构与嵌入式系统设计PPT课件(38页珍藏版)》请在金锄头文库上搜索。
1、微处理器系统结构与嵌入式系统微处理器系统结构与嵌入式系统设计设计*2/37第十一章第十一章 基于基于ARM的的软件系件系统设计1、嵌入式软件系统结构及工作流程嵌入式软件系统结构及工作流程2、嵌入式软件系统的引导和加载、嵌入式软件系统的引导和加载S3C2440S3C2440启动过程启动过程、BootLoader BootLoader 基本概念基本概念、 U-bootU-boot的分析与移植的分析与移植3、嵌入式、嵌入式Linux操作系统操作系统嵌入式操作系统嵌入式操作系统、嵌入式嵌入式LinuxLinux内核内核4、Linux下驱动程序设计示例下驱动程序设计示例打开串口、设置串口打开串口、设置串
2、口、读写串口读写串口、关闭串口关闭串口*3/37航空航天学院航空航天学院清水河清水河清水河清水河 研究院大楼研究院大楼研究院大楼研究院大楼108108陈陈 敏敏email: email: tel tel: 028-61830626 028-61830626*5/37*6/37*7/37*8/37*9/37S3C2440S3C2440启动方式启动方式 三星公司的三星公司的S3C2440支持支持Nor Flash和和Nand Flash启启动, 可以通可以通过硬件跳硬件跳线(引脚引脚OM1:0)设置启置启动方式。具体含方式。具体含义如下如下:1OM1:0=00时,处理器从理器从NAND Flas
3、h启启动2OM1:0=01时,处理器从理器从16位位宽度的度的Nor Flash启启动3OM1:0=10时,处理器从理器从32位位宽度的度的Nor Flash启启动4OM1:0=11时,处理器从理器从Test Mode启启动*10/37S3C2440NandFlash在系在系统上上电后后,Nand Flash控制器控制器会自会自动的把的把Nand Flash上的前上的前4K U-BOOT数据搬移到内部数据搬移到内部SRAM的的地址最低端地址最低端(此此SRAM被称被称为Steppingstone);CPU从内部从内部RAM的的0x00000000位位置开始启置开始启动并在并在uboot启启动代
4、代码的的前前4K里完成里完成S3C2440的核心配置,的核心配置,然后把然后把U-BOOT剩余部分搬到剩余部分搬到RAM中运行;中运行; S3C2440 Nand FlashS3C2440 Nand Flash启动过程启动过程*11/37引导程序引导程序BootLoaderBootLoaderl是嵌入式系是嵌入式系统在加在加电启启动后后执行的第一段代行的第一段代码,功,功能能类似似pc机的机的BIOS和和OS Loader,通常需要,通常需要固化固化在目在目标板中;板中;l主要主要负责CPU、存、存储器及相关硬件的器及相关硬件的初始化初始化,以及,以及将将装装载操作系操作系统映像到内存中,然后
5、跳映像到内存中,然后跳转到到规定的定的地址地址启启动操作系操作系统运行。运行。 Bootloader是是严重依重依赖硬件而硬件而实现的,每一种不的,每一种不同体系同体系结构的构的处理器都有不同的理器都有不同的Bootloader,甚至,甚至同一种同一种处理器的外理器的外围硬件配置不同,其硬件配置不同,其Bootloader也有差也有差别。因此开。因此开发特定的特定的Bootloader是构建嵌入是构建嵌入式式linux系系统之前的一之前的一项必要的基必要的基础工作。工作。*12/37BootloaderBootloader的开发的开发Stage1(汇编实现)1.基本硬件基本硬件设备初始化:初始
6、化:CPU时钟频率,寄存器,存率,寄存器,存储器数据器数据宽度、度、访问周期、刷新周期,中断系周期、刷新周期,中断系统,I/O端口端口等;等;2.为第二第二阶段准段准备RAM空空间,设置堆置堆栈;3.复制第二复制第二阶段代段代码到到RAM中,并跳中,并跳转到第二到第二阶段入口点段入口点Stage2(C实现)1.初始化本初始化本阶段要使用的硬件段要使用的硬件设备,实现对板板级驱动的支持;的支持;2.检测系系统内存映射;内存映射;3.将内核将内核镜像和根文件系像和根文件系统镜像从像从flash读到到RAM中;中;4.为内核内核设置启置启动参数;参数;5.将将PC指指针指向内核的入口指向内核的入口处
7、,调用内核。挂用内核。挂载文件系文件系统;*13/37Linux Linux 环境下环境下BootLoaderBootLoader种类种类BootloaderMonitor描描 述述x86ARMPowerPCLILO否否Linux磁盘引导程序磁盘引导程序是是否否否否GRUB否否GNU的的LILO替代程序替代程序是是否否否否Loadlin否否从从DOS引导引导Linux是是否否否否ROLO否否从从ROM引导引导Linux而不需要而不需要BIOS是是否否否否Etherboot否否通过以太网卡启动通过以太网卡启动Linux系统系统的固件的固件是是否否否否LinuxBIOS否否完全替代完全替代BUIS
8、的的Linux引导引导程序程序是是否否否否BLOB否否LART等硬件平台引导程序等硬件平台引导程序否否是是否否U-boot是是通用引导程序通用引导程序是是是是是是RedBoot是是基于基于eCos的引导程序的引导程序是是是是是是*14/37U-bootU-boot的分析与移植的分析与移植U-boot全称全称 Universal Boot Loader,支,支持持ARM体系等多种体系等多种处理器,包含常理器,包含常见的外的外设的的驱动,是一个开源的、功能,是一个开源的、功能强大的板极支持包;大的板极支持包;由德国由德国DENX软件工程中心的件工程中心的Wolfgang Denk维护。U-boot
9、启启动时处于正常的于正常的启启动加加载模式,模式,但是它会延但是它会延时指定指定时间(单位秒)等待位秒)等待终端用端用户按下任意按下任意键而切而切换到到下下载模式模式,如果在指定,如果在指定时间内用内用户没有按没有按键,则继续启启动操作系操作系统。*15/37U-bootU-boot主要包括以下目录主要包括以下目录lboard:该目目录存放了存放了U-Boot支持的一些已有开支持的一些已有开发板的信息。每一个开板的信息。每一个开发板都以一个子目板都以一个子目录出出现在当前目在当前目录中,如中,如SMDK2410子目子目录中存放与中存放与2410开开发板相关的配置文件,但由于自行板相关的配置文件
10、,但由于自行设计的目的目标板即使与已有开板即使与已有开发板使用相同板使用相同处理器,但其他硬件配置不一定相同,所以需要参考理器,但其他硬件配置不一定相同,所以需要参考该目目录下的内容来下的内容来进行修改,例如根据使用的行修改,例如根据使用的Flash存存储器的器的宽度和容量,可以度和容量,可以修改修改flash.c中中对应的参数。的参数。lcommon:该目目录存放的是存放的是U-Boot命令行界面下支持的各条命令的命令行界面下支持的各条命令的实现源源码。每一条命令都。每一条命令都对应一个文件,例如一个文件,例如bootm命令命令对应就是就是cmd_bootm.c。通常主要关心与内核引。通常主
11、要关心与内核引导有关的有关的cmd_boot.c和和cmd_bootm.c等代等代码。lcpu:该目目录存放了存放了U-Boot支持的支持的CPU类型。每一款型。每一款U-Boot下支持的下支持的CPU在在该目目录下下对应一个子目一个子目录,比如,比如S3C2440A采用的是采用的是ARM920T内内核,核,则子目子目录arm920t下即是下即是对该处理器核的支持源理器核的支持源码。CPU相关的文相关的文件主要是初始化一个件主要是初始化一个执行行环境,包括中断的初始化。其中有一个重要文境,包括中断的初始化。其中有一个重要文件件start.s,该文件是一个文件是一个汇编源文件,它是整个源文件,它
12、是整个U-Boot执行的第一段代行的第一段代码,它的功能是将整个,它的功能是将整个U-Boot目目标代代码重定位,也就是将重定位,也就是将U-Boot转移移至内存中去运行。至内存中去运行。*16/37U-bootU-boot主要包括以下目录主要包括以下目录ldrivers:U-Boot支持的各种支持的各种设备驱动程序都放在程序都放在该目目录,比如各种网卡、,比如各种网卡、支持支持CFI的的Flash、串口和、串口和USB等。等。lfs: 该目目录存放存放U-Boot支持的文件系支持的文件系统,例如,例如fat、fdos、jffs2、cramfs、ext2和和reiserfs等。等。linclu
13、de:U-Boot使用的使用的头文件,文件,还有有对各种硬件平台支持的各种硬件平台支持的汇编文件,文件,系系统的配置文件和的配置文件和对文件系文件系统支持的文件。支持的文件。该目目录下下configs目目录有与开有与开发板相关的配置板相关的配置头文件。文件。该目目录下的下的asm目目录有与有与CPU体系体系结构相关的构相关的头文件,文件,ARM对应的是的是asm-arm。llib_xxx: 与体系与体系结构相关的构相关的库文件。与文件。与ARM相关的相关的库放在放在lib_arm中。中。lnet:与网与网络协议栈相关的代相关的代码,BOOTP协议、TFTP协议、RARP协议和和NFS文件系文件
14、系统的的实现。ltools:生成生成U-Boot的工具,如:的工具,如:mkimage,crc等等。等等。ldoc:文档目文档目录。U-Boot有非常完善的文档,推荐参考有非常完善的文档,推荐参考阅读。*17/37U-bootU-boot的运行过程分析的运行过程分析U-Boot的的阶段一代段一代码通常放在通常放在start.s文件中,用文件中,用汇编语言写成,其主要言写成,其主要功能是功能是设置置处理器状理器状态、初始化中断和内存、初始化中断和内存时序、序、对整个整个U-Boot目目标代代码进行重新定位。行重新定位。阶段一段一刚开始的代开始的代码是是处理器的异常理器的异常处理向量表:理向量表:
15、.globl_start;系;系统复位的位置,由复位的位置,由U-Boot.ld决定决定_start: b reset;0x00000000,各个异常向量,各个异常向量对应的跳的跳转代代码 ldr pc, _undefined_instruction ;0x00000004,未定,未定义指令异常指令异常 ldrpc, _software_interrupt ;0x00000008,软件中断异常件中断异常 ldr pc, _prefetch_abort ;0x0000000c,预取中止异常取中止异常 ldrpc, _data_abort ;0x00000010,数据中止异常,数据中止异常 ldr
16、pc, _not_used ;0x00000014,未使用,未使用 ldrpc, _irq ;0x00000018,中断异常,中断异常 ldrpc, _fiq ;0x0000001c,快速中断异常,快速中断异常当当发生各生各类异常异常时,CPU将将执行行interrupts.c中中对应定定义的中断的中断处理函数。理函数。*18/37U-bootU-boot的运行过程分析的运行过程分析reset:/* set the cpu to SVC32 mode */mrsr0, cpsrbicr0, r0, #0x1forrr0, r0, #0xd3msrcpsr, r0 从以上代从以上代码可以看出,其
17、功能主要是修改程序状可以看出,其功能主要是修改程序状态寄寄存器存器CPSR的相关的相关值,修改后,修改后CPSR的低八位的低八位变为二二进制制值11x10011,依其,依其值可知可知CPU进入入SVC管理模式,且中断管理模式,且中断和快速中断均被关和快速中断均被关闭。 后后续代代码功能分功能分别是关是关闭看看门狗、禁止中断、配置狗、禁止中断、配置处理器内部理器内部时钟、配置内存区控制寄存器等,然后是代、配置内存区控制寄存器等,然后是代码搬搬移指令代移指令代码。*19/37U-bootU-boot的运行过程分析的运行过程分析接着通接着通过下列下列语句跳句跳转到到C代代码执行,行,阶段一的使命也就
18、段一的使命也就完成了。完成了。ldrpc, _start_armboot_start_armboot: .word start_armboot start_armboot()在在board.c中定中定义,是,是Bootloader中的中的C语言开言开始的函数,也是整个启始的函数,也是整个启动代代码中中C语言的主函数,同言的主函数,同时还是整个是整个UBoot(armboot)的主函数。它)的主函数。它类似于似于Linux内核的内核的start_kernel(),是一种系是一种系统初始化的接口函数,完成初始化工作。初始化的接口函数,完成初始化工作。 该函数主要完成如下操作:函数主要完成如下操作:
19、调用一系列初始化函数完成用一系列初始化函数完成CPU的基的基本本设置、开置、开发板的初始化、中断向量的初始化、板的初始化、中断向量的初始化、环境境变量的初始化、量的初始化、串口初始化等;配置可用的串口初始化等;配置可用的Flash区;内存初始化;区;内存初始化;I2C、LCD、video、音、音频等外等外围设备初始化;网初始化;网络设备初始化等等,最后初始化等等,最后进入入U-Boot命命令行。令行。*20/37嵌入式操作系统嵌入式操作系统*21/37l嵌入式嵌入式实时操作系操作系统RTlinux及其他嵌入式及其他嵌入式实时LinuxuC/OS IIeCOSVxworks (wind rive
20、r systems公司)公司)QNX (QNX software systems公司)公司)pSOSOS/9VRTXThreadXl嵌入式非嵌入式非实时操作系操作系统 一些嵌入一些嵌入inux系系统Windows CE、Embedded windows xp( Microsoft公司)公司)Palm OS (Palm公司)公司)EPOC (Symbian公司公司)*22/37LinuxLinux嵌入式操作系统嵌入式操作系统Linux是一个是一个类Unix(Unix-like)的、)的、免免费的、的、源代源代码开放开放的、符合的、符合POSIX(Portable Operating System
21、 Interface Standard)标准准规范的操作系范的操作系统;严格来格来说,Linux指由指由Linux Torvalds维护的(及通的(及通过主要主要镜像网站像网站发布的)布的)内核,内核,而整个而整个Linux系系统的其它的其它大部分都建立在大部分都建立在GNU软件之上;件之上;嵌入式嵌入式Linux内核内核为特殊的硬件配置、或特殊的硬件配置、或为了支持特了支持特别的的应用而用而经过特特别的裁剪的修改的裁剪的修改过的的Linux内核;内核;通常具有不同于工作站与服通常具有不同于工作站与服务器的内核配置;器的内核配置;嵌入式嵌入式Linux系系统基于基于Linux内核的嵌入式系内核
22、的嵌入式系统;嵌入式嵌入式Linux发行套件行套件开开发嵌入式嵌入式Linux系系统的平台;的平台;各种各种为了在嵌入式系了在嵌入式系统中使用而剪裁中使用而剪裁过的的应用用软件;件;*23/37LinuxLinux内核的发展历史内核的发展历史l1991年年11月,芬月,芬兰赫赫尔辛基大学的学生辛基大学的学生 Linus Torvalds写了个小写了个小程序,取名程序,取名为Linux,放在互,放在互联网上。他表达了一个愿望,希望借网上。他表达了一个愿望,希望借此搞出一个操作系此搞出一个操作系统的的“内核内核”来,来,这完全是一个偶然事件;完全是一个偶然事件;l1993,在一批高水平黑客的参与下
23、,在一批高水平黑客的参与下,诞生了生了Linux 1.0 版版 ;l1994年,年,Linux 的第一个商的第一个商业发行版行版 Slackware 问世;世;l1996年,美国国家年,美国国家标准技准技术局的局的计算机系算机系统实验室确室确认 Linux 版版本本 1.2.13(由(由 Open Linux 公司打包)符合公司打包)符合 POSIX 标准;准;l2001年,年,Linux2.4版内核版内核发布布 ;l2003年,年,Linux2.6版内核版内核发布;布;lLinux内核版本号由内核版本号由3位数字位数字组成成r.x.y第1位数字r为主版本号 第2位数字x为说明版本类型的次版本
24、号,如果x为偶数,则表示为产品化版本,为奇数时表示为实验版本 第3位数字y为修改号,表示错误修补的次数 *24/37几种流行的几种流行的Linux OSLinux OS发行版本发行版本*25/37嵌入式嵌入式LinuxLinux系统结构图系统结构图 嵌入式嵌入式Linux具有分具有分层的体系的体系结构,一般可分构,一般可分为3小小层及内核及内核空空间和用和用户空空间两大两大块,每一,每一层模模块都屏蔽了其以下各都屏蔽了其以下各层的具体的具体细节,只,只对上上层提供功能接口或提供功能接口或图形界面。上形界面。上层模模块不需要知道不需要知道其以下各其以下各层模模块的的实现方式,只需要利用下方式,只
25、需要利用下层提供的接口完成相提供的接口完成相应功能即可。功能即可。这样的的层次模型大大增加了嵌入式次模型大大增加了嵌入式Linux的安全性、的安全性、稳定性、裁减或增添模定性、裁减或增添模块的便利性。的便利性。*26/37LinuxLinux内核的各子系统之间的关系内核的各子系统之间的关系 嵌入式嵌入式Linux内核一般可以分内核一般可以分为4个部分:个部分:进程程调度管理、内度管理、内存管理、文件系存管理、文件系统和和设备驱动程序,它程序,它们之之间的关系如的关系如上上图所示。所示。进程程调度度处于中心位置,其他所有子系于中心位置,其他所有子系统都依都依赖于它。在嵌入式于它。在嵌入式系系统中
26、,嵌入式中,嵌入式Linux的的实时性能改造与性能改造与进程程调度有很大的关系,度有很大的关系,调度策略的算法直接关系到系度策略的算法直接关系到系统的的实时性能。性能。*27/37嵌入式嵌入式LinuxLinux中的文件系统结构中的文件系统结构 嵌入式嵌入式Linux的文件系的文件系统建立在建立在块设备上,不采用上,不采用驱动器号或器号或驱动器名称来器名称来标识,而是采用了,而是采用了树形形结构,每个独立文件系构,每个独立文件系统为一个子一个子树,组成成树形的形的层次化的次化的结构。当引入新的文件系构。当引入新的文件系统时,嵌入式嵌入式Linux通通过挂挂载方式将其方式将其连接到某个目接到某个
27、目录,从而使不同的文,从而使不同的文件系件系统组合成一个整体成合成一个整体成为可能。可能。*28/37嵌入式嵌入式LinuxLinux内核移植内核移植l如果一个系如果一个系统是可以在不同的硬件平台上运行,那么是可以在不同的硬件平台上运行,那么这个个系系统就是可移植的。就是可移植的。Linux内核移植指根据自己的硬件平内核移植指根据自己的硬件平台台对内核源代内核源代码进行行修改修改,同,同时对内核内核进行行裁剪裁剪,编译出出适合自己硬件平台的内核适合自己硬件平台的内核镜像文件。像文件。Linux内核源代内核源代码包括多个目包括多个目录:(1)arch:包括硬件特定内核代:包括硬件特定内核代码,如
28、,如arm、mips等;等;(2)drivers:包含硬件:包含硬件驱动代代码;(3)include:通用:通用头文件及文件及针对不同平台的特定不同平台的特定头文件;文件;(4)init:内核初始化代:内核初始化代码;(5)ipc:进程程间通信代通信代码;(6)kernel:内核核心代:内核核心代码;(7)mm:内存管理代:内存管理代码;(8)net:与网:与网络协议栈相关的代相关的代码;(9)fs:文件系:文件系统相关代相关代码,如,如nfs、vfat等;等;(10)lib:库文件,与平台无关的文件,与平台无关的strlen、strcpy等等*29/37LinuxLinux下驱动程序设计示例
29、下驱动程序设计示例lLinux操作系操作系统对串口有着很好的支持,其中的串串口有着很好的支持,其中的串口口驱动程序程序对用用户屏蔽了底屏蔽了底层硬件的相关信息,硬件的相关信息,而且而且为用用户提供了一系列的提供了一系列的标准准调用函数,极大用函数,极大的方便了串口通信的操作。用的方便了串口通信的操作。用户编写串口写串口应用程用程序的序的时候不需要考候不需要考虑硬件相关的硬件相关的问题,只需要根,只需要根据据Linux操作系操作系统提供的提供的调用函数来用函数来实现自己需要自己需要的功能的功能。l在在Linux操作系操作系统下,串口是被当做文件来下,串口是被当做文件来对待的,待的,因此因此对它它
30、进行数据收行数据收发等效于等效于对文件文件进行行读写操写操作。作。对串口的操作一般分串口的操作一般分为四个步四个步骤:打开串口打开串口、设置串口置串口、读写串口写串口和和关关闭串口串口。*30/37(1)(1)打开串口打开串口l在在ARM平台中平台中Linux操作系操作系统下的串口下的串口设备文件文件为/dev/ttySAC0。示例程序如下:示例程序如下:int fd;fd = open( /dev/ttySAC0, O_RDWR);/*以以读写方式打开串口写方式打开串口*/if (fd = -1) ; /*如果打开串口如果打开串口错误则输出提示信息出提示信息*/perror(Cant Ope
31、n Serial Port);*31/37(2)(2)设置串口设置串口l与无操作系与无操作系统的情况下的情况下对串口串口进行初始化行初始化设置置类似,在似,在Linux下最基本的串口下最基本的串口设置工作主要包括波置工作主要包括波特率、校特率、校验位和停止位的位和停止位的设置,其置,其设置方式主要置方式主要是是对struct termios结构体各成构体各成员值进行行设置。置。l在不同在不同应用中通常需要用中通常需要设置的波特率及数据格式置的波特率及数据格式等参数都不一等参数都不一样,可以将,可以将结构体成构体成员赋值的功能的功能编写成函数,通写成函数,通过对该函数入口参数的修改,即函数入口参
32、数的修改,即可方便的可方便的实现不同的不同的设置。置。*32/37波特率设置函数波特率设置函数void set_speed(int fd, int speed)int i;int status;struct termiosOpt;tcgetattr(fd, &Opt);/*得到机器原端口的默得到机器原端口的默认设置置*/for ( i= 0; i sizeof(speed_arr) / sizeof(int); i+) if (speed = name_arri) tcflush(fd, TCIOFLUSH); /*清除清除输入入/输出数据出数据*/ cfsetispeed(&Opt, spe
33、ed_arri); /设置置输入波特率入波特率cfsetospeed(&Opt, speed_arri); /设置置输出波特率出波特率status = tcsetattr(fd, TCSANOW, &Opt); /将将设置写入串口置写入串口if (status != 0) perror(tcsetattr fd1);return;tcflush(fd,TCIOFLUSH);*33/37数据格式数据格式设置函数设置函数int set_Parity(int fd,int databits,int stopbits,int parity)struct termios options;if ( tcg
34、etattr( fd,&options) != 0) /*得到机器原端口的默得到机器原端口的默认设置置*/perror(SetupSerial 1);return(FALSE);options.c_cflag &= CSIZE; switch (databits)/设置数据位个数置数据位个数 case 7: options.c_cflag |= CS7; /设置数据位置数据位为7位位 break; case 8: options.c_cflag |= CS8; /设置数据位置数据位为8位位 break; default: fprintf(stderr,Unsupported data size
35、n); return (FALSE); *34/37数据格式数据格式设置函数设置函数switch (stopbits)/设置停止位个数置停止位个数 case 1: options.c_cflag &= CSTOPB;/设置停止位置停止位为1位位 break; case 2: options.c_cflag |= CSTOPB; /设置停止位置停止位为2位位 break; default: fprintf(stderr,Unsupported stop bitsn); return (FALSE); *35/37switch (parity) /设置校置校验位属性位属性 case n: case
36、 N: options.c_cflag &= PARENB; /关关闭奇偶校奇偶校验 options.c_iflag &= INPCK; /关关闭输入奇偶校入奇偶校验检测 break; case o: case O: options.c_cflag |= (PARODD | PARENB); /设置置为奇效奇效验 options.c_iflag |= INPCK; /打开打开输入奇偶校入奇偶校验检测 break; case e: case E: options.c_cflag |= PARENB;/打开奇偶校打开奇偶校验 options.c_cflag &= PARODD;/设置置为偶效偶效验
37、 options.c_iflag |= INPCK;/打开打开输入奇偶校入奇偶校验检测 break; default: fprintf(stderr,Unsupported parityn);/不能不能识别的校的校验类型型 return (FALSE); *36/37(3)(3)读写串口实现数据传输读写串口实现数据传输从串口从串口发送数据:送数据:使用文件操作使用文件操作write函数函数实现数据数据发送,示例程序如下:送,示例程序如下:charbuffer1024;int Length;int writeByte;writeByte = write(fd, buffer ,Length);功
38、能:将功能:将发送送缓冲区冲区buffer中中Length大小的数据从串口大小的数据从串口发出。出。从串口接收数据:从串口接收数据:使用文件操作使用文件操作read函数函数实现数据接收,示例程序如下:数据接收,示例程序如下:charbuffer1024;int Length;int readByte;readByte= read(fd,buffer,Length);功能:功能:读取串口接收到的取串口接收到的Length大小的数据,并放到接收大小的数据,并放到接收缓冲区冲区buffer中。中。*37/37(4)(4)关闭关闭串口串口关关闭串口就是关串口就是关闭设备文件,使用文件操作文件,使用文件操作close函数函数实现。close(fd););结束语结束语谢谢大家聆听!谢谢大家聆听!38