I have problem with C programming. I want to send & receive data through serial communication. I send data(command) to device to get data from device but when receive data, it can't get altogether of data.
It get only some data. What should I do to get altogether of data?
If all of you have the solution. Please advice me.
Many thanks.
Could you explain the problem in more detail? What are you sending to? What are you sending? What are you receiving? What should you be receiving?
If your problem is regarding text data means the following may be the problem,
- It may be the buffer problem.You need to flush the buffers like stdin,stdout after sending and receiving the data.
2 .You should have the buffer size which is enough to hold your data.For example ,if you are getting the input data in a variable called buf[100].So your data should have the maximum 100 characters which includes the null character to terminate the string .
Thanks for all solution.
I'll explain in detail , I want to send & receive data in serial communication like minicom in Linux. Now I sent '\r' to the device. It should send data back to the program like
Login Failed.
Employee No.?
but it can receive only
Faild
ployNo.
My source is
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <errno.h>
#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
void signal_handler_IO (int status); /* definition of signal handler */
int wait_flag=TRUE; /* TRUE while no signal received */
char buf[255];
char new_buf[255];
int fd;
main()
{
int c, res,i;
struct termios oldtio,newtio;
struct sigaction saio; /* definition of signal action */
close(fd); //make sure that port is closed
/* open the device to be non-blocking (read will return immediatly) */
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd <0) {perror(MODEMDEVICE); exit(-1); }
/* install the signal handler before making the device asynchronous */
saio.sa_handler = signal_handler_IO;
sigemptyset(&saio.sa_mask);//saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
/* allow the process to receive SIGIO */
fcntl(fd, F_SETOWN, getpid());
/* Make the file descriptor asynchronous (the manual page says only
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd,&oldtio); /* save current port settings */
/* set new port settings for canonical input processing */
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
write(fd, "\r", 1);
sleep(1);
int count=0;
/* loop while waiting for input. normally we would do something
useful here */
while (STOP==FALSE) {
//sleep(3);
/* after receiving SIGIO, wait_flag = FALSE, input is available
and can be read */
if (wait_flag==FALSE) {
sleep(3);
res = read(fd,buf,255);
//printf("res = %d\n", res);
if(res > 1)
printf("%s",buf);
buf[res]='\0';
else if(res < 1)
STOP = TRUE;
wait_flag = TRUE; /* wait for new input */
}
}
/* restore old port settings */
tcsetattr(fd,TCSANOW,&oldtio);
}
/***************************************************************************
* signal handler. sets wait_flag to FALSE, to indicate above loop that *
* characters have been received. *
***************************************************************************/
void signal_handler_IO (int status)
{
int i=0;
//printf("fd = %d\n",fd);
printf("received SIGIO signal.\n");
wait_flag = FALSE;
}
What do I wrong with this source code.
Please advice, thanks.
Why are you null-terminating the buffer after you print it? You're closing the barn, but the horse's already left.
Never call printf from a signal handler. fprintf(stderr, "stuff"); might work since that's unbuffered but even that is not guaranteed. Use write(), along with sprintf if necessary.
Are you sure the device uses hardware flow control?
wait_flag should be volatile.
If your goal is to just wait for I/O, you don't need to use SIGIO, you can just configure your terminal to make you wait when you do a read(). This would be better IMHO, since under some circumstances signals can be missed. You could also use select().
code tags for code please. [ code ] my fancy program [ /code ] but without the spaces in the tags. This will show your code with proper indenting.
Could you edit my code ?
Could you please use code tags?
For the sake of completeness, it's a bad idea to call fprintf() in a signal handler if the interrupted code also calls fprintf() on the same stream.
Indeed, fprintf() may uses mutex to lock the stream. If it occurs that the signal interrupts fprintf() after it locked the mutex, and fprintf() is called in the signal handler. Well, it's game over: fprintf() shall try to grab again the mutex, and on many implementation this results a deadlock.
Lo�c.