2.linux文件io----在gec6818开发板上显示四叶草、彩虹

2023-10-29 20:20

本文主要是介绍2.linux文件io----在gec6818开发板上显示四叶草、彩虹,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

linux文件IO

1、内核实现

文件IO ==> file input output 文件的输入输出操作

在这里插入图片描述

对于文件的操作:

1.打开文件

2.读/写文件的内容

3.关闭文件

2.打开和关闭文件

打开open ===> 在ubuntu中使用man 2 open 查看函数相关手册

NAMEopen, openat, creat - open and possibly create a fileSYNOPSIS#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>open可以打开或者创建一个文件int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);
arg:@pathname :字符串,带路径的文件名,用来指定要打开的文件比如"./1.txt"表示当前路径下的1.txt文件@flags :标志位,用来表示打开文件的方式,可以位或多个但 下面三个只能选择一个:O_EDONLY	只读打开O_WRONLY	只写打开O_RDWR		读写打开然后可以再选择性的位或下列0个或多个宏O_CREAT		创建标志,如果指定的文件不存在,即先创建再打开O_TURNC		截断标志,打开文件并清空文件中的内容其余宏可查看函数手册@mode :当创建文件时,需要指定mode文件的权限,可以使用3位二进制表示比如:0777 0664 ...返回值:成功返回非负数,在程序中象征一个被打开的文件,称为文件描述符(fd),后续所有对于该文件的操作,都是通过文件描述符进行的失败返回-1,并且errno错误编码会被设置,此时就可以借助perror函数打印出错的信息

关闭 close

NAMEclose - close a file descriptorSYNOPSIS#include <unistd.h>close关闭指定的文件描述符(被打开的文件)int close(int fd);@fd:文件描述符,即open的返回值,指定要关闭的文件返回值:成功是0失败是-1,并且errno被设置

eg:以读写的方式打开当前目录下的1.txt文件,如果文件不存在则创建文件,如果文件存在则清空文件内容

       #include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>int main(void){int fd = 0;fd = open("./1.txt",O_RDWR|O_CREAT|O_TRUNC);if (fd == -1){perror("open file error");//perror参数可以带一个字符串,打印说明,函数会在字符串后根据errno自行输出错误的原因return -1;//如果打开文件失败,后续就无法执行}//打开文件后,就可以操作文件了close(fd);//不再进行操作了,记得关闭文件}

3.读写文件

文件被打开后,就可以调用read/write接口去读写文件的内容

读:从文件中获取文件内容

NAMEread - read from a file descriptorSYNOPSIS#include <unistd.h>read从指定文件描述符中读取数据存入缓冲区中ssize_t read(int fd, void *buf, size_t count);@fd :文件描述符,指定从那个文件读取数据@buf :指向一个缓存区,用来保存从文件中读取到的数据@count :整数,单位字节,表示你想要从文件中读取多少数据成功返回一个>=0的整数,表示实际从文件中读取到的字节数失败返回-1,并且errno被设置

写:与读正好相反,将指定的内容写入到文件中

NAMEwrite - write to a file descriptorSYNOPSIS#include <unistd.h>write写入数据到指定的文件描述符ssize_t write(int fd, const void *buf, size_t count);@fd :文件描述符,指定将数据写入到那个文件@buf :指针,所指向的空间中的数据就是要写入到文件中去的数据@count :整数,单位字节,表示你想要写入到文件中的字节数返回值:成功返回一个>=0的整数,表示实际写入到文件中的数据大小失败返回-1,并且errno被设置

eg:从打开的1.txt文件中读取20字节的数据

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{int fd = 0;ssize_t rsize = 0;//用来保存read的返回值,ssize_t其实就是longunsigned char rbuf[128] = {0};//定义一个缓冲区,用来保存从文件中读取的数据fd = open("./1.txt",O_RDWR);if (fd == -1){perror("open file error");return -1;}
//打开文件后就可以对文件进行其他操作了rsize = read(fd,rbuf,20);//从打开的文件中读取20个字节存入rbuf中if (rsize == -1){perror("read file error");close(fd);return -1;}else if(rsize == 0){printf("什么都没有读到\n");}else{printf("读取到了%ld个字节的数据存入了rbuf中,读取到的数据是:%s\n",rsize,rbuf);}//不再操作该文件了,就要记得关闭文件close(fd);return 0;
}

