串口通信中用到的函数Word格式.docx
- 文档编号:18838564
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:15
- 大小:24.61KB
串口通信中用到的函数Word格式.docx
《串口通信中用到的函数Word格式.docx》由会员分享,可在线阅读,更多相关《串口通信中用到的函数Word格式.docx(15页珍藏版)》请在冰豆网上搜索。
打开和创建文件。
intopen(constchar*pathname,intoflag,.../*mode_tmode*/);
返回值:
成功则返回文件描述符,否则返回-1
对于open函数来说,第三个参数(...)仅当创建新文件时(即使用了O_CREAT时)才使用,用于指定文件的访问权限位(accesspermissionbits)。
pathname是待打开/创建文件的路径名(如C:
/cpp/a.cpp);
oflag用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑或构成。
O_RDONLY只读模式
O_WRONLY只写模式
O_RDWR读写模式
打开/创建文件时,至少得使用上述三个常量中的一个。
以下常量是选用的:
O_APPEND每次写操作都写入文件的末尾
O_CREAT如果指定文件不存在,则创建这个文件
O_EXCL如果要创建的文件已存在,则返回-1,并且修改errno的值
O_TRUNC如果文件存在,并且以只写/读写方式打开,则清空文件全部容(即将其长度截短为0)
O_NOCTTY如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O
文件描述符:
核(kernel)利用文件描述符(filedescriptor)来访问文件。
文件描述符是非负整数。
打开现存文件或新建文件时,核会返回一个文件描述符。
读写文件也需要使用文件描述符来指定待读写的文件。
习惯上,标准输入(standardinput)的文件描述符是0,
标准输出(standardoutput)是1,
标准错误(standarderror)是2。
尽管这种习惯并非Unix核的特性,但是因为一些shell和很多应用程序都使用这种习惯,因此,如果核不遵循这种习惯的话,很多应用程序将不能使用。
POSIX定义了STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO来代替0、1、2。
这三个符号常量的定义位于头文件unistd.h。
ioctl
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。
所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。
它的调用个数
intioctl(intfd,indcmd,…);
其中fd就是用户程序打开设备时使用open函数返回的文件标示符,
cmd就是用户程序对设备的控制命令,
至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的。
ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支
持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道
cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、数据尺寸等生成,这个整数通过系统调用传递到核中的驱动程序,再由驱动程序使用解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过switch{case}结构进行相应的操作。
FIONREAD
:
通过由ioctl
的第三个参数指向的整数返回当前在本套接口接收缓冲区中的字节数。
本特性同样适用于文件,管道和终端
Write
ssize_twrite(intfiledes,constvoid*buf,size_tnbytes);
写入文档的字节数(成功);
-1(出错)
write函数向filedes中写入nbytes字节数据,数据来源为buf。
返回值一般总是等于nbytes,否则就是出错了。
常见的出错原因是磁盘空间满了或超过了文档大小限制。
Read
#include<
unistd.h>
ssize_tread(intfiledes,void*buf,size_tnbytes);
读取到的字节数;
0(读到EOF);
read函数从filedes指定的已打开文档中读取nbytes字节到buf中。
以下几种情况会导致读取到的字节数小于nbytes:
A.读取普通文档时,读到文档末尾还不够nbytes字节。
例如:
假如文档只有30字节,而我们想读取100
字节,那么实际读到的只有30字节,read函数返回30。
此时再使用read函数作用于这个文档会导致read返回0。
B.从终端设备(terminaldevice)读取时,一般情况下每次只能读取一行。
C.从网络读取时,网络缓存可能导致读取的字节数小于nbytes字节。
D.读取pipe或FIFO时,pipe或FIFO里的字节数可能小于nbytes。
E.从面向记录(record-oriented)的设备读取时,某些面向记录的设备(如磁带)每次最多只能返回一个记录。
F.在读取了部分数据时被信号中断。
读操作始于cfo。
在成功返回之前,cfo增加,增量为实际读取到的字节数。
/*打开串口*/
intopen_com1()/*打开串口2函数*/
{
intfd;
fd=open("
/tyCo/0"
O_CREAT|O_RDWR,0);
/*打开串口并返回串口设备文件描述符*/
if(fd==ERROR)/*如果不能打开串口1则打印出错信息*/
printf("
Youcan’topenportcom1!
\n"
);
elseprintf("
openCom1successfully!
}
/*配置串口*/
intconfig_com1(void)/*串口1配置函数*/
ioctl(fd,FIOSETOPTIONS,OPT_LINE);
/*设置串口工作模式为行模式:
LINE_MODE*/
ioctl(fd,FIOBAUDRATE,9600);
/*设置串口波特率为9600bps*/
ioctl(fd,FIOFLUSH,0);
/*清空输入输出缓冲*/
ioctl(fd,SIO_HW_OPTS_SET,CS8|STOPB|PARENB|PARODD);
/*设置8位数据位,2位停止位,带校验位,奇校验*/
ioctl(fd,FIOSETOPTIONS,OPT_ECHO|OPT_CRMOD|OPT_TANDEM|OPT_7_BIT);
setoptionssuccessfully\n"
}
/*串口发送数据*/
intsend_com1(void)/*向串口1发送数据函数*/
char*send_buf="
Hello,Datahadaccept!
"
;
/*待发送数据*/
write(fd,send_buf,strlen(send_buf));
/*任务阻塞等待写串口准备完毕*/
/*关闭串口*/
externSTATUSclose(fd)
{
close(fd);
FD_ZERO(fd_set*fdset);
将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配存空间后,通常并不作清空处理,所以结果是不可知的。
FD_SET(fd_set*fdset);
用于在文件描述符集合中增加一个新的文件描述符。
FD_CLR(fd_set*fdset);
用于在文件描述符集合中删除一个文件描述符。
FD_ISSET(intfd,fd_set*fdset);
用于测试指定的文件描述符是否在该集合中。
select函数:
系统提供select函数来实现多路复用输入/输出模型。
原型:
#includesys/time.h>
#includeunistd.h>
intselect(intmaxfd,fd_set*rdset,fd_set*wrset,
fd_set*exset,structtimeval*timeout);
intFD_ISSET(intfd,fd_set*fdset)
宏说明:
在调用select()函数后,用FD_ISSET来检测fdset中文件fd有无发生变化
返回整型,当fd是fdset的子集的时候,返回真,否者返回假。
参数maxfd是需要监视的最大的文件描述符值+1;
rdset需要检测的可读文件描述符的集合,
wrset可写文件描述符的集合
exset及异常文件描述符的集合。
structtimeval结构用于描述一段时间长度,如果在这个时间,需要监视的描述符没有事件发生则函数返回,返回值为0。
select模型
intselect(intn,fd_set*readfds,fd_set*writefds,
fd_set*exceptfds,structtimeval*timeout);
其中参数n表示监控的所有fd中最大值+1。
和select模型紧密结合的四个宏,
FD_CLR(intfd,fd_set*set);
FD_ISSET(intfd,fd_set*set);
FD_SET(intfd,fd_set*set);
FD_ZERO(fd_set*set);
理解select模型的关键在于理解fd_set,为说明方便,取fd_set长度为1字节,fd_set中的每一bit可以对应一个文件描述符fd。
则1字节长的fd_set最大可以对应8个fd。
(1)执行fd_setset;
FD_ZERO(&
set);
则set用位表示是0000,0000。
(2)若fd=5,执行FD_SET(fd,&
后set变为0001,0000(第5位置为1)
(3)若再加入fd=2,fd=1,则set变为0001,0011
(4)执行select(6,&
set,0,0,0)阻塞等待
(5)若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。
注意:
没有事件发生的fd=5被清空。
基于上面的讨论,可以轻松得出select模型的特点:
(1)可监控的文件描述符个数取决与sizeof(fd_set)的值。
我这边服务器上sizeof(fd_set)=512,每bit表示一个文件描述符,则我服务器上支持的最大文件描述符是512*8=4096。
据说可调,另有说虽然可调,但调整上限受于编译核时的变量值
(2)将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select监控集中的fd,一是用于再select返回后,array作为源数据和fd_set进行FD_ISSET判断。
二是select返回后会把以前加入的但并无事件发生的fd清空,则每次开始select前都要重新从array取得fd逐一加入(FD_ZERO最先),扫描array的同时取得fd最大值maxfd,用于select的第一个参数。
(3)可见select模型必须在select前循环array(加fd,取maxfd),select返回后循环array
timeout为结构timeval,用来设置select()的等待时间,其结构定义如下
structtimeval
time_ttv_sec;
time_ttv_usec;
};
如果参数timeout设为NULL则表示select()没有timeout。
taskDelay(n)使调用该函数的任务延时n个tick(核时钟周期)。
该任务在指定的时间主动放弃CPU,
除了taskDelay(0)专用于任务调度(将CPU交给同一优先级的其他任务)外,任务延时也常用于等待某一外部事件,作为一种定时/延时机制。
在没有中断触发时,taskDelay能很方便地实现,且不影响系统整体性能。
例如写数据至EEPROM,EEPROM需要一个部擦除时间(最大擦除时间为lOms)。
以下所提及的一个tick都假设为16.67ms(1/60s)。
可以简单地调用taskDelay
(2)来保证数据擦写完成。
taskDelay有接近一1个tick的误差存在,taskDelay(n)实际上是延时(n-1)tick~ntick的时间。
延时精度为l/n
主题:
ioctl函数详细说明
ioctl
函数
本函数影响由fd
参数引用的一个打开的文件。
#include<
int
ioctl(intfd,intrequest,.../*void*arg*/);
返回0
成功
-1
出错
第三个参数总是一个指针,但指针的类型依赖于request
参数。
我们可以把和网络相关的请求划分为6
类:
套接口操作
文件操作
接口操作
ARP
高速缓存操作
路由表操作
流系统
下表列出了网络相关ioctl
请求的request
参数以及arg
地址必须指向的数据类型:
类别
Request
说明
数据类型
套
接
口
SIOCATMARK
SIOCSPGRP
SIOCGPGRP
是否位于带外标记
设置套接口的进程ID
或进程组ID
获取套接口的进程ID
int
文
件
FIONBIN
FIOASYNC
FIONREAD
FIOSETOWN
FIOGETOWN
设置/
清除非阻塞I/O
标志
清除信号驱动异步I/O
获取接收缓存区中的字节数
设置文件的进程ID
获取文件的进程ID
SIOCGIFCONF
SIOCSIFADDR
SIOCGIFADDR
SIOCSIFFLAGS
SIOCGIFFLAGS
SIOCSIFDSTADDR
SIOCGIFDSTADDR
SIOCGIFBRDADDR
SIOCSIFBRDADDR
SIOCGIFNETMASK
SIOCSIFNETMASK
SIOCGIFMETRIC
SIOCSIFMETRIC
SIOCGIFMTU
SIOCxxx
获取所有接口的清单
设置接口地址
获取接口地址
设置接口标志
获取接口标志
设置点到点地址
获取点到点地址
获取广播地址
设置广播地址
获取子网掩码
设置子网掩码
获取接口的测度
设置接口的测度
获取接口MTU
(还有很多取决于系统的实现)
structifconf
structifreq
ARP
SIOCSARP
SIOCGARP
SIOCDARP
创建/
修改ARP
表项
获取ARP
删除ARP
structarpreq
路
由
SIOCADDRT
SIOCDELRT
增加路径
删除路径
structrtentry
流
I_xxx
套接口操作:
明确用于套接口操作的ioctl
请求有三个,
它们都要求ioctl
的第三个参数是指向某个整数的一个指针。
SIOCATMARK:
如果本套接口的的度指针当前位于带外标记,那就通过由第三个参数指向的整数返回一个非0
值;
否则返回一个0
值。
POSIX
以函数sockatmark
替换本请求。
SIOCGPGRP
通过第三个参数指向的整数返回本套接口的进程ID
或进程组ID
,该ID
指定针对本套接口的SIGIO
或SIGURG
信号的接收进程。
本请求和fcntl
的F_GETOWN
命令等效,POSIX
标准化的是fcntl
函数。
SIOCSPGRP
把本套接口的进程ID
或者进程组ID
设置成第三个参数指向的整数,该ID
信号的接收进程,本请求和fcntl
的F_SETOWN
操作。
文件操作:
以下5
个请求都要求ioctl
的第三个参数指向一个整数。
FIONBIO
根据ioctl
的第三个参数指向一个0
或非0
值分别清除或设置本套接口的非阻塞标志。
本请求和O_NONBLOCK
文件状态标志等效,而该标志通过fcntl
的F_SETFL
命令清除或设置。
FIOASYNC
根据iocl
值或非0
值分别清除或设置针对本套接口的信号驱动异步I/O
标志,它决定是否收取针对本套接口的异步I/O
信号(SIGIO
)。
本请求和O_ASYNC
文件状态标志等效,而该标志可以通过fcntl
本特性同样适用于文件,管道和终端。
FIOSETOWN
对于套接口和SIOCSPGRP
等效。
FIOGETOWN
对于套接口和SIOCGPGRP
接口配置:
得到系统中所有接口由SIOCGIFCONF
请求完成,该请求使用ifconf
结构,ifconf
又使用ifreq
结构,如下所示:
Structifconf{
intifc_len;
//
缓冲区的大小
union{
caddr_tifcu_buf;
//inputfromuser->
kernel
structifreq*ifcu_req;
//returnofstructuresreturned
}ifc_ifcu;
#define
ifc_buf
ifc_ifcu.ifcu_buf
//bufferaddress
ifc_req
ifc_ifcu.ifcu_req
//arrayofstructuresreturned
IFNAMSIZ
16
structifreq{
charifr_name[IFNAMSIZ];
//interfacename,e.g.,“le0”
union{
structsockaddrifru_addr;
structsockaddrifru_dstaddr;
structsockaddrifru_broadaddr;
shortifru_flags;
intifru_metric;
caddr_tifru_data;
}ifr_ifru;
#defi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 串口 通信 中用 函数