fmql之Linux以太网
正点原子第57章。
dts
fmql-dtsi:
我们用的PHY芯片是RTL8211F:
需要添加PHY信息:
fmql-dtsi提供的参考:
根据vivado工程自动生成的:
- reg = <0x1>;
配置
疑问
网口通讯需要网线,但是目前板卡上只有PS_LWIP,且连接路由器(为了远程传输文件)。
那么,该网口是否可以进行通信?(通过程序进行收发)
正点原子教程只是测试了gmac0和gmac1的联网是否正常。
对后续我们所需实现的功能:tcp协议收发数据,没有作解释。
解答
先说结论:理论上可以。
主机(即电脑 PC)连接路由器,与板卡处在同一网段。
主机ping板卡: 能ping通
板卡ping主机: 能ping通
测试联网
ping -c 10 www.baidu.com
主机:
板卡:
主机和板卡都无法联网,是因为路由器没有网。
所以,如果路由器有网,则能ping通baidu.com(理论上)。
应用程序编写
代码来自以下链接:
LINUX应用网络代码-CSDN博客
配置了ip_addr(固定ip)和PORT,分为服务器端和客户端的代码。
但是!
路由器通过dhcp自动给板卡分配了ip,在程序里如何利用这一点?
- 网线连接路由器,电脑与板卡在同一网段:
- 网线连接电脑:
再次尝试
(server的程序其实也是client)也就是说,在server的程序中,ifdef并没有注释掉client的代码。
重新测试server代码: 成功
client仍然不行
代码
server的代码并不需要ip地址。
/***************************************************************
文件名 : lwipServerAPP.c
作者 : Skylar
描述 : 网口收发测试
其他 : succeed
***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>
#include <arpa/inet.h>
#define TCP_PORT 5001
#define IP_ADDR "192.168.1.138"
#define BUF_SIZ 128
int main(void)//(int argc,char **argv)
{
int fd = -1;
struct sockaddr_in serve_addr;
int ret = -1;
char buf[BUF_SIZ];
const char *hello = "Hello from TCP Server";
if((fd = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
printf("fd = %d\n",fd);
perror("socket");
exit(1);
}
printf("socket\r\n");
bzero(&serve_addr,sizeof(serve_addr));
// IP & Port
serve_addr.sin_family = AF_INET;
serve_addr.sin_port = htons(TCP_PORT);
serve_addr.sin_addr.s_addr = INADDR_ANY;
/* if(inet_pton(AF_INET,ADDR,(void *)&serve_addr.sin_addr) != 1)
{
perror("pton");
exit(1);
}
*/
//绑定
if(bind(fd,(struct sockaddr *)&serve_addr,sizeof(serve_addr)) < 0)
{
perror("bind");
exit(1);
}
printf("bind\r\n");
//调用listen把主动套接字变成被动套接字
if(listen(fd,5) < 0) // 监听连接
{
perror("listen");
exit(1);
}
printf("listen\r\n");
socklen_t len = sizeof(struct sockaddr_in); //sockaddr
struct sockaddr_in * cilt =(struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
bzero(cilt,sizeof(struct sockaddr));
//阻塞等待客户端链接请求
int newfd = -1;
newfd = accept(fd,(struct sockaddr *)cilt,&len);
if(newfd < 0)
{
perror("accept");
exit(1);
}
printf("accept\r\n");
//读写
char p[INET_ADDRSTRLEN];
unsigned short int du = ntohs(cilt->sin_port);
inet_ntop(AF_INET,(void *)&(cilt->sin_addr),p,len);
ret = send(newfd, hello, strlen(hello), 0);
if(ret < 0){
perror("send");
return -1;
}else{
printf("send message succeed\r\n");
}
while(1)
{
bzero(buf,sizeof(buf));
do{
ret = read(newfd,buf,BUF_SIZ - 1);
} while(ret < 0 && EINTR == errno );
if(ret < 0)
{
perror("read");
exit(1);
}
if(!ret)
break;
printf("recv[%u]:[%s] data: %s\n",du,p,buf);
if(!strncasecmp(buf,"quit",strlen("quit")))
{
printf("exit \n");
break;
}
}
close(newfd);
close(fd);
return 0;
} // end of main
client.c (failed)
/***************************************************************
文件名 : lwipClientAPP.c
作者 : Skylar
描述 : 网口收发测试
其他 : failed(shell)
***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>
#include <arpa/inet.h>
#define TCP_PORT 5001
#define ADDR "192.168.1.138"
#define BUF_SIZ 128
int main(void)//(int argc,char **argv)
{
int fd = -1;
struct sockaddr_in serve_addr;
int ret = -1;
char buf[BUF_SIZ];
//创建套接字
if((fd = socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
perror("socket");
exit(1);
}
//链接服务器
bzero(&serve_addr,sizeof(serve_addr));
serve_addr.sin_family = AF_INET;
serve_addr.sin_port = htons(TCP_PORT);
//serve_addr.sin_addr.s_addr = inet_addr(ADDR);
// 将地址转换为二进制形式
if(inet_pton(AF_INET,ADDR,(void *)&serve_addr.sin_addr) != 1)
{
perror("pton");
exit(1);
}
if(connect(fd,(struct sockaddr *)&serve_addr,sizeof(serve_addr)) < 0)
{
perror("connect");
exit(1);
}
//读写数据
while(1)
{
bzero(buf,BUF_SIZ);
if(fgets(buf,BUF_SIZ - 1,stdin) == NULL)
{
continue;
}
if(!strncasecmp(buf,"quit",strlen("quit")))
{
printf("exit \n");
break;
}
write(fd,buf,strlen(buf));
}
close(fd);
//关闭套接字
} // end of main
Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析) - yxysuanfa - 博客园