练习1:

假设当前目录中存在文件1.txt,该文件中有数量不定的文件内容,请编写程序,将该文件复制一份到2.txt,要求两个文件中的内容一模一样

提示:

1.read函数可以从一个被打开的文件中读取数据,并且将读取到的数据保存在第二参数指向的缓冲区中,并且read函数的返回值是表示本次读取文件时读取到了多少字节的数据

2.write函数可以将指定的缓存区的数据,写入到一个被打开的文件中

3.想要两个文件一模一样,就必须要求2.txt在打开时里面不能用数据,并且读写文件时要做到读多少,写多少

LCD屏幕显示

arm板上有一个自带的lcd屏幕,大小是800*480个像素点,每个像素点是32位的,在linux中lcd屏幕对应的设备文件是"/dev/fb0",用户只需要打开这个文件,并且往文件中写入颜色值,就可以让屏幕显示相应的颜色

关于颜色 :

0X000000 黑色

0XFFFFFF 白色

0XFF0000 红色

0X00FF00 绿色

0XFFFF00 黄色

0X0000FF 蓝色

映射

linux中的映射是指将一个打开的文件内容,映射到进程的存储空间中(进程地址空间/内存),用户可以通过访问映射的内存地址,就对于访问了该映射文件的文件内容

我们编写的程序本身就是直接访问内存地址空间,不需要借助操作系统,因此访问内存地址空间显然比访问存储在硬盘中的文件内容要快

将一个文件映射到内存后,操作映射内存地址就等同于操作了该文件的内容

linux的映射是借助mmap来实现的

NAMEmmap, munmap - map or unmap files or devices into memorySYNOPSIS#include <sys/mman.h>mmap用来将一个打开的文件(文件描述符)映射到内存地址空间void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);@addr:用来指定映射的内存地址空间,一般为NULL,让系统自己去选择@length:指定用于映射的内存地址空间的大小,取决于我们要映射的文件内容的大小,单位字节@prot:指定映射内存地址空间的访问权限,要求与被映射文件open时的权限一致PROT_READ	读权限PROT_WRITE	写权限PROT_EXEC	执行权限上面三个宏,可以位或使用@flags:标志位,用来指定映射的方式MAP_SHARED 共享映射,是指映射的文件对其他用户可见,并且操作映射内存空间的内容会被同步到映射文件@fd:文件描述符,指定要映射的文件@offset:文件偏移量(光标),指定从文件的那个位置开始映射0==>表示从文件一开始的位置就映射返回值:成功 返回映射内存的首地址失败 返回MAP_FAILED,并且errno被设置

解除映射 munmap 释放映射内存地址空间

NAMEmmap, munmap - map or unmap files or devices into memorySYNOPSIS#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);int munmap(void *addr, size_t length);@addr:指向要接触映射的映射内存空间首地址,即mmap的返回值@length:指定接触映射的空间大小,单位字节返回值:成功 0失败 -1

任务:

1 画一个彩虹

ngth, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
@addr:指向要接触映射的映射内存空间首地址,即mmap的返回值
@length:指定接触映射的空间大小,单位字节
返回值:
成功 0
失败 -1


