串口通信中用到的函数.docx

上传人:b****5 文档编号:5851525 上传时间:2023-01-01 格式:DOCX 页数:15 大小:24.61KB
下载 相关 举报
串口通信中用到的函数.docx_第1页
第1页 / 共15页
串口通信中用到的函数.docx_第2页
第2页 / 共15页
串口通信中用到的函数.docx_第3页
第3页 / 共15页
串口通信中用到的函数.docx_第4页
第4页 / 共15页
串口通信中用到的函数.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

串口通信中用到的函数.docx

《串口通信中用到的函数.docx》由会员分享,可在线阅读,更多相关《串口通信中用到的函数.docx(15页珍藏版)》请在冰豆网上搜索。

串口通信中用到的函数.docx

串口通信中用到的函数

LinuxC语言中open函数

intopen(constchar*pathname,intflags);

intopen(constchar*pathname,intflags,mode_tmode);

函数说明

参数pathname指向欲打开的文件路径字符串。

下列是参数flags所能使用的旗标:

O_RDONLY以只读方式打开文件

O_WRONLY以只写方式打开文件

O_RDWR以可读写方式打开文件。

上述三种旗标是互斥的,也就是不可同时使用,但可与下列的旗标利用OR(|)运算符组合。

O_CREAT若欲打开的文件不存在则自动建立该文件。

O_EXCL如果O_CREAT也被设置,此指令会去检查文件是否存在。

文件若不存在则建立该文件,否则将导致打开文件错误。

此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。

O_NOCTTY如果欲打开的文件为终端机设备时,则不会将该终端机当成进程控制终端机。

O_TRUNC若文件存在并且以可写的方式打开时,此旗标会令文件长度清为0,而原来存于该文件的资料也会消失。

O_APPEND当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。

O_NONBLOCK以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。

O_NDELAY同O_NONBLOCK。

O_SYNC以同步的方式打开文件。

O_NOFOLLOW如果参数pathname所指的文件为一符号连接,则会令打开文件失败。

O_DIRECTORY如果参数pathname所指的文件并非为一目录,则会令打开文件失败。

参数mode组合

  此为Linux2.2以后特有的旗标,以避免一些系统安全问题。

参数mode则有下列数种组合,只有在建立新文件时才会生效,此外真正建文件时的权限会受到umask值所影响,因此该文件权限应该为(mode-umaks)。

  S_IRWXU00700权限,代表该文件所有者具有可读、可写及可执行的权限。

  S_IRUSR或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。

  S_IWUSR或S_IWRITE,00200权限,代表该文件所有者具有可写入的权限。

  S_IXUSR或S_IEXEC,00100权限,代表该文件所有者具有可执行的权限。

  S_IRWXG00070权限,代表该文件用户组具有可读、可写及可执行的权限。

  S_IRGRP00040权限,代表该文件用户组具有可读的权限。

  S_IWGRP00020权限,代表该文件用户组具有可写入的权限。

  S_IXGRP00010权限,代表该文件用户组具有可执行的权限。

  S_IRWXO00007权限,代表其他用户具有可读、可写及可执行的权限。

  S_IROTH00004权限,代表其他用户具有可读的权限

  S_IWOTH00002权限,代表其他用户具有可写入的权限。

  S_IXOTH00001权限,代表其他用户具有可执行的权限。

返回值

  若所有欲核查的权限都通过了检查则返回文件描述符,表示成功,只要有一个权限被禁止则返回-1。

C语言中open函数

作用:

打开和创建文件。

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

ssize_tread(intfiledes,void*buf,size_tnbytes);

返回值:

读取到的字节数;0(读到EOF);-1(出错)

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!

\n");

}

/*配置串口*/

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);

printf("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);后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 或进程组ID

int

int

int

 

 

 

 

FIONBIN

FIOASYNC

FIONREAD

FIOSETOWN

FIOGETOWN

 

设置/ 清除非阻塞I/O 标志

设置/ 清除信号驱动异步I/O 标志

获取接收缓存区中的字节数

设置文件的进程ID 或进程组ID

获取文件的进程ID 或进程组ID

int

int

int

int

int

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SIOCGIFCONF

SIOCSIFADDR

SIOCGIFADDR

SIOCSIFFLAGS

SIOCGIFFLAGS

SIOCSIFDSTADDR

SIOCGIFDSTADDR

SIOCGIFBRDADDR

SIOCSIFBRDADDR

SIOCGIFNETMASK

SIOCSIFNETMASK

SIOCGIFMETRIC

SIOCSIFMETRIC

SIOCGIFMTU

SIOCxxx

获取所有接口的清单

设置接口地址

获取接口地址

设置接口标志

获取接口标志

设置点到点地址

获取点到点地址

获取广播地址

设置广播地址

获取子网掩码

设置子网掩码

获取接口的测度

设置接口的测度

获取接口MTU

(还有很多取决于系统的实现)

structifconf

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

structifreq

 

ARP

SIOCSARP

SIOCGARP

SIOCDARP

创建/ 修改ARP 表项

获取ARP 表项

删除ARP 表项

structarpreq

structarpreq

structarpreq

SIOCADDRT

SIOCDELRT

增加路径

删除路径

structrtentry

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 指定针对本套接口的SIGIO 或SIGURG 信号的接收进程,本请求和fcntl 的F_SETOWN 命令等效,POSIX 标准化的是fcntl 操作。

 

文件操作:

以下5 个请求都要求ioctl 的第三个参数指向一个整数。

 

FIONBIO :

        根据ioctl 的第三个参数指向一个0 或非0 值分别清除或设置本套接口的非阻塞标志。

本请求和O_NONBLOCK 文件状态标志等效,而该标志通过fcntl 的F_SETFL 命令清除或设置。

 

FIOASYNC :

      根据iocl 的第三个参数指向一个0 值或非0 值分别清除或设置针对本套接口的信号驱动异步I/O 标志,它决定是否收取针对本套接口的异步I/O 信号(SIGIO )。

本请求和O_ASYNC 文件状态标志等效,而该标志可以通过fcntl 的F_SETFL 命令清除或设置。

 

FIONREAD :

     通过由ioctl 的第三个参数指向的整数返回当前在本套接口接收缓冲区中的字节数。

本特性同样适用于文件,管道和终端。

 

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

#define ifc_req ifc_ifcu.ifcu_req   //arrayofstructuresreturned

 

#define 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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1