




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux驱动程序设计主要内容设备驱动的基本原理设备驱动的编写方法2.6内核设备模型框架设备驱动中的中断处理方法串口读写程序实例ChavezWang@G2嵌入式系统研究室设备驱动的基本原理-1嵌入式系统研究室3ChavezWang@GUSERAPPVFSDEVICEopfuncDEV_REGISTERHARDWARE用户空间内核空间设备驱动设备文件与设备文件系统Linux中,字符设备和块设备都是通过文件节点进行访问。每个设备对应一个文件名,操作时对应各自的驱动程序。设备文件与设备文件系统Linux系统靠主次设备号来联系驱动程序和设备文件节点,依靠主设备号标志不同的驱动程序注册Linux设备号的方法为避免不同的驱动程序具有相同的设备号,需要提供一种分配设备号的机制每个驱动程序分配一个主设备号:不可行,Linux最多支持255个主设备根据/proc/devices中的对应关系,用脚本动态的创建设备文件:太麻烦,程序员不愿意设备文件系统自动管理注册Linux设备号的方法系统启动时,会把设备驱动程序挂载在/dev/目录下,Linux设备文件的创建和删除、目录层次都都由各个设备驱动程序管理/dev/下面每个文件都动态对应了一个系统上存在的设备驱动程序。新添加(或者删除)一个设备,比如u盘,系统就会自动在/dev目录中创建(或者删除)对应的设备节点。注册Linux设备号的方法在设备文件系统中,由于分的比较细致,一些驱动程序的对应目标跟以前比一样,如:Linux2.4之前:/dev/fb0/dev/ttyS0Linux2.6之后:/dev/fb/0/dev/tts/0可以用符号链接进行更改,以便与之前的相匹配:ln-s/dev/fb/0/dev/fb0ls-s/dev/tts/0/dev/ttyS0设备驱动的基本原理-2设备分类字符设备:存取时没有缓存、只能顺序读/写的设备。可通过设备文件节点被访问与普通文件的区别:普通文件的访问可以前后移动访问指针,而大多数字符设备不支持该操作。典型的字符设备鼠标键盘串口嵌入式系统研究室4ChavezWang@G设备驱动的基本原理-3设备分类块设备:一般块设备都有缓存支持,并且支持随机存取创建的块设备硬盘软盘ramdisk嵌入式系统研究室5ChavezWang@G设备驱动的基本原理-4设备分类网络设备:从BSDUNIX网络组件移植而来。网络设备没有对应地映射到文件系统的设备节点。在Linux中,网络设备的访问采用Socket机制实现嵌入式系统研究室6ChavezWang@G设备驱动的基本原理-5设备号:Linux采用主设备号和次设备号来标志一个具体设备。主设备号用来标志设备类型次设备号用来区分不同的具体设备系统创建一个设备驱动程序时,设备驱动需要使用一个主设备号向内核注册此驱动。创建一个设备节点的方法:mknod设备名设备类型主设备号次设备号例:mknodttyS0c644嵌入式系统研究室7ChavezWang@G设备驱动的基本原理-6-内核模块内核模块的概念:内核模块是一些可以让操作系统内核在需要时载入和执行的代码,不需要时可以从操作系统中卸载内核模块是Linux内核运行时动态扩展的一种技术,可以在Linux内核运行期间向内核动态添加代码,扩展内核的功能嵌入式系统研究室8ChavezWang@G设备驱动的基本原理-7-内核模块内核模块与应用程序加载的不同:内核模块的加载只是向内核预先注册自己以便服务于将来的某个请求,只是加载了某项功能,而不需要马上执行应用程序加载后就开始执行内核模块不能使用外部函数库,只能使用内核导出的函数应用程序可以使用外部函数库内核模块只能运行在内核空间,并且不生成新的进程应用程序运行在用户空间,一般一个应用程序生成一个新的进程嵌入式系统研究室9ChavezWang@G设备驱动的基本原理-8-内核模块内核模块的框架#include<linux/init.h>#include<linux/kernel.h>#include<linux/module.h>MODULE_LICENSE("DualBSD/GPL");staticinthello_init(void){ printk(KERN_ALERT"Hello,world\n"); return0;}staticvoidhello_exit(void){ printk(KERN_ALERT"Goodbye,world\n");}module_init(hello_init);module_exit(hello_exit);嵌入式系统研究室10ChavezWang@G设备驱动的基本原理-9-内核模块2.6系列内核模块的编译与加载内核源码树的每个子目录都有一个kconfig文件,为makefile提供配置数据库,分别描述了所属目录源文件相关的内核配置菜单项内核配置时,从kconfig中读出配置菜单,配置后生成.config文件编译内核时,makefile读入对应的.config文件生成内核映像加入新驱动到内核源码树时,需要修改相应目录的kconfig,将新驱动加入内核的配置菜单,同时需要修改makefile文件嵌入式系统研究室11ChavezWang@G设备驱动的基本原理-10-内核模块嵌入式系统研究室12ChavezWang@G.configMakefileKconfigKconfigKconfigmakefilemakefilearch/arm/makefileScrip/makefilemenuconfig输出Kconfig配置文件Konfig文件树是内核的配置数据库每个Kconfig文件描述一系列内核配置菜单项,每个菜单项提供一个关键字标识语法:Config<symbol><configoptions>例:configHELLO_MODULE bool“hellotestmodule”嵌入式系统研究室13ChavezWang@G设备驱动的基本原理-11-内核模块设备驱动的基本原理-12-内核模块Kconfig配置文件类型定义有:bool、tristate、string、hex、integer等依赖性定义:如果菜单项的出现依赖于另一个定义时,就用关键字dependson或者requires标识
config HELLO_MODULE bool“hellotestmodel”dependsonARCH_PXA帮助定义:关键字help或者–help--嵌入式系统研究室14ChavezWang@G设备驱动的基本原理-13-内核模块内核的makefile:内核源码根目录下的顶层makefile可以分为五部分该makefile本身,负责linux内核的二进制映像文件vmlinux和内核模块的编译内核配置文件.config,记录内核的当前配置并在编译时提供给makefile成为其一部分特定体系结构相关目录下的makefile,提供与体系结构相关的信息Scripts下的makefile.*,包含一些内核模块编译共用的定义和规则内核源码树各子目录中的与模块编译相关的kbuildmakefile。编译时,集成上层makefile传下来的宏定义和其他编译规则将源代码编入内核或编译成内核模块嵌入式系统研究室15ChavezWang@GKbuildmakefile内容:最简单的只有一行。以hello.c为例:obj-y+=hello.o:编译进内核的二进制映像中obj-m+=hello.o:编译成内核的可加载模块obj-$(CONFIG_HELLO_MODULE)+=hello.o根据变量的不同,既可以编译进内核,也可以编译为模块嵌入式系统研究室16ChavezWang@G设备驱动的基本原理-13-内核模块Kbuildmakefile内容:若具有多个文件,如mymodule由file1.cfile2.c构成,则Makefile定义为obj-m:=mymodule.oMymodule-objs:=file1.ofile2.o在内核源码树之外的模块,则用下面的方式编译:
make-C<PATH_TO_KERNEL>M=$PWDmodules嵌入式系统研究室17ChavezWang@G设备驱动的基本原理-13-内核模块驱动程序的编译设备驱动程序的结构-1设备驱动程序从总体上看可以分为两部分驱动与内核的接口层:实现在内核的注册加载和卸载清除工作。若采用了中断处理,还要包括中断处理函数的注册与注销。硬件设备接口层:主要描述驱动程序与设备的交互。包括:硬件探测硬件初始化设备读写访问设备控制操作嵌入式系统研究室18ChavezWang@G虚拟文件系统与硬件驱动的接口1Linux系统中用户对设备的操作采用文件接口实现。虚拟文件系统将这种对文件的访问操作转化为对设备的具体操作。虚拟文件系统为设备驱动提供了一个标准化的文件操作实现接口。该接口定义在:Include/linux/fs.h中的file_operations定义嵌入式系统研究室19ChavezWang@G/**NOTE:*read,write,poll,fsync,readv,writevcanbecalled*withoutthebigkernellockheldinallfilesystems.*/structfile_operations{ structmodule*owner; loff_t(*llseek)(structfile*,loff_t,int); ssize_t(*read)(structfile*,char__user*,size_t,loff_t*); ssize_t(*aio_read)(structkiocb*,char__user*,size_t,loff_t); ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*); ssize_t(*aio_write)(structkiocb*,constchar__user*,size_t,loff_t); int(*readdir)(structfile*,void*,filldir_t); unsignedint(*poll)(structfile*,structpoll_table_struct*); int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);
嵌入式系统研究室20ChavezWang@Gint(*mmap)(structfile*,structvm_area_struct*); int(*open)(structinode*,structfile*); int(*flush)(structfile*); int(*release)(structinode*,structfile*); int(*fsync)(structfile*,structdentry*,intdatasync); int(*aio_fsync)(structkiocb*,intdatasync); int(*fasync)(int,structfile*,int); int(*lock)(structfile*,int,structfile_lock*); ssize_t(*readv)(structfile*,conststructiovec*,unsignedlong,loff_t*); ssize_t(*writev)(structfile*,conststructiovec*,unsignedlong,loff_t*); ssize_t(*sendfile)(structfile*,loff_t*,size_t,read_actor_t,void*); ssize_t(*sendpage)(structfile*,structpage*,int,size_t,loff_t*,int); unsignedlong(*get_unmapped_area)(structfile*,unsignedlong,unsignedlong,unsignedlong,unsignedlong); int(*check_flags)(int); int(*dir_notify)(structfile*filp,unsignedlongarg); int(*flock)(structfile*,int,structfile_lock*);};嵌入式系统研究室21ChavezWang@G注意:结构体中的函数,并不是每个都需要实现的。不需要实现的函数,可以直接初始化为空。在嵌入式系统中,一般仅仅实现其中的几个接口函数:read,write,ioctl,open,release等,就可以完成应用系统需要的功能嵌入式系统研究室22ChavezWang@G虚拟文件系统与硬件驱动的接口2Open方法:方法open用于打开设备,open操作是对设备的第一个操作,如果open方法为空,则设备始终打开成功递增使用计数检查特定设备错误如果设备是首次打开,则对其进行初始化识别次设备号嵌入式系统研究室23ChavezWang@G虚拟文件系统与硬件驱动的接口3虚拟文件系统与硬件驱动的接口4release方法:方法release在关闭文件时调用,其工作与open方法相反释放由open分配的filp->private_data中的左右内容使用计数减一在最后一次关闭操作时关闭设备嵌入式系统研究室24ChavezWang@G虚拟文件系统与硬件驱动的接口5read方法:方法read从设备中读取数据,函数返回非负值表示成功读出的字节数返回值等于传递给read系统调用的count参数,表明请求的数据传输成功返回值大于0,但小于传递给read系统调用的count参数,表明部分数据传输成功,根据设备的不同,导致这个问题的原因也不同,一般采取再次读取的方法返回值=0,表示到达文件的末尾返回值为负数,表示出现错误,并且指明何种错误在阻塞型io中,read调用会出现阻塞。嵌入式系统研究室25ChavezWang@G虚拟文件系统与硬件驱动的接口6write方法:方法write向设备中写入数据,函数返回非负值表示成功写入的字节数返回值等于传递给write系统调用的count参数,表明请求的数据传输成功返回值大于0,但小于传递给write系统调用的count参数,表明部分数据传输成功,根据设备的不同,导致这个问题的原因也不同,一般采取再次写入的方法返回值=0,表示没有写入任何数据。此时一般会重复调用write返回值为负数,表示出现错误,并且指明是何种错误。在阻塞性io中,write调用会出现阻塞。嵌入式系统研究室26ChavezWang@G虚拟文件系统与硬件驱动的接口7ioctl方法:方法ioctl为设备调用ioctl提供了一种执行设备特定命令的方法,主要是读写之外的其他控制。如配置设备、进入或者退出某种操作模式等。实验板上的SPI设备通道的选择操作,即通过这种方式嵌入式系统研究室27ChavezWang@G虚拟文件系统与硬件驱动的接口8*owner指向拥有该结构的模块,内核使用指针维护模块的使用计数llseek用来修改文件当前位置,并将新位置作为结果返回。loff_t是在linux中定义的长偏移量。出错时返回负值。嵌入式系统研究室28ChavezWang@G方法poll是系统调用select和poll的后端实现,用这两个系统调用来查询设备是否可以读写或者是否处于某种状态。如果poll为空,则驱动设备会被认为既可读,又可写,返回值是一个状态掩码。方法mmap将设备内存映射到进程地址空间。嵌入式系统研究室29ChavezWang@G虚拟文件系统与硬件驱动的接口9简单的字符驱动-1大多数字符设备比较简单,通常直接使用file_operations接口。本课程将以一个虚拟的字符设备test_char为例,说明字符驱动的结构嵌入式系统研究室30ChavezWang@G简单的字符驱动-2虚拟文件系统与设备驱动程序的接口本设备之设计到读写和设备的打开关闭操作。因此可以定义以下file_opertions结构体变量。structfile_operationstestchar_fops{ .read=test_read, .write=test_write, .open=test_open, .release=test_release};注意:定义结构体变量之前需要先实现用到的函数嵌入式系统研究室31ChavezWang@G简单的字符驱动-3staticchartest_val=‘a’;//用全局变量保存虚拟设备读写的数据staticssize_ttest_read(structfile*filp,char__user*buf,size_tcount,loff_t*l){ copy_to_user(buf,&val,sizeof(val)); returnsizeof(val);}//copy_to_user(void__user*to,constvoid*from,unsignedlongn);Staticssize_ttest_write(structfile*file,constchar__user*buf,size_tcount,loff_t*l){ copy_from_user(&val,buf,sizeof(val); returnsizeof(val);}//copy_from_user(void*to,void__user*from,unsignedlongn)Staticinttest_open(structinode*inode,structfile*filp){ try_module_get(THIS_MODULE);//模块计数加一
return0;}Staticinttest_release(structinode*inode,structfile*filp){ module_put(THIS_MODULE);//模块计数减一
return0;}嵌入式系统研究室32ChavezWang@G简单的字符驱动-4驱动模块的加载和卸载操作
#defineTEST_MAJOR251 #defineTEST_NAME “TEST_CHAR” int__initinit_routine(void){ register_chrdev(TEST_MAJOR,TEST_NAME,&testchar_fops); return0;}//intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations//*fops)Voidcleanup_routine(void){ unregister_chrdev(TEST_MAJOR,TEST_NAME);} module_init(init_routine); module_exit(cleanup_routine);嵌入式系统研究室33ChavezWang@GLinux2.6内核设备模型-1Linux2.2版之前没有统一的驱动形式,2.4通过使用一组通用接口将PCI、PCMIA等整合到一个单一的设备结构中,2.6内核则更进一步,试图在整个系统的范围内对硬件设备进行抽象,建立一个统一的全新设备模型新模型包括四个重要数据结构:structkobjectstructksetstructktypestructsubsystem嵌入式系统研究室34ChavezWang@GLinux2.6内核设备模型-2structkobject结构:最底层的基础数据结构structkobject{ char *k_name;//动态分配空间的设备名称
char name[KOBJ_NAME_LEN];//长度受限的设备名称
atomic_t refcount;//引用计数
struct list_head entry;//挂接到所有集合中去的入口
structkobject*parent;// 商机对象的指针
structkset *kset;//所属对象集合的指针
structkobj_type ktype;// 所属对象类型指针
structdentry*dentry;//在sysfs系统中的文件节点路径指针}嵌入式系统研究室35ChavezWang@GLinux2.6内核设备模型-3structkset结构:用于描述同一类kobject集合structkset{ structsubsystem *subsys;//所在的subsystem的指针
structkobj_type *ktype;//集合中的对象类型
structlist_head list;//集合中的对象链表
structkobject kobj;//集合自身相关信息的内核对象
structkset_hotplug_ops *hotplug_ops;//该集合的热插拔函数}嵌入式系统研究室36ChavezWang@GLinux2.6内核设备模型-4structkobj_ktype结构:structkobj_type{ void(*release)(structkobject*);//本类对象的释放函数
structsysfs_ops *sysfs_ops;//本类对象在sysfs中的操作函数
structattribute**default_attrs;//本类对象在sysfs中的属性}嵌入式系统研究室37ChavezWang@GLinux2.6内核设备模型-5structsubsystem内核对象子系统:是最上层的数据结构,用于描述同属一类设备的子系统structsubsystem{ structksetkset;//该子系统的内核对象集合
structrw-semaphorerwsem;//互斥访问信号量}嵌入式系统研究室38ChavezWang@GLinux2.6内核设备模型-6系统初始化时,drivers/base/init.c中的driver-init()函数将几个顶层子系统的subsystem数据结构注册到内核初始化子系统数据结构在sysfs文件系统下建立各个子系统的目录树五个子系统:设备子系统devices_subbus总线子系统bus_subbus设备基类子系统class_subbus固件子系统(fireware_subbus)虚拟系统总线子系统(system_subbus)嵌入式系统研究室39ChavezWang@GLinux2.6内核设备模型-7五个子系统构成了管理框架初始化时,初始化程序调用内核对象注册函数将设备数据结构中的成员kobject结构注册到相应的子系统中最终用户可以通过sysfs文件系统看到所有设备的信息嵌入式系统研究室40ChavezWang@GLinux内核的中断处理-1中断机制是实现外部I/O异步操作的重要方法Linux内核对外部设备的中断处理在设备驱动程序里实现嵌入式系统研究室41ChavezWang@GLinux内核的中断处理-2中断处理程序的注册注册函数Intrequest_irq(unsignedintirq,irqreturn_t(*handler)(int,void*,structpt_regs*), unsignedlongirq_flags,constchar*devname,void*dev_id);该函数成功则返回0;irq为要注册的中断号Handler指向中断处理程序的函数指针irq-flags为中断标志,含义如下:SA_INTERRUPT:不受中断屏蔽的影响,任何情况下都可以响应。一般只有时钟中断具有此标志。SA_SAMPLE_RAMDOM:产生中断的间隔时间放入系统随机数的内核熵池SA_SHIRQ:表明为共享中断嵌入式系统研究室42ChavezWang@GLinux内核的中断处理-3中断处理程序的注册dev_name:与中断相关的设备名字。dev_id:主要用于共享中断中,释放共享中断时,根据dev_id的标志信息来删除指定的那个中断处理程序处理的中断。若dev_id设为null,则为独占式的中断嵌入式系统研究室43ChavezWang@GLinux内核的中断处理-4中断处理程序的释放Voidfree_irq(unsignedintirq,void*dev_id)若释放的中断是共享的,则dev_id对应的中断处理程序与中断的绑定关系被删除若删除了最后一个中断处理程序的绑定关系,则此中断被禁用若要释放的中断是非共享的,则删除中断处理程序的同时也将禁用中断嵌入式系统研究室44ChavezWang@GLinux内核的中断处理-5中断处理程序的编写中断处理程序与其他内核函数的不同之处:中断处理程序发送或者接受数据都必须在内核空间,不能在内核与用户空间之间发送或者接受数据中断不能做任何可能发生休眠的操作,也不能调用schedule函数进行进程调度。staticirqreturn_tirq_handler(intirq,void*dev_id,structpt_regs*regs)当中断程序被调用并正确处理时,返回IRQ_HANDLED,否则返回IRQ_NONE嵌入式系统研究室45ChavezWang@GLinux2.6内核的工作推后执行机制-1问题引入:通常中断处理程序需要尽量做到短小和快速处理,以免中断阻塞时间过长,影响实时性和中断响应速度但是,有些设备产生中断后需要处理较多的与中断相关的工作,所以速度会比较慢处理方法将中断处理分为两个部分:中断处理程序部分:只做必要的有严格时限的工作,如中断应答和复位硬件等,一般需要屏蔽中断的情况下处理其他需要时间的不是很紧急的工作推后处理。嵌入式系统研究室46ChavezWang@G内核工作推后执行的机制主要有:软中断tasklet工作队列嵌入式系统研究室47ChavezWang@GLinux2.6内核的工作推后执行机制-2软中断:通常用于执行频率很高的强实时性的场合。作为一种底层机制,很少由内核程序员直接使用。enum{ HI_SOFTIRQ=0,//优先级高的tasklet软中断
TIMER_SOFTIRQ,//定时器软中断
NET_TX_SOFTIRQ,//网络数据包发送软中断
NET_RX_SOFTIRQ,//网络数据包接收软中断
SCSI_SOFTIRQ,//SCSI软中断的软中断
TASKLET_SOFTIRQ.//tastlet软中断的软中断}嵌入式系统研究室48ChavezWang@GLinux2.6内核的工作推后执行机制-3tasklet:小任务,指一小段可以执行的嗲吗,通常以函数的形式出现,对于io驱动程序,是实现工作推后执行的首选方法。tasklet基于软中断机制实现,实际上只是一种软中断的应用和包装structtasklet_struct{ structtasklet_struct*next;//指向链表中的下一个结构体
unsignedlongstate;//tasklet的状态,初始化时为0,被调用时为1 atomic_tcount;//引用计数器,若不为0,则不能执行;若为0则可以执行
void(*func)(unsignedlong);//tasklet处理函数
unsignedlongdata;//给tasklet处理函数的参数}嵌入式系统研究室49ChavezWang@GLinux2.6内核的工作推后执行机制-4tasklet的使用tasklet声明:DECLARE_TASKLET(name,func,data)//初始值为0,激活状态DECLARE_TASKLET_DISABLED(name,func,data)//初始值为1,停用状态name:tasklet_struct变量的名字func:是tasklet的执行函数data:是tasklet执行函数的参数嵌入式系统研究室50ChavezWang@GLinux2.6内核的工作推后执行机制-5tasklet的使用tasklet执行函数定义Voidfunc(unsignedlongdata)注意:必须与structtasklet_struct结构中的func定义一致Func()要在tasklet声明之前定义不能使用信号量或者其他可能引起阻塞的函数,因为tasklet不能休眠嵌入式系统研究室51ChavezWang@GLinux2.6内核的工作推后执行机制-6tasklet的使用tasklet的调度tasklet_schedule(&name):将一个tasklet状态置为准备执行状态,系统由合适的机会时,就会尽快执行Tasklet_disable():将tasklet的count计数增1,从而停用该taskletTasklet_enable():激活tasklet。Tasklet_kill():从等待执行的tasklet队列中删除一个tasklet嵌入式系统研究室52ChavezWang@GLinux2.6内核的工作推后执行机制-6工作队列每个工作队列有一个专门的线程,称之为工作队列线程工作队列中推后执行的工作由此线程完成,所有的工作在线程的上下文中被执行。因此,允许重新调度甚至睡眠嵌入式系统研究室53ChavezWang@GLinux2.6内核的工作推后执行机制-7工作队列:structwork_struct数据结构Structwork_struct{ unsignedlongpending;//工作是否等待处理
structlist_headentry;//工作队列中的工作链表
void(*func)(void*);//处理函数
void*data;//处理函数的参数
void*wq_data;//内部使用
structtimer_listtimer;//定时器}嵌入式系统研究室54ChavezWang@GLinux2.6内核的工作推后执行机制-8工作队列的使用创建工作队列:Structworkquene_struct*create_workquene(constchar*name)//创建一个新工作队列,返回新工作队列的指针例如:structworksquene_struct*my_workqe; my_workqe=create_workquene(“my_workqe”);创建推后执行的工作编译时创建工作队列:#defineDECLARE_WORK(name,func,data)\structwork_structn=__WORK_INITALIZER(name,func,data)运行时动态创建:Structwork_structmy_work;INIT_WORK(my_work,my_work_func,data);嵌入式系统研究室55ChavezWang@GLinux2.6内核的工作推后执行机制-9工作队列的使用定义工作的任务处理函数Voidfunc(void*data)将工作加入工作队列中intquene_work(structworkquene_struct*squene,structwork_struct*work);//即时加入工作队列intquene_delayed_work(structworkquene_struct*quene,structwork_struct*work,unsignedlongdelay);//延迟一段时间加入工作队列Intcancel_delayed_work(structwork_struct*work)//取消延期加入工作队列的工作;如果已经加入则不受影响嵌入式系统研究室56ChavezWang@GLinux2.6内核的工作推后执行机制-10工作队列的使用刷新工作队列Voidfastcallflush_workquene(structworkquene_struct*wq);//在卸载前,保证操作都已经执行完毕。如果没有执行完毕,会进入休眠状态销毁工作队列Voiddestroy_workquene(structworkquene_struct*wq);//销毁使用完毕的工作队列注意:不是所有的驱动都需要自己的工作队列。嵌入式系统研究室57ChavezWang@GLinux2.6内核的工作推后执行机制-6串行通信的基本概念串行通信与串口定义串行方式传输数据传输速度用bps或者波特率描述常用的串口为RS-232-C串口通信的基本参数每秒位数—波特率数据位奇偶校验位停止位数据流控制在Linux下进行串口通信
打开串口类似于打开文件,必须使用O_NOCTTY方式:如果打开的是一个终端设备,程序不会成为对应这个端口的控制终端#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>intfd;if((fd=open(“dev/ttyS0”,O_RDWR|O_NOCTTY))==1)perrro(“…”)设置串口通信参数波特率设置获得端口波特率通过cfgetispeed函数和cfgetospeed函数实现设置端口波特率通过cfsetispeed函数和cfsetospeed函数实现数据位数据位指的是每次输入字节中实际数据所占的比特数,通过修改termios结构体中的c_cflag成员来实现。其中CS5CS6CS7CS8分别表示数据位为5、6、7、8位。设置时,必须先使用CSIZE做位屏蔽。奇偶校验位奇偶校验可以选择偶校验、奇校验、空格等方式,也可以不使用校验。如果要设置偶检验的话,首先将ternios结构体中c_cflag设置PARENB标志,并清除PARODD标志。奇校验同时设置ternios结构体中c_cflag设置PARENB标志和PARODD标志。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 初中英语口语教学策略优化与实践研究论文
- 花桥镇干部管理制度
- 茶叶分公司管理制度
- 防聚集工作管理制度
- 财务会计岗位综合实训(一)
- 论坛营销 - 网络营销系列之三
- 财务会计业务题
- 设备主管工作职责
- 山东省滨州市博兴县2024-2025学年九年级下学期4月期中考试数学试题(含部分答案)
- 红白色创意笔刷西藏旅游介绍
- 2024年04月湖州银行杭州分行社会招考综合柜员笔试历年参考题库附带答案详解
- DB32-T 4878-2024 居住区供配电设施建设标准
- 《心肺运动试验介绍》课件
- 2024年05月恒丰银行上海分行零售金融部社会招聘(4人)笔试历年参考题库附带答案详解
- 经济师考试知识产权高级经济实务新考纲题库详解(2025年)
- 医院培训课件:《失血性休克的急救护理》
- 【MOOC】模式识别-青岛大学 中国大学慕课MOOC答案
- 透析患者贫血的护理
- 【MOOC】电子线路设计、测试与实验(二)-华中科技大学 中国大学慕课MOOC答案
- 《LNG基本知识培训》课件
- 2024年宁夏中考历史真题卷及答案解析
评论
0/150
提交评论