【Linux学习笔记28】系统IO的核心API(下)(dup、ioctl、fcntl、mmap,以及错误码处理)

本文深入探讨了Linux系统中的文件操作技巧,包括dup、ioctl、fcntl和mmap的使用,以及错误码处理方法。重点讲解了mmap在特殊文件处理中的应用,如将LCD屏幕的设备节点文件与内存进行映射,实现图像直接显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

继上一篇笔记后,这一篇笔记主要是介绍dup、ioctl、fcntl、mmap,以及错误码处理。

dup&dup2

系统中的文件重定向,实际上就是复制文件的描述符。而dup的作用就是复制这个文件的描述符:
在这里插入图片描述
上图是使用dup新生成一个fb也是指向a.txt的文件描述符。
那么dup只能使用在最小未使用的文件描述符中
如果要将文件描述符1不指向屏幕而指向a.txt呢?
在这里插入图片描述
使用dup2能够令指定文件描述符指向目标文件描述符。
如图就是:将文件描述符1指向文件描述符3指向的目标。(原理与cp类似)


ioctl

我们以一张图来介绍Ioctl
在这里插入图片描述
因为ioctl比较杂,因此更多具体的实例还得详细到实际使用的地方,例如控制LCD屏幕,可以作为LCD提供的头文件来作为参数使用。
详细可以通过Man ioctl


fcntl

fcntl会比ioctl晚出现,那么fcntl会比ioctl的功能整理地更加完善一些。但是与ioctl一样,参数也是需要根据实际需要而定。
但是不一样的是,fcntl有固定的cmd命令集。详细可以man fcntl查看。
在这里插入图片描述

cmd功能
F_DUPFD功能与dup类似
F_DUPFD_CLOEXEC多进程时,打开新文件代码是否被继承
F_GETFD获得/设置fd标签(很少用)
F_SETFL打开文件的模式设定(只读,只写,可读可写,阻塞方式打开等)
F_SETLK文件锁

mmap

一般使用在特殊文件处理。这里以LCD显示器为例:
在这里插入图片描述

  • 第一步:每个硬件设备在Linux中dev目录下的设备节点文件,那么首先将这个设备节点文件与内存进行映射。
  • 这里以LCD为例,长宽比为800:480,那么这块内存的大小主要取决于LCD屏幕的字节数,假设一个像素点为4字节,那么这块内存的大小就为:4800480字节。
  • 那么mmap函数就充当这个过程的映射作用。
  • 如果我们要将一张图片显示在LCD上,只需要将图片放入内存中就可以直接映射在LCD屏幕上。
代码实现
void *mmap(void * addr, size_t length, int prot , 
int flags ,int fd ,off_t offset);
参数作用
addr映射内存的起始地址,一般设置为NULL就会自动寻找一个合适的起始地址
length映射内存的大小,可以比显示屏大,但是不建议比显示屏小。
prot映射内存的保护权限:
protPROT_EXEC:可执行
protPROT_READ:可读
protPROT_WRITE:可写
protPROT_NONE:不可访问
flags当多个进程同时访问该内存时,该参数可以决定某一个进程内使映射内存的数据发生变更是否影响其他进程,也可以决定是否影响其对应的文件数据
fdLCD的文件描述符
offset图像偏移量相对的偏移
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#include<linux/input.h>

#include<sys/stat.h>
#include<sys/types.h>
#include <sys/mman.h>

#define BLACK 0xFFFFFFFF
#define WRITE 0x00000000
#define BLUE  0x000000FF

int main(int argc, char const *argv[])
{
  int lcd = open("/dev/fb0", O_RDWR|O_EXCL);

  char *p_lcd;
  p_lcd = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd,0);

  unsigned x = BLACK;

  int i ;
for ( i = 0; i < 800*480; i++)
  {
    memcpy(p_lcd+(4*i),&x,4);
  }
  return 0;
}


错误码处理

在编写代码的过程中,可以使用错误码处理,有针对显示出错误信息。
首先需要包含一个头文件errno.h,那么在使用我们的IO函数的过程是这样的:
在这里插入图片描述

  • 例如open函数是首先在应用中开始工作,然后进入库函数,完成工作后,再返回给应用。
  • 可是当在运行过程中遇到错误,比如权限不足,就会把信息发送给errno,errno会输出一个错误码。
  • 那么问题来了,errno只是负责输出一个错误码,而我们并不看得懂这个错误码,因此就要使用函数:perror或者strerror 函数来解读这个错误码:
perror("XXXX") perror会将XXXX完整输入,
并且在后面自动加上错误信息
strerror(errno) 会将errno给的错误码进行解读,
然后返回一个字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值