Serial port communication in C on Linux platform

K

Thread Starter

Kirti

Hello friends,
I am working on Redhat Linux 9.0 & want to establish the communication between microcontroller connected to the serial port and the PC Could someone send me some examples of source code in 'C' Actually I understood the commands tcsetattr and tcgetattr but after that i want to send the character to the MCU through the port. How to do that???. Please help me!
Kirti
 
R

Rokicki, Andrew

Since you understand tcsetattr and tcgetattr you know how to set serial port parameters.

Here is some code to read and write to the port. It is just a file so you can read/write to it as such.

char *sCompPort="/dev/ttyS0";
unsigned char c ;

open(sComPort,O_RDWR | O_NOCTTY);
write(fdComPort,&c,1);
read(fdComPort,&c,1);
close(fdComPort);


You need to put in you error checking, This code is just a quick example and has not been tested, so use it at your
own risk.

Andy R.
Somewhere at: 41 -72
 
J
I'm working on a Linux based Allen Bradley DF1 library that does similar terminal I/O functions. Send me your email address and I'll send you some code.

jvalenzuela <at> dspfl <dot> com
 
C

Curt Wuollet

<p>Here's a hack I did to communicate with a UPS
Short, but shows the general idea. Remember this is a hack. I believe it worked, but don't represent it as good form.

<p>There seems to be enough interest to risk being shredded for every minute detail by our members. The gist is that once you get the port set up, it's just a file like everything else in nixville.
<pre>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#define TC0 "/dev/ttyS0" /* Set to _your_ port */

static struct termios pots;
int pfda;

/* restore original terminal settings on exit */

void cleanup_termios(int signal)
{
tcsetattr(pfda, TCSANOW, &pots);
exit(0);
}

void send()
{
int i;
char cmd[30];
sprintf(cmd," 123 2026 2021 7411 125 ");

write(pfda,&cmd,strlen(cmd));
sleep(1);
}

int main(int argc, char *argv[]) {
struct termios pts; /* termios settings on port */
struct sigaction sact;/* used to initialize the signal handler */
char key;

/* Section to configure TC0 port */

pfda = open( TC0, O_RDWR);
if (pfda < 0)
{
perror("problem opening TC0 port");
exit(2);
}
/* modify the port configuration */
tcgetattr(pfda, &pts);
pots = pts;
pts.c_lflag &= ~ICANON;
pts.c_lflag &= ~(ECHO | ECHOCTL | ECHONL);
pts.c_cflag |= HUPCL;
pts.c_cflag &= ~PARENB;
pts.c_cflag &= ~PARODD;
pts.c_cc[VMIN] = 1;
pts.c_cc[VTIME] = 0;
pts.c_oflag &= ~ONLCR;
pts.c_iflag &= ~ICRNL;

cfsetospeed(&pts, B9600); /* All this sets the port to UPS defaults */

/* set the signal handler to restore the old
termios handler */
sact.sa_handler = cleanup_termios;
sigaction(SIGHUP, &sact, NULL);
sigaction(SIGINT, &sact, NULL);
sigaction(SIGPIPE, &sact, NULL);
sigaction(SIGTERM, &sact, NULL);

tcsetattr(pfda, TCSANOW, &pts);

send();

tcsetattr(pfda, TCSANOW, &pots);
exit(0);
}
</pre>

<p>Regards

<p>cww
 
B

Brian Lebiednik

<p>Likewise I have a hack that I would like someone to take a look at. I am pretty sure that it works for the most basic configuration of a serial port. I would really like to get some feedback on it so that I can improve it for use. It really doesnt matter what it sends right now as long as the other side recieves the message.

<p>Take a look:
<pre>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main (void)
{
int iOut = 0;
int fd = 0;
char *sCompPort="/dev/tty32";
char cmd[30];
sprintf(cmd,"9:30:30");
/* initializes the variables that we will use for connectivity */
/* to the serial port */

fd = open(sComPort, O_RDWR | O_NOCTTY);
/* opens port 32 for usage */

if (fd >0)
then
{
printf("port open.");
iOut = write(fd, cmd, strlen(cmd));
/* writes our cmd string to the designated port */

}
otherwise
{
printf("Unable to open port.");
/* lets us know that the port is not open */

}
if (iOut > 0)
{
printf("No commmunication.");
}
else
{
printf("communication sent.");
}
/* lets us know if the string was sent successfully */

return (0);
}
</pre>
<p>Like I said very basic. I just got into this type of C programming and I cannot find anything in the books that I was using before. Thank you for your time.

<p>BL
 
C

Curt Wuollet

Hi Brian

Most of the diffs are to handle things that you really do want to do in real world Linux apps. For example, you do want to set the baud rate, in case the last app wasn't written to be polite. And it's a good idea to catch signals so you don't leave the port in some unknown state on exit. Exclusive opens are a good idea for the real world as is the creating of a lock file in the conventional location. To paraphrase Einstein, "Linux programs shouls be made as simple as possible, but no simpler".

There are many good references on Linux serial comms. The Linux Documentation Project on ibiblio.org has some free ones. Almost any UNIX text will be close. One book I can recommend is "Linux Application Development" by Troan and Johnson. I believe, I don't have my copy nearby. I have an old Unix Programmer's Bible that is useful for general concepts. And, by all means, read the source of programs that do what you want to do in yours. It's there for that purpose and a great way to stand on the shoulders of those
who figured all this out already. Since this is pretty much cookbook stuff, feel free to "steal" code that works already.

Feel free to ask any questions you may have. There are a lot of Linux coders lurking.

Regards

cww
 
Top