嵌入式Linux系统生产实习报告3文档格式.docx
《嵌入式Linux系统生产实习报告3文档格式.docx》由会员分享,可在线阅读,更多相关《嵌入式Linux系统生产实习报告3文档格式.docx(9页珍藏版)》请在冰豆网上搜索。
签字
二、实习报告
一、实习公司介绍:
我是西安工业大学探测制导与控制技术专业的学生,我生产实习所在的西安普特信息科技有限公司位于西安市高新区科技二路佳贝大厦,是一家专注于嵌入式产品研发、虚拟现实物联网智能软硬件设计开发、软件人才孵化的高新科技企业。
其中产品研发以电子产品研发为核心,倾力打造具有自主知识产权的电子产品开发销售服务平台,能够为OEM和系统集成客户提供快速有效的解决方案。
虚拟现实旨在建立物理世界和虚拟世界的桥梁,建立起了贯穿软件、硬件、外设、游艺设备的上下游生态体系,让科技改变娱乐。
人才孵化整合实训、咨询、项目多方面资源;
为被孵化人才提供创就业实战环境和项目,降低了孵化项目参与企业的运营成本,实现合作共赢。
二、实习目标及内容:
(1)实习目标:
1、熟悉linux的开发环境,常用的一些相关相关软件和命令。
2、熟练使用变量、指针、结构体,和基本函数使用方法;
能独立编写排序算法。
3、掌握文件操作的基本函数,打开使用设备;
可独立编写键盘输入记录和播放程序。
4、掌握进程线程创建的基本方法,会用互斥体完成资源保护。
5、理解网络通信的基本概念,掌握通信函数的基本使用;
编写聊天室模型。
6、将linux环境下的各种操作与硬件平台结合起来,利用驱动以及linux环境下的编程实现对硬件屏幕的控制。
(2)实习内容:
1、嵌入式相关介绍;
环境安装。
2、C语言基础补习回顾。
3、I/O编程:
介绍标准I/O编程、文件I/O编程;
4、进程编程:
进程线程的创建、进程间通信、进程间同步与互斥;
5、网络编程:
介绍网络通信模型(OSI模型、TCP/IP模型)、TCP/IP协议簇以及使用socket编程。
(3)具体文件操作及函数功能介绍:
1、linux哲学之一:
一切皆为文件
Linux文件种类:
1.普通文件2.目录文件3.链接文件4.设备文件
2、关于文件描述符
文件描述符是一个非负整数,是一个索引值
0STDIN_FILENO;
1STDOUT_FILENO;
2STDERR_FILENO,包含在<
unistd.h>
中,文件描述符的范围是0~OPEN_MAX,Linux下OPEN_MAX为1048576
3、不带缓冲的文件I/O操作
这次生产实习中将要用到的文件操作函数有open()close()read()write()lseek()注:
这些函数不是ANSIC的组成部分,但是是POSIX的组成部分。
4、关于出错处理
由于对文件的操作由于某种原因,比如文件打开失败、文件读、写失败,这些出错会导致程序执行失败。
解决办法:
加上出错处理,可以在出错时很明了的发现错误出在哪里;
常用函数:
#include<
errno.h>
、#include<
stdio.h>
、voidperror(constchar*s);
5、不带缓冲的文件操作函数
#include<
sys/types.h>
sys/stat.h>
#include<
fcntl.h>
,Intopen(constchar*pathname,intflags);
Intopen(constchar*pathname,intflags,mode_tmode);
返回值:
成功返回新分配的文件描述符,出错返回-1并讴置errno。
6、参数的含义
pathname:
是要打开或创建的文件的名字。
flags:
参数可用于说明此函数的多个选择项。
Mode:
对于open函数而言,仅当创建新文件时才使用第三个参数。
以下三个常数中必须指定一个,且仅允讲指定一个(这些常数定义在<
头文件中):
O_RDONLY只读打开。
O_WRONLY只写打开。
O_RDWR读、写打开。
7、可选项
以下可选项可以同时指定0个或多个,和必选项按位或来作为flags参数。
O_APPEND每次写时都加到文件的尾端。
O_CREAT若此文件不存在则创建它。
使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取讲可权位。
O_EXCL如果同时指定了O_CREAT,而文件已经存在,则出错。
这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。
O_TRUNC如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。
8、第三个参数mode指定文件权限,可以用八进制数表示,比如0644表示-rw-r--r—
9、close()函数
可用close函数关闭一个打开文件:
Intclose(intfiledes);
返回:
若成功为0,若出错为-1当一个进程终止时,它所有的打开文件都由内核自动关闭。
10、read()函数
用read函数从打开文件中读数据#include<
ssize_tread(intfeledes,void*buff,size_tnbytes);
读到的字节数,若已到文件尾为0,若出错为-1。
如read成功,则返回读到的字节数。
如已到达文件的尾端,则返回0。
11、write()函数
用write函数向打开文件写数据。
ssize_twrite(intfiledes,constvoid*buff,size_tnbytes);
若成功为已写的字节数,若出错为-1。
其返回值通常不参数nbytes的值不同,否则表示出错。
write出错的一个常见原因是:
磁盘已写满,或者超过了对一个给定进程的文件长度限制。
12、lseek()函数
off_tlseek(intfilesdes,off_toffset,intwhence);
若成功为新的文件位移,若出错为-1。
对参数offset的解释和参数whence的值有关。
若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset个字节。
若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset,offset可为正或负。
若whence是SEEK_END,则将该文件的位移量设置为文件长度加offset,offset可为正或负。
13、标准I/O操作
标准i/o库及其头文件stdio.h为底层I/O系统调用提供了一个通用的接口,这个库已经成为ANSI标准C的一部分在启动程序时,有三个文件流是自动打开的,他们是stdin,stdout,stderr这三个文件分别代表着标准输入、标准输出、标准错误输出,与底层文件描述符0、1、2对应标准I/O库提供了大量的复杂函数。
14、fopen函数
函数原型#include<
,FILE*fopen(constchar*filename,constchar*mode)返回值:
成功返回一个非空的FILE*指针,失败时返回NULL参数:
mode可以是以下字符串中的一个(注意是字符串不是字符)。
15、fopen()函数
“r”:
只读,文件必须已存在“w”:
只写,如果文件不存在则创建,如果文件已存在则把文件长度截断(Truncate)为0字节再重新写,也就是替换掉原来的的文件内容“a”:
只能在文件末尾追加数据,如果文件不存在则创建“r+”:
允许读和写,文件必须已存在“w+”:
允许读和写,如果文件不存在则创建,如果文件已存在则把文件长度截断为0字节再重新写“a+”:
允许读和追加数据,如果文件不存在则创建。
举例:
打开一个文件。
fp=fopen(“./hello.txt"
"
r"
);
if(fp==NULL){perror("
Openhello.txt"
exit
(1);
}
16、fclose()函数
Intfclose(FILE*fp);
成功返回0,出错返回EOF并设置errno
17fread()/fwrite()函数
原型:
:
size_tfread/fwrite(void*ptr,size_tsize,size_tnmemb,FILE*stream)参数:
size:
读取/写入的记录大小。
nmemb:
读取/写入的记录数;
返回值:
成功返回实际读入或写入的记录数目,失败返回EOF。
使用举例:
FILE*stream;
intarry[]={1,2,3,4,5,6,7,8};
stream=fopen(“data”,”w”);
if(stream==NULL)exit(-1);
fwrite(arry,sizeof(int),sizeof(arry)/sizeof(int),stream);
fclose(stream);
18、fseek()函数
:
fseeek(FILE*stream,longintoffset,intwhence)其参数与前面lseek完全一样
19、fgets()函数
char*fgets(char*str,intn,FILEstream)说明:
fgets函数从输入文件流stream里读取一个字符串。
并把它读到的字符写到str指向的字符串里,直到:
1、遇到换行符,应经传输了n-1个字符,或者达到文件尾。
注意:
它会把遇到的换行符也传递到接收字符串里,再在结尾加上一个表示结尾的空字节\0。
20、标准I/O的三种缓冲
全缓冲:
如果缓冲区写满了就写回内核。
常规文件通常是全缓冲的。
行缓冲:
如果用户程序写的数据中有换行符就把这一行写回内核,或者如果缓冲区写满了就写回内核。
标准输入和标准输出对应终端设备时通常是行缓冲的。
不带缓冲:
用户程序每次调库函数做写操作都要通过系统调用写回内核。
标准错误输出通常是无缓冲的,这样用户程序产生的错误信息可以尽快输出到设备。
21、socket编程
Intsocket(intfamily,inttype,intprotocol);
socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符,应用程序可以像读写文件一样用read/write在网络上收发数据,如果socket()调用出错则返回-1。
对于IPv4,family参数指定为AF_INET即为遵循UNIX网络套接字。
对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议。
(如果是UDP协议,则type参数指定为SOCK_DGRAM,表示面向数据报的传输协议。
)protocol参数的介绍从略,指定为0即可。
22、bind()函数
Intbind(intsockfd,conststructsockaddr*myaddr,socklen_taddrlen);
bind()成功返回0,失败返回-1。
服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑定一个固定的网络地址和端口号。
bind()的作用是将参数sockfd和myaddr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听myaddr所描述的地址和端口号。
23、sockaddr的初始化
bzero(&
servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(SERV_PORT);
首先将整个结构体清零,然后设置地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,直到不某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为SERV_PORT,我们定义为9732
24、listen()函数
Intlisten(intsockfd,intbacklog);
listen()成功返回0,失败返回-1。
典型的服务器程序可以同时服务于多个客户端,当有客户端发起连接时,服务器调用的accept()返回并接受这个连接,如果有大量的客户端发起连接而服务器来不及处理,尚未accept的客户端就处于连接等待状态,listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接待状态,如果接收到更多的连接请求就忽略。
25、select()函数
定义函数intselect(intn,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);
函数说明select()用来等待文件描述符状态的改变。
参数n代表最大的文件描述符加1,参数readfds、writefds和exceptfds称为描述符组,是用来回传该描述符的读,写或例外的状况。
26、select()的操作:
select底下的宏提供了处理这三种描述词组的方式:
FD_CLR(intfd,fd_set*set);
用来清除描述词组set中相关fd的位FD_ISSET(intfd,fd_set*set);
用来测试描述词组set中相关fd的位是否为真FD_SET(intfd,fd_set*set);
用来设置描述词组set中相关fd的位FD_ZERO(fd_set*set);
用来清除描述词组set的全部位参数timeout为结构timeval,用来设置select()的等待时间,其结构定义如下structtimeval{time_ttv_sec;
time_ttv_usec;
};
如果参数timeout设为NULL则表示select()没有timeout。
执行成功则返回文件描述符状态已改变的个数
27、accept()函数
Intaccept(intsockfd,structsockaddr*cliaddr,socklen_t*addrlen);
三次握手完成后,服务器调用accept()接受连接,如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来。
cliaddr是一个传出参数,accept()返回时传出客户端的地址和端口号。
addrlen参数是一个传入传出参数(value-resultargument),传入的是调用者提供的缓冲区cliaddr的长度以避免缓冲区溢出问题,传出的是客户端地址结构体的实际长度(有可能没有占满调用者提供的缓冲区)。
如果给cliaddr参数传NULL,表示不关心客户端的地址。
28、客户端程序
Intconnect(intsockfd,conststructsockaddr*servaddr,socklen_taddrlen);
connect()成功返回0,出错返回-1。
客户端需要调用connect()连接服务器,connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对方的地址。
三、实习总结:
3.1实习中遇到的问题
在本次实习中,老师系统的给我们讲述了linux环境下的嵌入式开发的基础知识,使我对linux的基本操作以及在linux环境下进行嵌入式的系统开发有了初步的认识,但是由于实习时间较短,在学校学习的理论知识没有能够在这短期的生产实习中与实践完全的融合起来。
在实习中了解了更多的行业前沿知识,认识到了自身知识及能力的不足,同时对自己有了更准确的定位。
因此在以后的学习中,我会更加注重理论与实践相结合来提高自己的能力。
3.2实习收获
这次实习,除了让我对嵌入式开发的基本知识有了一定了解,并且能进行基本操作外,我觉得自己在其他方面的收获也是挺大的.作为一名一直生活在单纯的大学校园的我,这次的生产实习无疑成为了我踏入社会前的一个平台,为我今后踏入社会奠定了基础.首先,我觉得在校学习和生产实习的最大一个不同就是必须要有很强的责任心.在生产实习时,我们必须要有强烈的责任感,要对自己工作负责,要对自己负责.如果没有完成当天应该完成的学习内容,那就必须得自己找时间自学;
如果不小心出现了错误,也必须及时纠正。
其次,我觉得每个人都必须要坚守自己的职业道德和努力提高自己的职业素养,正所谓做一行就要懂一行的行规.在这一点上我在实习时深有体会.比如,在学习理论知识时,如果有不懂的地方必须提出来并且尽快的找出解决的方法,否则将会对自己的实习有一定的影响。
所以对于我来说,实习态度问题尤为重要.最后,我觉得毕业实习以后,学历并不显得最重要,主要看的是个人的工作能力和交际能力.任何工作,做得时间久了是谁都会做的,在实际工作中动手能力更重要.因此,我体会到,如果将我们在大学里所学的知识与更多的实践结合在一起,用实践来检验真理,使一个本科生具备较强的处理基本事务的能力与比较系统的专业知识,这才是我们生产实习的真正目的.很感谢学校和实习单位-西安普特信息科技有限公司给我这个这么好的实习机会,让我学习很多、成长很多、收获很多。
3.3实习总结
实习期间,对于任何知识的学习一贯谦虚谨慎、认真学习。
如今的我通过此次实习了解到很多的软件开发知识。
我想这除了有较强的适应能力和积极向上的心态以外,更重要的是得益于实习老师的悉心指导。
实习生活,给我仅是初步的经验积累,对于迈向社会是远远不够的。
“吃的苦中苦,方为人上人”,我要恪守吃苦精神。
因此,在今后,我会继续努力拼搏,抓住每一个机遇,迎接每一个挑战,相信自己一定会演绎出精彩的一幕。
通过此次实习,让我学到了很多课堂上更本学不到的东西,仿佛自己一下子成熟了,懂得了做人做事的道理,也懂得了学习的意义,时间的宝贵,人生的真谛。
明白人世间一生不可能都是一帆风顺的,只要勇敢去面对人生中的每个驿站!
这让我清楚地感到了自己肩上的重任,看清了自己的人生方向,也让我认识到了文秘工作应支持仔细认真的工作态度,要有一种平和的心态和不耻下问的精神,不管遇到什么事都要总代表地去思考,多听别人的建议,不要太过急燥,要对自己所做事去负责,不要轻易的去承诺,承诺了就要努力去兑现。
单位也培养了我的实际动手能力,增加了实际的操作经验,对实际的财务工作的有了一个新的开始,更好地为我们今后的工作积累经验。
我知道工作是一项热情的事业,并且要持之以恒的品质精神和吃苦耐劳的品质。
我觉得重要的是在这段实习期间里,我第一次真正的融入了社会,在实践中了解社会掌握了一些与人交往的技能,也打开了视野,增长了见识,为我们以后进一步走向社会打下坚实的基础实习期间,我从末出现无故缺勤。
我勤奋好学.谦虚谨慎,认真听取老师的指导,对于别人提出的建议虚心听取并能够仔细观察、切身体验、独立思考、综合分析,并努力学到把学样学到的知道应用到实际工作中,尽力做到理论和实际相结合的最佳状态,培养了我执着的敬业精神和勤奋踏实的工作作风。
也培养了我的耐心和素质。
并始终坚持一条原则:
要么不做,要做就要做最好。