Sh4wn
9th May 2011, 11:11 AM
Hi guys,
I'm trying to open the serial port with in a C program, but unfortunately it doesn't work.
Here's my code:
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* main.c
* Copyright (C) Lucas van Dijk 2011 <info@return1.net>
*
* voltmeter is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* voltmeter is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
/**
* Opens serial port on given location
*
* Sets the filedescriptor to block when no data is available
*
* @param port String with the location of the port (/dev/ttyS0 for example)
* @return file descriptor of the port
*/
int init_serial(char * port)
{
int fd;
printf("Before open");
fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd != -1)
{
printf("Before options");
fcntl(fd, F_SETFL, 0);
// Get options
struct termios options;
tcgetattr(fd, &options);
// Set up serial
// 9600-8-E-1
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_cflag &= ~CSTOPB;
tcsetattr(fd, TCSANOW, &options);
}
return fd;
}
/**
* Send request to our measurement device to start a new measurement
*
* @param fd File descriptor
*/
int send_request(int fd)
{
if(fd == -1)
{
return -1;
}
printf("Sending request..\n");
return write(fd, "r", 1);
}
/**
* Main entry point of the application
*/
int main(int argc, char * argv[])
{
printf("Hallo\n");
if(argc < 2)
{
// No port given, print error
printf("Please specify which serial port to use.\n");
printf("\tUsage: %s serial_port\n", argv[0]);
return 1;
}
printf("Open serial: %s\n", argv[1]);
int fd = 0;
fd = init_serial(argv[1]);
if(fd == -1)
{
printf("Could not open serial port\n");
return 1;
}
int i = 0;
time_t last_request = 0;
time_t current_time;
while(1)
{
time(¤t_time);
if(current_time + 5 < last_request)
{
send_request(fd);
char buffer[5];
// Read Response
read(fd, buffer, 4);
printf("Measurement #%d: %s", i, buffer);
i++;
time(&last_request);
}
}
close(fd);
return 0;
}
I've added myself to the dialout group, so in theory it should run under a non-root user.
Output as non-root user:
[lucas@lucas-netbook src]$ ./voltmeter /dev/ttyUSB0
Hello
Open serial: /dev/ttyUSB0
Before openCould not open serial port
Output as root:
[lucas@lucas-netbook src]$ sudo ./voltmeter /dev/ttyUSB0
[sudo] password for lucas:
Hello
Open serial: /dev/ttyUSB0
*hangs*
So there's something strange here, when running as root, it doesn't even enter the function init_serial() (as the printf doesn't appear in the terminal), and it also hangs.
When not running as root, it almost immediately ends with the message it can't open the serial port.
Any idea what i can be, and how to fix this?
Thanks in advance,
Lucas
I'm trying to open the serial port with in a C program, but unfortunately it doesn't work.
Here's my code:
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* main.c
* Copyright (C) Lucas van Dijk 2011 <info@return1.net>
*
* voltmeter is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* voltmeter is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
/**
* Opens serial port on given location
*
* Sets the filedescriptor to block when no data is available
*
* @param port String with the location of the port (/dev/ttyS0 for example)
* @return file descriptor of the port
*/
int init_serial(char * port)
{
int fd;
printf("Before open");
fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd != -1)
{
printf("Before options");
fcntl(fd, F_SETFL, 0);
// Get options
struct termios options;
tcgetattr(fd, &options);
// Set up serial
// 9600-8-E-1
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_cflag &= ~CSTOPB;
tcsetattr(fd, TCSANOW, &options);
}
return fd;
}
/**
* Send request to our measurement device to start a new measurement
*
* @param fd File descriptor
*/
int send_request(int fd)
{
if(fd == -1)
{
return -1;
}
printf("Sending request..\n");
return write(fd, "r", 1);
}
/**
* Main entry point of the application
*/
int main(int argc, char * argv[])
{
printf("Hallo\n");
if(argc < 2)
{
// No port given, print error
printf("Please specify which serial port to use.\n");
printf("\tUsage: %s serial_port\n", argv[0]);
return 1;
}
printf("Open serial: %s\n", argv[1]);
int fd = 0;
fd = init_serial(argv[1]);
if(fd == -1)
{
printf("Could not open serial port\n");
return 1;
}
int i = 0;
time_t last_request = 0;
time_t current_time;
while(1)
{
time(¤t_time);
if(current_time + 5 < last_request)
{
send_request(fd);
char buffer[5];
// Read Response
read(fd, buffer, 4);
printf("Measurement #%d: %s", i, buffer);
i++;
time(&last_request);
}
}
close(fd);
return 0;
}
I've added myself to the dialout group, so in theory it should run under a non-root user.
Output as non-root user:
[lucas@lucas-netbook src]$ ./voltmeter /dev/ttyUSB0
Hello
Open serial: /dev/ttyUSB0
Before openCould not open serial port
Output as root:
[lucas@lucas-netbook src]$ sudo ./voltmeter /dev/ttyUSB0
[sudo] password for lucas:
Hello
Open serial: /dev/ttyUSB0
*hangs*
So there's something strange here, when running as root, it doesn't even enter the function init_serial() (as the printf doesn't appear in the terminal), and it also hangs.
When not running as root, it almost immediately ends with the message it can't open the serial port.
Any idea what i can be, and how to fix this?
Thanks in advance,
Lucas