LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 09-05-2011, 10:33 AM   #1
balaqemu
LQ Newbie
 
Registered: Aug 2011
Posts: 19

Rep: Reputation: Disabled
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);
}
 
Old 09-05-2011, 10:16 PM   #2
tbrand
Member
 
Registered: Jul 2006
Location: Toronto, Canada
Distribution: gentoo
Posts: 33

Rep: Reputation: 17
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.
 
Old 09-05-2011, 11:33 PM   #3
rb.
LQ Newbie
 
Registered: Jan 2010
Posts: 2

Rep: Reputation: 0
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);
}
 
Old 09-06-2011, 12:03 AM   #4
vortmax
Member
 
Registered: Nov 2005
Posts: 91

Rep: Reputation: 17
Quote:
Originally Posted by rb. View Post
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.
 
Old 09-06-2011, 06:48 AM   #5
balaqemu
LQ Newbie
 
Registered: Aug 2011
Posts: 19

Original Poster
Rep: Reputation: Disabled
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
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
serial port programming help PARIHAR Linux - Newbie 5 04-19-2010 06:20 AM
serial port programming sundaresh Programming 6 07-19-2007 08:32 AM
Problem of serial port programming fingerling54 Linux - Software 4 05-18-2005 03:22 PM
serial port programming!!! novice_din Programming 4 02-03-2005 08:50 PM
Programming the Serial Port karans Linux - Networking 2 11-03-2003 01:54 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 04:46 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration