Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

Problem with uart and ethernet communication

I have same problem with uart communication.

I want receive data from ethernet and send to UART and vice versa.

UART to Ethernet is OK, but Ethernet to UART is not OK.

# define NETWORK_PORT 5000# define BUFFER_SIZE 32

# define true 1# define false 0

static char data_buffer[BUFFER_SIZE];

void DieWithError(const char *msg)

{

perror(msg);

exit(1);

}

int open_socket(void)

{

int listen_fd;

int incoming_fd;

struct sockaddr_in my_addr;

struct sockaddr_in other_addr;

//socklen_t other_addr_len;

int other_addr_len;

int yes = 1;

// create socket.

listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if(listen_fd == -1)

DieWithError("socket");

if(setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {

DieWithError("setsockopt SO_REUSEADDR");

}

if(setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int)) == -1) {

DieWithError("setsockopt SO_KEEPALIVE");

}

my_addr.sin_family = AF_INET;

my_addr.sin_port = htons(NETWORK_PORT);

my_addr.sin_addr.s_addr = INADDR_ANY;

memset(my_addr.sin_zero, '\0', sizeof(my_addr.sin_zero));

if(bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)

DieWithError("bind socket");

printf("Listening on %s, port %d.\n", inet_ntoa(my_addr.sin_addr), ntohs(my_addr.sin_port));

// listen

if(listen(listen_fd, 1) == -1)

DieWithError("listen socket");

// accept connection.

other_addr_len = sizeof(struct sockaddr_in);

if((incoming_fd = accept(listen_fd, (struct sockaddr *)&other_addr, &other_addr_len)) == -1)

DieWithError("accept socket");

// close socket.

if(close(listen_fd) == -1)

DieWithError("close old socket");

printf("New connection from %s, port %d.\n", inet_ntoa(other_addr.sin_addr), ntohs(other_addr.sin_port));

return incoming_fd;

}

// close socket

void close_socket(int fd)

{

if(close(fd) == -1)

DieWithError("close socket");

}

// open uart.

int open_serialport(void)

{

int fd;

// open uart.

fd = open("/dev/uart", O_RDWR | O_NOCTTY | O_SYNC);

if(fd == -1)

DieWithError("open serialport");

return fd;

}

// close serialport

void close_serialport(int fd)

{

if(close(fd) == -1)

DieWithError("close serialport");

}

int fromuartTask(void)

{

int network_fd;

int serial_fd;

fd_set read_fds;

struct timeval tv;

int tmp;

// open uart and network connection

serial_fd = open_serialport();

network_fd = open_socket();

while(1)

{

FD_ZERO(&read_fds);

FD_SET(network_fd, &read_fds);

FD_SET(serial_fd, &read_fds);

tv.tv_sec = 0;

tv.tv_usec = 0;

// wait.

if(network_fd > serial_fd)

tmp = network_fd;

else

tmp = serial_fd;

if(select(tmp + 1, &read_fds, NULL, NULL, &tv) == -1)

DieWithError("select");

// Ethernet data ??

if(FD_ISSET(network_fd, &read_fds))

{

// recv from ethernet.

printf("wait for network data.\n");

tmp = recv(network_fd, data_buffer, BUFFER_SIZE, 0);

if(tmp == -1)

DieWithError("recv");

if(tmp == 0)

break;

// write to uart.

if(write(serial_fd, data_buffer, tmp) == -1)

DieWithError("write");

printf("Got network data.\n");

}

// Data from UART??

if(FD_ISSET(serial_fd, &read_fds))

{

// read from uart.

printf("waiting for serial data.\n");

tmp = read(serial_fd, data_buffer, BUFFER_SIZE);

if(tmp == -1)

DieWithError("read");

// send to ethernet.

if(send(network_fd, data_buffer, tmp, 0) == -1)

DieWithError("send");

printf("Got serial data.\n");

}

}

// close socket and serial port

close_socket(network_fd);

close_serialport(serial_fd);

return 0;

}

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It was a long time age that I tried, but IIRC the select() call doesn't work well with the Interniche stack. It only detects incoming data on one of the sockets, but not both.

    This was a long time ago (with Quartus 7.2 I think) so it may have been fixed since then. Otherwise you could try to use two threads to read data on each socket.