一、设计思路与设计方法
嵌入式Linux系统移植主要由四大部分组成:
- 搭建交叉开发环境
- bootloader的选择和移植
- kernel的配置、编译和移植
- 根文件系统的制作
把bootloader烧写到开发板的Kernel中后,开发板从Kernel启动,硬件会自动将bootloader加载到内存中运行,bootloader将板载资源都初始化完成后,会停留在一个命令行界面,接收并执行用户敲入的命令。这时候用户可以通过命令控制开发板,比如查看参数列表:print、读写read、write 、内存管理:mm、设置参数列表:setenv、网络下载:tftp、启动内核:bootm等等。如果我们把一个编译好的内核通过tftp服务器下载到内存中,就可以通过bootm 命令启动内核。
简易网盘的实现方法:
网络连接是通过socket编程进行TCP连接。
编写好程序之后在虚拟机上通过gcc命令编译tcp_server.c成为可执行文件server,通过arm-none-linux-gnueabi-gcc命令将tcp_client.c编译为可执行文件client。
通过tftp服务器在目标板上用tftp -g -r向服务器192.168.0.100中下载可执行文件client。
先在虚拟机上运行Server程序,再在目标板上运行Client程序,在出现connect ok后表示连接完成。
在连接完成后在客户机上输入需要下载的文件名,例如:12.txt,按下回车就可看到传输过程。传输结束后按ctrl+c退出后输入ls就可看到传输的文件。
二、运行结果
三、遇到的问题及解决的方法
问题1:别的人的电脑可以通过tftp在下载我电脑上的文件,而我却不能下载别人电脑上的文件。
解决方法:通过将动态地址转换为静态地址解决了这个问题。
问题2:tftp在环境配置中配置错误,导致终端调试出现无法修复的问题。
解决方法:通过删除虚拟机系统,重新解压出新的虚拟机系统解决。
问题3:传输文件时,传输完成后又多传输了两行
解决方法:是因为写代码时使用了do-while循环导致比while循环多运行一次,客户机和服务器加起来就是两次,所以把do-while循环换成了while循环。
问题4:通过gcc编译的client文件在目标板上无法执行
解决方法:因为虚拟机时x86架构的,而目标板是ARM架构的所以无法执行gcc编译的程序,只能通过arm-none-linux-gnueabi-gcc命令编译成ARM架构的可执行文件才可执行。
四、源代码
1. /*************************************************************************
2. > File Name: tcp_server.c
3. > Version:3.0
4. > Author: DL
5. > Finished Time: Thu 9 Jun 2020 16:11:59 PM CTS ************************************************************************/
6.
7. #include<stdio.h>
8. #include <sys/types.h>
9. #include <sys/socket.h>
10. #include <string.h>
11. #include <netinet/in.h>
12. #include <unistd.h>
13. #include <fcntl.h>
14. #include <sys/stat.h>
15.
16. #define BUF_SIZE 20
17.
18. int main()
19. {
20. int ret,ret1;
21. //socket
22. int iServer=socket(AF_INET,SOCK_STREAM,0);
23. if(-1==iServer)
24. {
25. return -1;
26. }
27. printf("socket ok,iServer=%d\r\n",iServer);
28. //bind
29. struct sockaddr_in stServer;
30. stServer.sin_family=AF_INET;
31. stServer.sin_port=htons(8888);
32. stServer.sin_addr.s_addr=inet_addr("192.168.0.100");
33. ret=bind(iServer,(struct sockaddr *)&stServer,sizeof(struct sockaddr_in));
34. if(-1==ret)
35. {
36. return -1;
37. }
38. printf("bind ok\r\n");
39. listen
40. ret=listen(iServer,5);
41. if(-1==ret)
42. {
43. return -1;
44. }
45. printf("listen ok\r\n");
46. //accept
47. struct sockaddr_in stClient;
48. socklen_t len=sizeof(struct sockaddr_in);
49. char buf[BUF_SIZE];
50. int iClient;
51. while(1)
52. {
53. memset(buf,0,BUF_SIZE);
54. memset(&stClient,0,len);
55. iClient=accept(iServer,(struct sockaddr *)&stClient,&len);
56. if(-1==iClient)
57. {
58. return -1;
59. }
60. printf("accept ok,iClient=%d\r\n",iClient);
61.
62. //recv
63. ret=recv(iClient,buf,BUF_SIZE,0);
64. if(ret<=0)
65. {
66. close(iClient);
67. continue;
68. }
69. printf("recv:%d %s\r\n",ret,buf);
70.
71. int fd = open(buf,O_RDWR,0644);
72. if(fd<0)
73. {
74. perror("open");
75. return -1;
76. }
77. while(ret = read(fd,buf,BUF_SIZE),ret > 0)
78. {
79. //read
80. //ret = read(fd,buf,BUF_SIZE);
81. if(ret<0)
82. {
83. printf("read error!\n");
84. }
85. //send
86. ret1=send(iClient,buf,strlen(buf)-1,0);
87. printf("send:ret=%d %s\r\n",ret1,buf);
88. memset(buf,0,BUF_SIZE);
89.
90. }
91. }
92.
93.
94. close(iClient);
95. return 0;
96. }
97. /*************************************************************************
98. > File Name: tcp_client.c
99. > Version:3.0
100. > Author: DL
101. > Finished Time: Thu 9 Jun 2020 16:11:59 PM CTS ************************************************************************/
102.
103. #include<stdio.h>
104. #include <sys/types.h> /* See NOTES */
105. #include <sys/socket.h>
106. #include <unistd.h>
107. #include <fcntl.h>
108. #include <sys/stat.h>
109. #include <string.h>
110. #include <netinet/in.h>
111.
112.
113.
114. #define BUF_SIZE 20
115. int main()
116. {
117. //socket
118. int iClient=socket(AF_INET,SOCK_STREAM,0);
119. if(-1==iClient)
120. {
121. return -1;
122. }
123. printf("socket ok\r\n");
124. //connect
125. struct sockaddr_in stServer;
126. stServer.sin_family=AF_INET;
127. stServer.sin_port=htons(8888);
128. stServer.sin_addr.s_addr=inet_addr("192.168.0.100");
129. int ret=connect(iClient,(struct sockaddr *)&stServer,sizeof(struct sockaddr_in));
130. if(-1==ret)
131. {
132. return -1;
133. }
134. printf("connect ok\r\n");
135.
136. while(1)
137. {
138. char buf[BUF_SIZE]={0};
139. // fgets(buf,BUF_SIZE,stdin);
140. gets(buf);
141. //send filename
142. ret=send(iClient,buf,BUF_SIZE,0);
143.
144. if(-1==ret)
145. {
146. printf("send file error\r\n");
147. }
148.
149. // printf("send ok,ret=%d\r\n",ret);
150.
151.
152. //recv
153.
154. int fd1 = open(buf,O_RDWR|O_CREAT,0644);
155. memset(buf,0,BUF_SIZE);
156. while((ret =recv(iClient,buf,BUF_SIZE,0))>0)
157. {
158. //ret =recv(iClient,buf,BUF_SIZE,0);
159. if( -1 == ret )
160. {
161. printf("recv error\r\n");
162. }
163. printf("recv ok,ret=%d %s\r\n",ret,buf);
164. // write
165.
166. if(fd1< 0)
167. {
168. perror("open");
169. return -1;
170. }
171. int ret1=write(fd1,buf,ret);
172. if(ret1<0)
173. {
174. printf("write error!");
175. }
176. memset(buf,0,BUF_SIZE);
177. }
178. //while(ret>0);
179.
180. }
181. close(iClient);
182. return 0;
183. }