文件IO控制之fcntl

1.ANSIC与POSIX

  • ANSI C:这一标准是 ANSI(美国国家标准局)于 1989 年制定的 C 语言标准。 后来被 ISO(国际标准化组织)接受为标准,因此也称为 ISO C。
    ANSI C 的目标是为各种操作系统上的 C 程序提供可移植性保证,而不仅仅限于 UNIX。 该标准不仅定义了 C 编程语言的语发和语义,而且还定义了一个标准库。这个库可以根据 头文件划分为 15 个部分,其中包括:字符类型 (<ctype.h>)、错误码 (<errno.h>)、 浮点常数 (<float.h>)、数学常数 (<math.h>)、标准定义 (<stddef.h>)、 标准 I/O (<stdio.h>)、工具函数 (<stdlib.h>)、字符串操作 (<string.h>)、 时间和日期 (<time.h>)、可变参数表 (<stdarg.h>)、信号 (<signal.h>)、 非局部跳转 (<setjmp.h>)、本地信息 (<local.h>)、程序断言 (<assert.h>) 等等。
  • POSIX:该标准最初由 IEEE 开发的标准族,部分已经被 ISO 接受为国际标准。该标准的具体内容 见 1.1.3。POSIX.1 和 POSIX.2 分别定义了 POSIX 兼容操作系统的 C 语言系统接口 以及 shell 和工具标准。这两个标准是通常提到的标准。POSIX 表示可移植操作系统接口(Portable Operating System Interface ,缩写为 POSIX 是为了读音更 像 UNIX)。电气和电子工程师协会(Institute of Electrical and Electronics Engineers,IEEE) 最初开发 POSIX 标准,是为了提高 UNIX 环境下应用程序的可移植性。然而,POSIX 并不局限于 UNIX。 许多其它的操作系统,例如 DEC OpenVMS 和 Microsoft Windows NT,都支持 POSIX 标准,尤其是 IEEE Std. 1003.1-1990(1995 年修订)或 POSIX.1,POSIX.1 提供了源代码级别的 C 语言应用编程 接口(API)给操作系统的服务程序,例如读写文件。POSIX.1 已经被国际标准化组织(International Standards Organization,ISO)所接受,被命名为 ISO/IEC 9945-1:1990 标准

2.linux 系统主要是通过文件描述符对文件,对管道设备,设备(UART,SDIO,Flash),socket套接字进行操作的.
3. 不带缓存的文件I/O操作(用POSIX里的函数)
函数:open,write,read,lseek,close,fcntl,select
其中fcntl解决文件资源共享问题,select解决文件I/O复用问题
4.fcntl
refer to https://www.cnblogs.com/zxc2man/p/7649240.html
4.1fcntl函数原型
#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd ,struct flock* lock);

4.1.1cmd 参数
fcntl函数功能依据cmd的值的不同而不同。参数对应功能如下:

4.1.2 clock 参数

struct flock
{
    short_l_type;    /*锁的类型*/
    short_l_whence;  /*偏移量的起始位置:SEEK_SET,SEEK_CUR,SEEK_END*/
    off_t_l_start;     /*加锁的起始偏移*/
    off_t_l_len;    /*上锁字节*/
    pid_t_l_pid;   /*锁的属主进程ID */
}; 

(1)short_l_type
F_RDLCK为读锁
F_WDLCK为写锁
F_UNLCK为解锁
>F_SETLK
此时fcntl函数用来设置或释放锁。当short_l_type为F_RDLCK为读锁,F_WDLCK为写锁,F_UNLCK为解锁。
如果锁被其他进程占用,则返回-1;
这种情况设的锁遇到锁被其他进程占用时,会立刻停止进程。
>F_SETLKW
此时也是给文件上锁,不同于F_SETLK的是,该上锁是阻塞方式。当希望设置的锁因为其他锁而被阻止设置时,该命令会等待相冲突的锁被释放。
>F_GETLK
第3个参数lock指向一个希望设置的锁的属性结构,如果锁能被设置,该命令并不真的设置锁,而是只修改lock的l_type为F_UNLCK,然后返回该结构体。如果存在一个或多个锁与希望设置的锁相互冲突,则fcntl返回其中的一个锁的flock结构。


(2)l_whence,l_start,l_len三个变量来确定给文件上锁的区域。
l_whence确定文件内部的位置指针从哪开始,l_star确定从l_whence开始的位置的偏移量,两个变量一起确定了文件内的位置指针先所指的位置,即开始上锁的位置,然后l_len的字节数就确定了上锁的区域。特殊的,当l_len的值为0时,则表示锁的区域从起点开始直至最大的可能位置,就是从l_whence和l_start两个变量确定的开始位置开始上锁,将开始以后的所有区域都上锁。为了锁整个文件,我们会把l_whence,l_start,l_len都设为0。

 

==============================串口操作========================================

 1.有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。
对于fcntl
(1)fcntl(s_fd, F_SETFL, FNDELAY);     //None block
(2)fcntl(s_fd, F_SETFL, 0);                     //block

阻塞的定义:
       对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数;
      对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数。

非阻塞的定义:
         对于read,no block指当串口输入缓冲区没有数据的时候,read函数立即返回,返回值为0。
         对于write,no block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将进行写操作,写入当前串口输出缓冲区剩下空间允许的字节数,然后返回写入的字节数。

 

14. read data from uart 
read(fd, pBuffer, size);

15. write
send data to uart


1.  termio structure 
#include<termios.h> 
struct  termio
{
   unsigned short c_iflag;    //input mode flag 
   unsigned short c_oflag;   //output mode flag
   unsigned short c_cflag;   //control mode flag
   unsigned short c_lflag;   //local mode flag 
   unsigned char c_line;    //line discipline
   unsigned char c_cc[NCC];        //control characters

2. tcgetattr
// get the default parameters of uart to struct termio
struct termio option; 
tcgetattr(fd,&option)

3. cfsetispeed 
//set the baudrate of input mode 
cfsetispeed( &options, baudrate );

4.cfsetospeed
//set the baudrate of output mode
cfsetospeed( &options, baudrate);

5.cfmakeraw(&option) 
// set the uart to raw mode
termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP| INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

6. options.c_cflag |= ( CLOCAL | CREAD )    
// ignore modem control lines and enable receiver 

7.set the character size
    options.c_cflag &= ~CSIZE; // mask the character size bits
    options.c_cflag |= CS8;    // select 8 data bits

8. set no parity (8N1)
      options.c_cflag &= ~PARENB;
      options.c_cflag &= ~CSTOPB;
      options.c_cflag &= ~CSIZE;
      options.c_cflag |= CS8;

9. enable raw input
      options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 

10.disable software flow control
     options.c_iflag &= ~(IXON | IXOFF | IXANY);

11. chose raw (not processed) output
     options.c_oflag &= ~OPOST;

12. tcsetattr(fd,TCSANOW,&option)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值