嵌入式Linux C概述
c和Linux c区别(嵌入式和非嵌入式区别):是否有操作系统
操作系统:
文件管理
设备管理
进程管理
网络协议栈
为什么要分为内核空间和用户空间?
由于在Linux中,为了更好的保护内核空间,将程序的运行空间分为内核空间和用户空间,用户进程在通常情况下不允许访问内核数据,也无法使用内核函数。
用户如何访问内核空间?
系统调用 硬件中断(没讲)
系统调用:
是指系统提供给用户的一组特殊接口(函数),用户可以通过这组特殊接口来获得操作系统内核提供的服务
它并不是直接与程序员进行交互的,在实际使用中程序员调用的是用户编程接口—API
怎么进行系统调用?
用户编程接口(函数接口)—API
系统命令和系统调用API的关系
为什么要学习嵌入式Linux C开发?
1、嵌入式上层应用软件开发
2、嵌入式底层软件的测试程序
嵌入式Linux C开发-I/O技术
嵌入式Linux系统中文件作用:“一点哲学”—一切皆为文件,通过文件来管理比较方便(文件系统)
Linux文件类型分类:
-表示普通文件;
d表示目录文件;
l表示链接文件;
c表示字符设备;
b表示块设备;
p表示管道文件,如FIFO文件;
f表示堆栈文件,如LIFO。
文件描述符:
知道一个文件的id,操作这个id,就相当与操作这个文件
动态分配:只要当操作这个文件时,系统才会给你分配文件描述符
非负整数:从3编号开始
0,1,2三个文件描述符有其它作用
无缓冲访问文件(系统调用)
creat函数:
//mode_t 无符号整数
作用:创建文件
第一个参数:创建的文件名,可带路径
第二个:权限
成功返回一个文件描述符,失败返回-1
注意:如果已经存在会被覆盖
errno:用来保存系统调用的错误信息,文件编程
perror:可以直接打印错误信息
open函数:
第一个参数:文件名
第二个参数:指定打开的方式
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
上面三种之间互斥,可以用 | 与下列一起使用
O_CREAT:不存在就创建
O_APPEND:读写文件时从文件尾开始移动,所写数据会加入到文件后面
第三个参数:创建文件时使用,指定权限
write函数
第一个参数:函数描述符,写入的文件
第二个参数:数据存放缓冲区的地址
第三个参数:写多少个
写入成功,返回写入的个数,不成功,返回小于0的数
O_APPEND:从末尾添加
read函数:
第二个参数,读出来的参数放入的地址
返回值:成功返回读到的字节数
==0 ,读到文件尾
-1,有错误发生
lseek函数:
作用:移动文件读写位置指针
第二个参数:有符号 正,往后移 负,往前移
第三个参数:
第一个,相对于文件头
第二个,当前位置
第三个,末尾
返回距离头的位置
问题:如何用lseek获取文件的长度?
答:int file_len=lseek(fd,0,SEEK_END);
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>
int main(int argc,char* argv[])
{
int fd=open(argv[1],O_RDWR|O_CREAT,0655);
if(fd==-1)
{
perror("open file error!");
exit(1);
}
printf("open file success=%d\n",fd);
char buffer[1024];
strcpy(buffer,"hello world");
int w_len=write(fd,buffer,strlen(buffer));
if(w_len==-1)
{
perror("write data error!");
exit(1);
}
printf("write data len=%d\n",w_len);
lseek(fd,0,SEEK_SET);
//lseek(fd,-w_len,SEEK_CUR);
memset(buffer,0,sizeof(buffer));//清空缓冲区
int r_len=read(fd,buffer,sizeof(buffer)-1);
if(r_len==-1)//==0 读到了末尾
{
perror("read data error!");
exit(1);
}
else if(r_len==0)
{
printf("read file end!\n");
}
buffer[r_len]='\0';
printf("read data:%s\n",buffer);
close(fd);
return 0;
}
实例1:
写三行数据hello1、hello2、hello3
分别读出每行数据
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
int read_line(int fd,char*buffer,int max_len)
{
int i;
int ret;
char temp;
for(i=0;i<max_len;i++)
{
ret=read(fd,&temp,1);
if(ret<0)
{
perror("read error!");
exit(1);
}
if(ret==0)
{
break;
}
if(temp=='\n')
{
break;
}
buffer[i]=temp;
}
buffer[i]='\0';
return i;
}
int main(int argc,char*argv[])
{
int fd;
if((fd=open(argv[1],O_RDWR|O_CREAT,0655))==-1)
{
perror("open file errror!");
exit(1);
}
char buffer[1024];
for(int i=0;i<3;i++)
{
memset(buffer,0,sizeof(buffer));
printf("please input data:\n");
scanf("%s",buffer);
if(write(fd,buffer,strlen(buffer))<0)
{
perror("write data error!");
exit(1);
}
write(fd,"\n",1);
}
memset(buffer,0,sizeof(buffer));
lseek(fd,0,SEEK_SET);
while(read_line(fd,buffer,sizeof(buffer)-1)!=0)
{
printf("buffer=%s\n",buffer);
memset(buffer,0,sizeof(buffer));
}
close(fd);
return 0;
}
实例2:拷贝文件
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#define BUFFER_SIZE 1024
int main(int argc,char *argv[])
{
int from_fd,to_fd;
int bytes_read,bytes_write;
char buffer[BUFFER_SIZE];
char *ptr;
if(argc!=3)
{
perror("fail!");
exit(1);
}
//打开源文件
if((from_fd=open(argv[1],O_RDONLY))==-1)
{
perror("open fail!");
exit(1);
}
//创建文件
if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1)
{
perror("open fail");
exit(1);
}
while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))
{
if((bytes_read==-1)&&(errno!=EINTR))
break;
else if(bytes_read>0)
{
ptr=buffer;
while(bytes_write=write(to_fd,ptr,bytes_read))
{
if((bytes_write==-1)&&(errno!=EINTR))
break;
else if(bytes_write==bytes_read)
break;
else if(bytes_write>0)
{
ptr +=bytes_write;
bytes_read-=bytes_write;
}
}
if(bytes_write==-1)
break;
}
}
close(from_fd);
close(to_fd);
exit(0);
}