linux硬件设备操作函数 open(/dev/ietctl, O_RDWR|...)

一般的写法是if((fd=open("/dev/ttys0",O_RDWR | O_NOCTTY | O_NDELAY)<0){
perror("open");}这个事常用的一种用法fd是设备描述符,linux在操作硬件设备时,屏蔽了硬件的基本细节,只把硬件当做文件来进行操作,而所有的操作都是以open函数来开始,它用来获取fd,然后后期的其他操作全部控制fd来完成对硬件设备的实际操作。你要打开的/dev/ttyS0,代表的是串口1,也就是常说的com1,后面跟的是一些控制字。int open(const char *pathname, int oflag, …/*, mode_t mode * / ) ;这个就是open函数的公式。控制字可以有多种,我现在给你列出来:
O_RDONLY 只读打开。
O_WRONLY 只写打开。
O_RDWR 读、写打开。
O_APPEND 每次写时都加到文件的尾端。
O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位。
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错。这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。
O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。
O_NOCTTY 如果p a t h n a m e指的是终端设备,则不将此设备分配作为此进程的控制终端。
O_NONBLOCK 如果p a t h n a m e指的是一个F I F O、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I / O操作设置非阻塞方式。
O_SYNC 使每次w r i t e都等到物理I / O操作完成。
这些控制字都是通过“或”符号分开(|)
通过这些介绍,你的那段代码就不难解释了:是以读写方式、不把该文件作为终端设备、无延时模式打开串口1.

1. read函数

1)      函数原型:

       #include <unistd.h>

       ssize_t read(int fd, void *buf, size_t count);

2)      函数功能:

       read系统调用从文件描述符fd指向的文件中,读取count个字节到buf中。

3)      参数说明:

       fd:文件描述符

       buf:保存读入信息的缓存

      count:要读取的字节数

      返回值:如果read成功,则返回读到的字节数,如果已达到结尾,则返回0,出错     

                返回-1

      

2. write函数

1)   函数原型:

         #include <unistd.h>

         ssize_t write(int fd, const void *buf, size_t count);

2)   函数功能:

       write系统调用将buf所指向的缓冲区的count个字节内容写入fd指向的文件

3)   参数说明:

       fd:要写入的文件

       buf:要写入的信息所在的缓存

      count:要写入的字节数

      返回值:如果write成功,则返回写入的字节数,出错返回-1

 

3. lseek函数

1)    函数原型:

       #include <sys/types.h>

       #include <unistd.h>

       off_t  lseek(int fildes, off_t offset, int whence);

2)    函数功能:

       lseek系统调用用来移动读写指针的位置

3)   参数说明:

       fd:要操作的文件

      offset:相对whence移动的位移数,允许负值

      whence:起始指针,它有三个取值

            SEEK_SET 从文件开始处计算偏移量

            SEEK_CUR 从文件指针的当前位置开始计算偏移量

            SEEK_END 从文件结尾处开始计算偏移量

     文件指针值等于当前指针值加上offset的值。

     返回值:调用成功时范围当前的读写位置,也就是距离文件开始处多少字节,若

                有错误返回-1

4)  常见用法:

       将文件读写指针移动到文件开头:

       lseek(int fildes, 0, SEEK_SET);

       将文件读写指针移动到文件结尾:

  lseek(int fildes, 0, SEEK_END);

  获取文件读写指针当前的位置

  lseek(int fikdes, 0, SEEK_CUR);

注意:有些设备(或者说设备文件)不能使用lseek,linux系统不允许lseek()对tty设备进行操作,此项操作会使得lseek()范围错误代码ESPIPE

 

4.实例程序:

1)演示文件读写和文件指针的移动过程:

复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

void my_error(const char* errstring, int line)
{
    fprintf(stderr,"line:%d",line);
    perror(errstring);
    exit(1);
}

int my_read(int fd)
{
    int len = 19,ret,i;
    char buf[128];
    
    if((lseek(fd,0,SEEK_END)) == -1)
    {
        my_error("lseek",__LINE__);
    }
    if((len = lseek(fd,0,SEEK_CUR)) == -1)
    {
        my_error("lseek",__LINE__);
    }
    if((lseek(fd,0,SEEK_SET)) == -1) 
    {
        my_error("lseek",__LINE__);
    }
   
       printf("文件长:%d\n",len);
    if((ret = read(fd,buf,len)) == -1)
    {
        my_error("read",__LINE__);
    }

    for(i=0;i<len;i++)
    {
        printf("%c",buf[i]);
    }
    printf("\n");
}


int main()
{
    int fd;
    char buf[128] = "my name is haohuai!";
    umask(0000);
    if((fd = open("test.txt",O_RDWR | O_CREAT | O_TRUNC,0777)) == -1)
    {
        my_error("open",__LINE__);
    }
    else
    {
        printf("open success!\n");
    }
    
    if(write(fd,buf,strlen(buf)) != strlen(buf))
    {
        my_error("write",__LINE__);
    }
    else
    {
        printf("write success!\n");
    }
    my_read(fd);
    return 0;

}
复制代码

注:1)其中__LINE__是预编译器内置宏,表示当前行,类似的还有__TIME__、

    __FUNCTION__ 、__FILE__等,表示时间、函数名、文件名。

    2)read读取文件之前一定要先将文件指针指向文件开始处,否则文件指针处

    于文件结尾处。

运行结果:

[hb@localhost unixadvance]$ gcc -g -o testWRL testWRL.c

[hb@localhost unixadvance]$ ./testWRL

open success!

write success!

文件长:19

my name is haohuai!

 

2)将标准输入复制到标准输出

复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define SIZE 1024

int main()
{
    int n ;
    char buf[SIZE];

    while((n = read(STDIN_FILENO,buf,SIZE)) > 0)
    {
        if(write(STDOUT_FILENO,buf,n) != n)
        {
            perror("write error");
        }
    }
    if(n < 0)
    {
        perror("read error");
    }

    return 0;
}
复制代码

注:STDIN_FILENO和STDOUT_FILENO分别是标准输入和标准输入的文件描述

   符,一般是0和1,定义在<unistd.h>


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值