任务:1 画一个彩虹```c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
int main()
{// 打开LCD屏幕文件int fd = open("/dev/fb0", O_RDWR | O_CREAT);if(fd == -1){printf("open txt failed\n");return -1;}/*红色 #FF0000橙色 #FF7F00黄色 #FFFF00绿色 #00FF00青色 #00FFFF蓝色 #0000FF紫色 #8B00FF0xffffff 白色*/// LCD 800*480 v 百度rgb颜色代码   0x ff 80 40int lcd_buf[480][800];int color[8] = {0x8b00ff, 0x0000ff, 0x00ffff, 0x00ff00, 0xffff00, 0xff7f00, 0xff0000, 0xffffff};int i, j, count = 0; // 记录色块落在哪个区间for(i = 0; i < 480; i++){for(j=-400; j< 400 ;j++){if((480-i)*(480-i)+j*j > 400*400 || (480-i)*(480-i)+j*j < 225){lcd_buf[i][j+400] = color[7];}else{count = sqrt((480-i)*(480-i) + j*j )/55;lcd_buf[i][j+400] = color[count];}}}write(fd, lcd_buf, 800*480*4);// fd文件描述符 指向我们将要写入数据的文件// buf	数据	我们将要写入数据// count	计数	我们最多写入多少个字节close(fd);return 0;}

在这里插入图片描述

2 画一个四叶草

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>int lcdfd = 0; //保存LCD屏幕文件的文件描述符
int *plcd = 0; //保存LCD屏幕映射内存首地址int lcd_init(void) //初始化LCD屏:打开和映射LCD屏幕文件
{/* 打开LCD屏驱动设备文件 */lcdfd = open("/dev/fb0",O_RDWR);if(-1 == lcdfd){perror("open lcd error");return -1;}/* 将LCD屏映射到内存空间 =》Frame Buffer 帧缓冲设备*/plcd = (int*)mmap(NULL,//系统自动选择映射地址800*480*32/8,	//映射空间大小(单位 字节),屏幕800*480个像素点,每个像素点32位(32/8个字节)PROT_READ|PROT_WRITE,//具备读写权限MAP_SHARED,//共享映射,对映射内存空间的操作会被同步到文件lcdfd,//指定映射的文件0); //从文件头开始映射if(MAP_FAILED == plcd){perror("mmap lcd error");close(lcdfd);return -1;}return 0;
}int lcd_uninit(void)//释放LCD屏:接触映射,关闭LCD屏幕文件
{/* 收尾:解除映射,关闭屏幕文件 */munmap(plcd,800*480*32/8);close(lcdfd);return 0;
}int lcd_draw_point(int x,int y,int color)	//画点函数,用来将坐标为(x,y)的像素点显示为color色
{if(x<0 || x >=800 || y<0 || y>=480){printf("指定画点的坐标超出屏幕范围\n");return -1;}*(plcd + y*800 + x) = color;return 0;
}int lcd_draw_clear(int x0,int y0,int w,int h,int color)//清屏函数,用来将从(x0,y0)为起点,宽w,高h的矩形区域显示为 color色
{int x = 0;int y = 0;for(x=x0;x<x0+w;x++){for(y=y0;y<y0+h;y++){lcd_draw_point(x,y, color);}}return 0;
}int lcd_draw_FourLeafClover(void)//在屏幕上显示一个四叶草(取上下左右四个圆两两的交集)
{//中心(400,240)//上:(400,40) 下:(400,440)左:(200,240) 右:(600,240)int x = 0;int y = 0;for(y=0;y<480;y++){for(x=0;x<800;x++){if( (x-400)*(x-400)+(y-40)*(y-40)<=200*200 && (x-200)*(x-200)+(y-240)*(y-240)<=200*200  //上左||(x-400)*(x-400)+(y-440)*(y-440)<=200*200 && (x-200)*(x-200)+(y-240)*(y-240)<=200*200  //下左||(x-400)*(x-400)+(y-440)*(y-440)<=200*200 && (x-600)*(x-600)+(y-240)*(y-240)<=200*200  //下右||(x-400)*(x-400)+(y-40)*(y-40)<=200*200 && (x-600)*(x-600)+(y-240)*(y-240)<=200*200)  //下右{lcd_draw_point(x,y,0x00ff00);}}}
}int lcd_draw_Rainbow(void)//在屏幕上显示一个彩虹
{int x = 0;int y = 0;for(y=0;y<480;y++){for(x=0;x<800;x++){if((x-400)*(x-400)+(y-479)*(y-479)<=40*40){lcd_draw_point(x,y,0xffffff);}else if((x-400)*(x-400)+(y-479)*(y-479)<=80*80){lcd_draw_point(x,y,0xff00ff);}else if((x-400)*(x-400)+(y-479)*(y-479)<=120*120){lcd_draw_point(x,y,0x0000ff);}else if((x-400)*(x-400)+(y-479)*(y-479)<=160*160){lcd_draw_point(x,y,0x00ffff);}else if((x-400)*(x-400)+(y-479)*(y-479)<=200*200){lcd_draw_point(x,y,0x00ff00);}else if((x-400)*(x-400)+(y-479)*(y-479)<=240*240){lcd_draw_point(x,y,0xffff00);}else if((x-400)*(x-400)+(y-479)*(y-479)<=280*280){lcd_draw_point(x,y,0xff8020);}else if((x-400)*(x-400)+(y-479)*(y-479)<=320*320){lcd_draw_point(x,y,0xff0000);}}}
}

这篇关于2.linux文件io----在gec6818开发板上显示四叶草、彩虹的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/xqmids99/article/details/131255015
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/303113

相关文章

idea中project的显示问题及解决

《idea中project的显示问题及解决》:本文主要介绍idea中project的显示问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录idea中project的显示问题清除配置重China编程新生成配置总结idea中project的显示问题新建空的pr

windows和Linux安装Jmeter与简单使用方式

《windows和Linux安装Jmeter与简单使用方式》:本文主要介绍windows和Linux安装Jmeter与简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows和linux安装Jmeter与简单使用一、下载安装包二、JDK安装1.windows设

Kali Linux安装实现教程(亲测有效)

《KaliLinux安装实现教程(亲测有效)》:本文主要介绍KaliLinux安装实现教程(亲测有效),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、下载二、安装总结一、下载1、点http://www.chinasem.cn击链接 Get Kali | Kal

linux服务之NIS账户管理服务方式

《linux服务之NIS账户管理服务方式》:本文主要介绍linux服务之NIS账户管理服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、所需要的软件二、服务器配置1、安装 NIS 服务2、设定 NIS 的域名 (NIS domain name)3、修改主

Linux实现简易版Shell的代码详解

《Linux实现简易版Shell的代码详解》本篇文章,我们将一起踏上一段有趣的旅程,仿照CentOS–Bash的工作流程,实现一个功能虽然简单,但足以让你深刻理解Shell工作原理的迷你Sh... 目录一、程序流程分析二、代码实现1. 打印命令行提示符2. 获取用户输入的命令行3. 命令行解析4. 执行命令

Python文件操作与IO流的使用方式

《Python文件操作与IO流的使用方式》:本文主要介绍Python文件操作与IO流的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、python文件操作基础1. 打开文件2. 关闭文件二、文件读写操作1.www.chinasem.cn 读取文件2. 写

ubuntu16.04如何部署dify? 在Linux上安装部署Dify的技巧

《ubuntu16.04如何部署dify?在Linux上安装部署Dify的技巧》随着云计算和容器技术的快速发展,Docker已经成为现代软件开发和部署的重要工具之一,Dify作为一款优秀的云原生应用... Dify 是一个基于 docker 的工作流管理工具,旨在简化机器学习和数据科学领域的多步骤工作流。它

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Linux系统调试之ltrace工具使用与调试过程

《Linux系统调试之ltrace工具使用与调试过程》:本文主要介绍Linux系统调试之ltrace工具使用与调试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、ltrace 定义与作用二、ltrace 工作原理1. 劫持进程的 PLT/GOT 表2. 重定

Linux区分SSD和机械硬盘的方法总结

《Linux区分SSD和机械硬盘的方法总结》在Linux系统管理中,了解存储设备的类型和特性是至关重要的,不同的存储介质(如固态硬盘SSD和机械硬盘HDD)在性能、可靠性和适用场景上有着显著差异,本文... 目录一、lsblk 命令简介基本用法二、识别磁盘类型的关键参数:ROTA查询 ROTA 参数ROTA