LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   serial port programming using C (https://www.linuxquestions.org/questions/linux-newbie-8/serial-port-programming-using-c-901240/)

balaqemu 09-05-2011 10:33 AM

serial port programming using C
 
Hi,

I need to access the data from CC2530ZNP usb dongle to my application on linux PC ,


i'm using the following c code read the data print on console .

Below is the code which I use to read the data .

When I do it first time it works fine , when I close the program and re-run it again it wont, it opens the port well but it does not read anything , the read buffer is empty ..

If I restart my system it works again for the first time .. why it is unable to read the data in second time ..? I'm using ubuntu 11.04 ...pls help





#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyACM0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];

fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) {perror(MODEMDEVICE); exit(-1); }

tcgetattr(fd,&oldtio); /* save current port settings */

bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;

/* set input mode (non-canonical, no echo,...) */
newtio.c_lflag = 0;

newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 5; /* blocking read until 5 chars received */

tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);


while (STOP==FALSE) { /* loop for input */
res = read(fd,buf,255); /* returns after 5 chars have been input */
buf[res]=0; /* so we can printf... */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
tcsetattr(fd,TCSANOW,&oldtio);
}

tbrand 09-05-2011 10:16 PM

I'm sorry I cannot try to duplicate your problem since I don't have your hw and sw, so, this is no better than a guess:

Are you quite sure that the ``tcsetattr(fd,TCSANOW,&oldtio);'' is actually getting executed. Since you don't handle signals, if your program was stopping because of a signal the last call would not be executed. The behavior of your program is consistent with the settings of the serial driver not getting restored at the end of the run.

At least, print the return value of the last tcsetattr() call and maybe also errno.

rb. 09-05-2011 11:33 PM

Hi,

also use close(fd) on exit.


Code:

void finalize(void)
{
//...       
        tcsetattr(fd,TCSANOW,&oldtio);
// check for error
        if (fd) fclose(fd);

}

int main(int argc, char *argv[])
{
        atexit(finalize);
//...
        exit(0);
}


vortmax 09-06-2011 12:03 AM

Quote:

Originally Posted by rb. (Post 4462512)
Hi,

also use close(fd) on exit.


Code:

void finalize(void)
{
//...       
        tcsetattr(fd,TCSANOW,&oldtio);
// check for error
        if (fd) fclose(fd);

}

int main(int argc, char *argv[])
{
        atexit(finalize);
//...
        exit(0);
}


I've run into this issue more times that I can count, and it has nearly always been the port not being properly released. Adding fclose should clear it up.

balaqemu 09-06-2011 06:48 AM

Facing diffrent kind of problem
 
Hi,
I tried closing the fd but no success, and also checked I checked the return value of the last tcsetattr() it was one
so I have written bit better code to read the data and print

It works for some times and if remove the device and reconnect , it connect with out any error but it read nothing in the read buffer .

after trying many times(removing and connecting ) it works again , then if I remove it again it goes to the same state .

what may be the problem ...? why it reads nothing when I read ..? and also I tried in minicom , there also it gives same problem , it connects well and able to read if I remove the device and reconnect, it shows cant open dev/ttyACM0! .
I have attached my code for the reference



first file .

// adrserial.c - Serial Port Test Example


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "adrport.h"

// this is the mainline thingee
int main(int argc, char *argv[])
{
char sCmd;
char sResult[254];
if (argc < 2 || argc > 2)
{
printf("adrserial needs 1 parameter for the serial port\n");
printf(" ie. use 'adrserial 0' to connect to /dev/ttyS0\n");
return 0;
} // end if
printf("Type q to quit.\n\n");
if (OpenAdrPort(argv[1]) < 0) return 0;
while (1)
{
int iSpot;

if(kbhit())
getchar(sCmd);
if (sCmd == 'q' || sCmd == 'Q') { CloseAdrPort(); return 0;}

if (ReadAdrPort(sResult,254) > 0)
{
printf("****Response is %s\n", sResult);
} // end if
} // end while

CloseAdrPort();

} // end main



Second file

// adrport.c - Serial Port Handler


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include "adrport.h"
static int fd = 0;

// opens the serial port
// return code:
// > 0 = fd for the port
// -1 = open failed
int OpenAdrPort(char* sPortNumber)
{
char sPortName[64];
printf("in OpenAdrPort port#=%s\n", sPortNumber);
sprintf(sPortName, "/dev/ttyACM%s", sPortNumber);
printf("sPortName=%s\n", sPortName);

// make sure port is closed
CloseAdrPort(fd);
sleep(1);
fd = open(sPortName, O_RDWR | O_NOCTTY | O_NDELAY);
sleep(1);
CloseAdrPort(fd);
sleep(1);
fd = open(sPortName, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0)
{
printf("open error %d %s\n", errno, strerror(errno));
}
else
{
struct termios my_termios;
printf("fd is %d\n", fd);
tcgetattr(fd, &my_termios);
// NOTE: you may want to save the port attributes
// here so that you can restore them later
printf("old cflag=%08x\n", my_termios.c_cflag);
printf("old oflag=%08x\n", my_termios.c_oflag);
printf("old iflag=%08x\n", my_termios.c_iflag);
printf("old lflag=%08x\n", my_termios.c_lflag);
printf("old line=%02x\n", my_termios.c_line);

tcflush(fd, TCIFLUSH);

my_termios.c_cflag = B9600 | CS8 |CREAD | CLOCAL | HUPCL;

cfsetospeed(&my_termios, B9600);
tcsetattr(fd, TCSANOW, &my_termios);

printf("new cflag=%08x\n", my_termios.c_cflag);
printf("new oflag=%08x\n", my_termios.c_oflag);
printf("new iflag=%08x\n", my_termios.c_iflag);
printf("new lflag=%08x\n", my_termios.c_lflag);
printf("new line=%02x\n", my_termios.c_line);
} // end if
return fd;
} // end OpenAdrPort

// writes zero terminated string to the serial port
// return code:
// >= 0 = number of characters written
// -1 = write failed
int WriteAdrPort(char* psOutput)
{
int iOut;
if (fd < 1)
{
printf(" port is not open\n");
return -1;
} // end if
iOut = write(fd, psOutput, strlen(psOutput));
if (iOut < 0)
{
printf("write error %d %s\n", errno, strerror(errno));
}
else
{
printf("wrote %d chars: %s\n", iOut, psOutput);
} // end if
return iOut;
} // end WriteAdrPort

// read string from the serial port
// return code:
// >= 0 = number of characters read
// -1 = read failed
int ReadAdrPort(char* psResponse, int iMax)
{
int iIn;
printf("in ReadAdrPort iMax=%d\n", iMax);
if (fd < 1)
{
printf(" port is not open\n");
return -1;
} // end if
strncpy (psResponse, "N/A", iMax<4?iMax:4);
iIn = read(fd, psResponse, iMax-1);
printf(" chars: %s\n", psResponse);
if (iIn < 0)
{
if (errno == EAGAIN)
{
return 0; // assume that command generated no response
}
else
{
printf("read error %d %s\n", errno, strerror(errno));
} // end if
}
else
{
psResponse[iIn<iMax?iIn:iMax] = '\0';
// printf("read %d chars: %s\n", iIn, psResponse);
} // end if

return iIn;
} // end ReadAdrPort

// closes the serial port
void CloseAdrPort()
{
// you may want to restore the saved port attributes
if (fd > 0)
{
close(fd);
} // end if
} // end CloseAdrPort


All times are GMT -5. The time now is 02:44 AM.