Linux: open Serial port, send array of bytes

Hi

I am trying to (a) open a serial port, and then (b) write a stream of bytes to it and read any responses from the serial port. I have some code so far (will post below) but what I really want to know is, am I on the right track. There seem to be lots of posts on lots of forums about serial programming, but very little in the way of simple examples that actually work. What method should I use to open the port? What method should I use to write bytes to the serial port? What method do I use to read a response from the port?

This code doesn't actually work yet, and I am not sure if its even opening the port properly since I can still open the port in cutecom when this is running.

Thanks!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * Main.cpp
 *
 *  Created on: 9-Jan-2009
 *      Author: root
 */


/////////////////////////////////////////////////
// Serial port interface program               //
/////////////////////////////////////////////////

#include <stdio.h> // standard input / output functions
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitionss
#include <time.h>   // time calls


int open_port(void)
{
	int fd; // file description for the serial port
	
	fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
	
	if(fd == -1) // if open is unsucessful
	{
		//perror("open_port: Unable to open /dev/ttyS0 - ");
		printf("open_port: Unable to open /dev/ttyS0. \n");
	}
	else
	{
		fcntl(fd, F_SETFL, 0);
		printf("port is open.\n");
	}
	
	return(fd);
} //open_port

int configure_port(int fd)      // configure the port
{
	struct termios port_settings;      // structure to store the port settings in

	cfsetispeed(&port_settings, B115200);    // set baud rates
	cfsetospeed(&port_settings, B115200);

	port_settings.c_cflag &= ~PARENB;    // set no parity, stop bits, data bits
	port_settings.c_cflag &= ~CSTOPB;
	port_settings.c_cflag &= ~CSIZE;
	port_settings.c_cflag |= CS8;
	
	tcsetattr(fd, TCSANOW, &port_settings);    // apply the settings to the port
	return(fd);

} //configure_port

int query_modem(int fd)   // query modem with an AT command
{
	char n;
	fd_set rdfs;
	struct timeval timeout;
	
	// initialise the timeout structure
	timeout.tv_sec = 10; // ten second timeout
	timeout.tv_usec = 0;
	
	//Create byte array
	unsigned char send_bytes[] = { 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x01, 0x21, 0x03};
	
	
	write(fd, send_bytes, 13);  //Send data
	printf("Wrote the bytes. \n");
	
	// do the select
	n = select(fd + 1, &rdfs, NULL, NULL, &timeout);
	
	// check if an error has occured
	if(n < 0)
	{
	 perror("select failed\n");
	}
	else if (n == 0)
	{
	 puts("Timeout!");
	}
	else
	{
	 printf("\nBytes detected on the port!\n");
	}

	return 0;
	
} //query_modem

int main(void)
{ 
	int fd = open_port();
	configure_port(fd);
	query_modem(fd);
	
	return(0);
	
} //main
This code looks reasonable to me... though I haven't looked at your termios settings. open(), read(), write(), close() can be used on serial ports. If open() is returning >= 0 and /dev/ttyS0 points to a real serial port, then the port is open.
I'm in no way an expert Linux programming, but don't you need root privileges to open/write the files in the /dev directory? - I remember having
problems doing a usb prog and had to log on as root to get the prog to
run properly.
jsmith:
Yes, I get the message that the port is open. Shouldn't it be locked somehow?

guestgulkan:
I am running this as root (actually as root from eclipse CDT).
Is there a better way to do this? Is there a way to have a function/method listening for inbound data from the serial port connection rather than calling the read function?
I think all you missed was to populate your file descriptor set by using FD_SET (int filedes, fd_set *set). You would need to do something like this before calling the select() function:
FD_ZERO( &rfds );
FD_SET( fd, &rfds );
Hope this helps.
Topic archived. No new replies allowed.