---------------------------------------------------------------------------------
系统环境:Centos 6.5
开发板:s3c2440
---------------------------------------------------------------------------------
1、程序功能
该程序是一个运行在开发板上的client程序,连接到windows下usr-tcp调试工具模拟的server,接受串口和socket数据并转发
usr-tcp通过tcp服务器向client发送数据,client接受到数据后通过串口发回usr-tcp
usr-tcp通过串口向client发送数据,client接收到数据后通过socket发回usr-tcp
2、源代码
串口相关设置 serial.c
/*********************************************************************************
* Copyright: (C) 2016 Lu Zengmeng<[email protected]>
* All rights reserved.
*
* Filename: serial.c
* Description: This file
*
* Version: 1.0.0(08/01/2016)
* Author: Lu Zengmeng <[email protected]>
* ChangeLog: 1, Release initial version on "08/01/2016 06:44:59 PM"
*
********************************************************************************/
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#define FAIL -1
#define OK 0
int speed_arr[] = {B115200,B57600,B38400,B19200,B9600,B4800,B2400,B1200,B600,B300,B110};
int name_arr[] = { 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 600, 300, 110};
/* set baud rate */
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios options;
tcgetattr(fd, &options);
options.c_iflag &= ~ (INLCR | ICRNL | IGNCR);
options.c_oflag &= ~(ONLCR | OCRNL);
options.c_iflag &= ~(IXON);
for( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if(speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);/*empty input cache*/
cfsetispeed(&options, speed_arr[i]);
cfsetospeed(&options, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &options);
if(status != 0)
perror("tcsetattr fd");
return;
}
tcflush(fd,TCIOFLUSH);/*empty input cache*/
}
}
/**
* *@brief 设置串口数据位,停止位和效验位
* *@param fd 类型 int 打开的串口文件描述符
* *@param databits 类型 int 数据位 取值 为 7 或者8
* *@param stopbits 类型 int 停止位 取值为 1 或者2
* *@param parity 类型 int 效验类型 取值为N,E,O,S
* */
int set_parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FAIL);
}
options.c_cflag &= ~CSIZE;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
switch (databits) /*set datebits*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FAIL);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FAIL);
}
/*set stopbits */
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FAIL);
}
/* Set input parity options */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 0; // 15 seconds
options.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH); /* Update the optionsions and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("tcsetattr");
return FAIL;
}
return (OK);
}
/**
* *@breif open device
* */
int open_dev(char *dev)
{
int fd;
fd = open( dev, O_RDWR|O_NOCTTY|O_NDELAY);
if (fd < 0)
{
perror("open");
return FAIL;
}
else
return fd;
}
serial.h
/********************************************************************************
* Copyright: (C) 2016 Lu Zengmeng<[email protected]>
* All rights reserved.
*
* Filename: serial.h
* Description: This head file
*
* Version: 1.0.0(08/01/2016)
* Author: Lu Zengmeng <[email protected]>
* ChangeLog: 1, Release initial version on "08/01/2016 06:44:25 PM"
*
********************************************************************************/
#include <stdio.h>
#ifndef __SERIAL_H__
#define __SERIAL_H__
extern int speed_arr[];
extern int name_arr[];
extern void set_speed(int fd, int speed);
extern int set_parity(int fd,int databits,int stopbits,int parity);
extern int open_dev(char *dev);
#endif
socket初始化连接 tcp.c
/*********************************************************************************
* Copyright: (C) 2016 Lu Zengmeng<[email protected]>
* All rights reserved.
*
* Filename: tcp.c
* Description: This file
*
* Version: 1.0.0(08/02/2016)
* Author: Lu Zengmeng <[email protected]>
* ChangeLog: 1, Release initial version on "08/02/2016 08:09:55 AM"
*
********************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "tcp.h"
/**************************************************************************************
* Description:
* Input Args:
* Output Args:
* Return Value:
*************************************************************************************/
int socket_init(void)
{
int fd;
struct sockaddr_in serv_addr;
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if ((inet_pton(AF_INET,IPADDR,&serv_addr.sin_addr)) < 0)
{
perror("inet_pton");
exit(1);
}
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
perror("socket");
exit(1);
}
if (-1 == connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)))
{
perror("connect");
exit(1);
}
printf("connect sucesseful\n");
return fd;
}
/* ----- End of socket_init() ----- */
tcp.h
/********************************************************************************
* Copyright: (C) 2016 Lu Zengmeng<[email protected]>
* All rights reserved.
*
* Filename: tcp.h
* Description: This head file
*
* Version: 1.0.0(08/02/2016)
* Author: Lu Zengmeng <[email protected]>
* ChangeLog: 1, Release initial version on "08/02/2016 08:22:06 AM"
*
********************************************************************************/
#include <stdio.h>
#ifndef __TCP_H_
#define __TCP_H_
#define PORT 8003
#define IPADDR "192.168.1.104"
extern int socket_init(void);
#endif
main.c
/*********************************************************************************
* Copyright: (C) 2016 Lu Zengmeng<[email protected]>
* All rights reserved.
*
* Filename: main.c
* Description: This file
*
* Version: 1.0.0(08/01/2016)
* Author: Lu Zengmeng <[email protected]>
* ChangeLog: 1, Release initial version on "08/01/2016 06:45:37 PM"
*
********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <pthread.h>
#include "serial.h"
#include "tcp.h"
#define DEVICE "/dev/ttyS1"
#define BUF_SIZE 128
int usrt_fd;
int sock_fd;
void usrt_to_socket (void);
void socket_to_usrt (void);
/* start main */
int main(int argc,char **argv)
{
int ret;
char *dev = DEVICE;
pthread_t sock,usrt;
sock_fd = socket_init();
usrt_fd = open_dev(dev);
set_parity(usrt_fd,8,1,'N'); // 设置串口数据位、停止位、校验位
set_speed(usrt_fd,9600); // 设置串口波特率
ret = pthread_create(&sock,NULL,(void *)socket_to_usrt,NULL); // 创建sock线程接收socket数据
if(ret < 0)
{
perror("phread_create");
exit(1);
}
ret = pthread_create(&usrt,NULL,(void *)usrt_to_socket,NULL); // 创建usrt线程接收串口数据
if(ret < 0)
{
perror("phread_create");
exit(1);
}
pthread_join(sock,NULL); // 等待线程退出
pthread_join(usrt,NULL);
close(sock_fd);
close(usrt_fd);
printf("main exit...\n");
return 0;
}
/**************************************************************************************
* Description:接收socket数据并通过串口转发
* Input Args:
* Output Args:
* Return Value:
*************************************************************************************/
void socket_to_usrt (void)
{
printf("start socket_to_usrt...\n");
int n = 0;
int m = 0;
char buf[BUF_SIZE];
while(1)
{
memset(buf,0,BUF_SIZE);
n = read(sock_fd,buf,BUF_SIZE);
if(n>0)
{
if(0==strncmp(buf,"exit",4)) // 收到exit时,线程退出
{
m = write(usrt_fd,buf,BUF_SIZE);
if(m<0)
{
perror("write to usrt");
}
break;
}
m = write(usrt_fd,buf,BUF_SIZE);
if(m<0)
{
perror("write to usrt");
}
}
else if(n<0)
{
perror("read from socket");
}
}
printf("socket_to_usrt exit...\n");
pthread_exit(0);
} /* ----- End of sock_to_usrt() ----- */
/**************************************************************************************
* Description:接收串口数据并通过socket转发
* Input Args:
* Output Args:
* Return Value:
*************************************************************************************/
void usrt_to_socket (void)
{
printf("start usrt_to_socket...\n");
int n = 0;
int m = 0;
char buf[BUF_SIZE];
while(1)
{
memset(buf,0,BUF_SIZE);
n = read(usrt_fd,buf,BUF_SIZE);
if(n>0)
{
if(0==strncmp(buf,"exit",4)) // 收到exit时,线程退出
{
m = write(sock_fd,buf,BUF_SIZE);
if(m<0)
{
perror("write to sock");
}
break;
}
m = write(sock_fd,buf,BUF_SIZE);
if(m<0)
{
perror("write to sock");
}
}
else if(n<0)
{
perror("read from usrt");
}
}
printf("usrt_to_socket exit...\n");
pthread_exit(0);
} /* ----- End of usrt_to_sock() ----- */
makefile
NAME=client
CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
EXTRA_CFLAGS+= -Wall -Werror
EXTRA_CFLAGS+= -lpthread
all:
$(CC) $(EXTRA_CFLAGS) main.c serial.c tcp.c -o $(NAME)
cp $(NAME) /tftp
3、调试助手下载