嵌入式串口和网络编程实验报告_arm串口通信实验报告
嵌入式串口和网络编程实验报告由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“arm串口通信实验报告”。
嵌入式实验报告
题目:linux
串口和网络编程
一、实验目的:
1、强化本学期所学的相关的内容。
2、掌握串口相关设置。
3、强化基于TCP网络传输的三次握手。
4、自学Linux线程的使用。
二、实验内容:
本试验基于server和client的透明传输来实现类似于QQ的聊天功能。
三、实验过程:
1、linux开发环境的建立
2、嵌入式linux系统的搭建
1>BootLoader的移植
2>linux系统的裁剪与移植 Linux内核裁剪
./make_image生成自己的uImage2638
上电验证:
3>根文件系统的移植 修改hostname为:whmtt
./mkcramfsdisk_new 生成rootfs_new.cramfs
大小从老师给的40000到37b00(因为有的没有用到,大小变小了):
上电验证:
3、客服端编程client.c 相关代码: #include #include #include #include #include #include #include #include
#define SERVER_PORT 20000 //设置服务端口
#define CLIENT_PORT((20001+rand())%65536)//设置客户端端口(随机)#define BUFFER_SIZE 256 #define LENGTH_OF_LISTEN_QUEUE 10 //可窃听队列长为10 #define WELCOME_MESSAGE “welcome to connect the server.”
void usage(char* name){ printf(“usage: %s IpAddrn ” ,name);}
struct sockaddr_in servaddr,cliaddr;int servfd,clifd,length=0;struct sockaddr_in servaddr,cliaddr;socklen_t socklen=sizeof(servaddr);char buf[BUFFER_SIZE],buf2[BUFFER_SIZE];pthread_t tidp,tidp2;int pth;int runflag=0;
void *Thread1(void *arg)/*等待runflag为1,当为1时清空buf,同时接收来自server的数据并输出。
但当没有清空,则break.*/ { while(runflag){
memset(buf,0,BUFFER_SIZE);
length=recv(clifd,buf,BUFFER_SIZE,0);
if(strstr(buf,“$”)>0){runflag=0;printf(“stop!n”);break;}
if(length>0)printf(“from server:%s”,buf);
} }
void *Thread2(void *arg)/*等待发送数据给Server*/ { printf(“Please input your words to Server:--$ to stopn”);while(runflag){
memset(buf2,0,BUFFER_SIZE);
scanf(“%s”,buf2);
send(clifd,buf2,strlen(buf2),0);
if(strstr(buf2,“$”)>0){runflag=0;printf(“stop!n”);break;}
} }
int main(int argc, char** argv){ if(argc
usage(argv[0]);
exit(1);} if((clifd = socket(AF_INET,SOCK_STREAM,0))
printf(“ create socket error!n ”);
exit(1);}
srand(time(NULL));// initialize random generator
bzero(& cliaddr, sizeof(cliaddr));cliaddr.sin_family = AF_INET;cliaddr.sin_port = htons(CLIENT_PORT);cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
if(bind(clifd,(struct sockaddr*)&cliaddr,sizeof(cliaddr))
printf(“bind to port %d failure!n ” ,CLIENT_PORT);
exit(1);}//绑定的目的是让其端口是随机的,否则端口是自增1 //一般情况下client端不用绑定
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;inet_aton(argv[1], &servaddr.sin_addr);servaddr.sin_port = htons(SERVER_PORT);
if(connect(clifd,(struct sockaddr *)&servaddr, socklen)
printf(“can't connect to %s!n”, argv[1]);
exit(1);}
runflag=1;
pth=pthread_create(&tidp,NULL,Thread1,NULL);
if(pth!=0){printf(“error!”);return-1;}
pth=pthread_create(&tidp2,NULL,Thread2,NULL);
if(pth!=0){printf(“error!”);return-1;}
pthread_detach(tidp);
pthread_detach(tidp2);
while(runflag){;}
close(clifd);
return 0;}
4、服务端server.c编写
相关代码: #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
#define COM0 0 #define BLOCK_MODE 1 #define NONBLK_MODE 0 #define SERVER_PORT 20000 #define LENGTH_OF_LISTEN_QUEUE 10 #define QUEUE 20 #define BUFFER_SIZE 256 #define WELCOME_MESSAGE “welcome to connect the server.”
static struct termios g_newtio,g_oldtio;
static int speed_arr[] = { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
static int name_arr[] = { 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, };
int Init_COM(int Comm,int Baudrate,int Parity,int Stopbit,int Flagblock){ int ret,i;char dev_buf[16];
if(Comm > 3){
printf(“Com%d not existn”,Comm);
return-1;}
memset(dev_buf,0x00,sizeof(dev_buf));sprintf(dev_buf,“/dev/ttyS%d”,Comm);
if(Flagblock){
ret = open(dev_buf, O_RDWR | O_NOCTTY);//以默认阻塞方式打开
} else {
ret = open(dev_buf, O_RDWR | O_NOCTTY | O_NONBLOCK);//以非阻塞方式打开
}
if(ret
printf(“Open ttyS%d failedn”,Comm);
return-1;
}
if(tcgetattr(ret, &g_oldtio)
{
printf(“Get Com Parameter Error.n”);
return-1;}
for(i= 0;i
if(Baudrate == name_arr[i])
{
cfsetispeed(&g_newtio,speed_arr[i]);/*设置输入输出波特率*/
cfsetospeed(&g_newtio,speed_arr[i]);
break;
} }
if(i>=sizeof(speed_arr)/ sizeof(int)){
printf(“Unsupported Speed!n”);
return-1;}
switch(Parity){
case 'n':
case 'N':
g_newtio.c_cflag &= ~PARODD;
g_newtio.c_cflag &= ~PARENB;
break;
case 'o':
case 'O':
g_newtio.c_cflag |= PARENB;
g_newtio.c_cflag |= PARODD;//奇校验
break;
case 'e':
case 'E':
g_newtio.c_cflag |= PARENB;//偶校验
g_newtio.c_cflag &= ~PARODD;
break;
default:
printf(“Unsupported Parityn”);
return-1;}
switch(Stopbit)//设置停止校验位是为2,否为1.{
case 1:
g_newtio.c_cflag &= ~CSTOPB;
break;
case 2:
g_newtio.c_cflag |= CSTOPB;
break;
default:
printf(“Unsupported Stopbit!n”);
return-1;} g_newtio.c_iflag = 0;g_newtio.c_oflag = 0;g_newtio.c_lflag = 0;
g_newtio.c_cc[VTIME] = 1;//最大等待时间为1*100ms g_newtio.c_cc[VMIN] = 1;//最小读数为1
g_newtio.c_iflag &= ~INPCK;g_newtio.c_cflag &= ~CRTSCTS;g_newtio.c_cflag &= ~CSIZE;//设置数据位
g_newtio.c_cflag |= CS8;// g_newtio.c_cflag |= CLOCAL;g_newtio.c_cflag |= CREAD;
if(tcsetattr(ret, TCSANOW, &g_newtio)!= 0)//激活设置
{
printf(“Set Com Parameter Error!n”);
return-1;}
tcflush(ret, TCIOFLUSH);//刷新输入输出缓存
return ret;}
//以上为套接字的相关定义
//一下类似与client一样设置数据接收和发送。
void RestoreComConfiguration(int fd,struct termios *ptios){ if(tcsetattr(fd, TCSANOW, ptios)!= 0){
printf(“Restore Com Parameter Error!n”);} }
int fd;char buf[1024],buf2[1024];int servfd,clifd;
struct sockaddr_in servaddr,cliaddr;int runflag=0;
void *Thread1(void *arg){ printf(“Please input your words to Server:--$ to stopn”);while(runflag){
memset(buf,0,BUFFER_SIZE);
read(fd,buf,1024);
send(clifd,buf,strlen(buf),0);
if(strstr(buf,“$”)>0){runflag=0;printf(“stop!n”);break;}
} }
void *Thread2(void *arg){ int length=0;while(runflag){char stdstr[1024]=“from client:”;
memset(buf2,0,BUFFER_SIZE);
length=recv(clifd,buf2,1024,0);if(length>0){
strcat(stdstr,buf2);strcat(stdstr,“n”);
if(strstr(buf2,“$”)>0)
{runflag=0;printf(“stop!n”);break;}
write(fd,stdstr,strlen(stdstr));
}
}
} void socket_init(void){ if((servfd=socket(AF_INET,SOCK_STREAM,0))= 0)RestoreComConfiguration(fd,&g_oldtio);
runflag=1;
pth=pthread_create(&tidp,NULL,Thread1,NULL);
if(pth!=0){printf(“error!”);return-1;}
pth=pthread_create(&tidp2,NULL,Thread2,NULL);
if(pth!=0){printf(“error!”);return-1;}
pthread_detach(tidp);
pthread_detach(tidp2);
while(runflag){;}
close(clifd);close(fd);close(servfd);//全部关闭
return 0;} 编译结果:
5、nfs挂载
四、实验结果:
五、心得体会: