Thread: Best operating system for C programming with serial ports?

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    9

    Best operating system for C programming with serial ports?

    What is the best and easiest operating system to program in C in especially if I’m programming a serial port? Windows, Linux, or just DOS?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Is that it, or were you planning to do something else as well?
    Driving the solution from looking at just one aspect of the problem isn't the way to go.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    This is a robotics project. I'm using a R232 serial port to control a microcontroller board. So the computer will be doing calculations and decisions, but input and output will be through the serial port. I’ve been working in a Linux environment with GCC, yet reading and writing through the port seems very complicated. I finally can send numbers out (every other time I run the program), but I get a segmentation error-core dumped when I try to read from the port. I wonder if plain DOS would have fewer “hoops” to jump through to send and receive numbers through the port.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Serial ports in Linux is far less complicated than doing it in DOS - for one thing, the OS will actually help you with the collection of data, and (almost) guarantee that you never miss a reply from the sending side.

    Windows has the same advantage.

    A segmentation fault is nothing to do with accessing the serial port (or at least, it's highly unlikely), but rather with how you deal with data to or from the serial port. Segmentation errors are caused by accessing memory that is not available - usually caused by errant pointers.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > but I get a segmentation error-core dumped when I try to read from the port.
    Post your code, then we can fix it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Salem, that is an awesome avatar.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    Here is my code for recieving bytes from a device through the serial port:
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>               
    #include <sys/io.h>  
    #include <fcntl.h>
    #include <termios.h>  
    #include <sys/types.h>
    #include <sys/stat.h>  
    #include <sys/time.h>  
    #define SERIAL "/dev/ttyS0"
    #define BAUDRATE B57600
    #define _POSIX_SOURCE 1 
    #define FALSE 0
    #define TRUE 1
            
    volatile int STOP=FALSE;
    
    void get_data(void);
    void request_data(void);       
    int sensor[26];
    int n, fd;
    struct termios oldtio,newtio;
    
    int main(void)/*------------------------MAIN PROGRAM*/
    {
    	request_data(); /* Asks for data from Roomba*/	
    	get_data(); /*Reads input from Roomba*/
    	/* restore the old port settings */
             tcsetattr(fd,TCSANOW,&oldtio);	
    	
      	return 0;
    }
    
    
                 
     void request_data()/*..................................Asks for input from Roomba*/
    {
    	
    	fd = open(SERIAL, O_RDWR | O_NOCTTY | O_NONBLOCK);
    	if (fd<0) {perror(SERIAL); exit(-1);} 
    	tcgetattr(fd,&oldtio); // save current port settings 
          // set new port settings for canonical input processing 
          newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
          newtio.c_iflag = IGNPAR | ICRNL;
          newtio.c_oflag = 0;
          newtio.c_lflag = 0;       //ICANON;
          newtio.c_cc[VMIN]=1;
          newtio.c_cc[VTIME]=0;
          tcflush(fd, TCIFLUSH);
          tcsetattr(fd,TCSANOW,&newtio);
    
    	/*Roomba Control*/
      	int begin[1];
    	begin[0] = 128;	
    	n=write(fd, begin, 1); /*Prepares Roomba to receive orders*/
    	if (n < 0)
    	printf("Error @ begin!\n");
    	begin[0] = 130;
    	n=write(fd, begin, 1); 
    	/* Roomba Ready!*/
    	
    	begin[0] = 142;  /* Get Data*/
    	n=write(fd, begin, 1); 
    
    	begin[0] = 0; /* Return all 26 bytes*/
    	n=write(fd, begin, 1); 
    
    	close (fd); /*Closes the port?*/
    
    	
    }
    
    void get_data() /* =========================Read data that Roomba sent*/
    	{
    	int ch, i;
    	char a;
    	fd = open(SERIAL, O_RDWR | O_NOCTTY);
    	if (fd<0) {perror(SERIAL); 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] = 26;   /* blocking read until 26 chars received */
    
            tcsetattr(fd,TCSANOW,&newtio);
    
    	n=read(fd, sensor, 255); /* returns after 26 chars have been input */
    	
    	printf("&#37;d\n",sensor[0]);
    	printf("%d\n",sensor[1]);
    	printf("%d\n",sensor[2]);
    	printf("%d\n",sensor[3]);
    
    	close (fd); /*Closes the port?*/
           
    		
    }
    When certain numbers are sent to this device it is programmed to return all data from its sensors which is 26 bytes, but instead I get a segmentation error-core dumped message.
    Thanks for any help with the code, but first a question. I have a degree in mechanical engineering, and I want to build a robot that is sophisticated enough to count as experience in robotics to help me get a job in robotics. Is C the best language for this, and would robot “experts” be pleased with experience in programming in Linux or another system?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Why are you using int arrays for all your byte streams ?

    Why do you open/close the connection in both functions? Open it once at the start of the program, then close it again when you're done.

    > n=read(fd, sensor, 255); /* returns after 26 chars have been input */
    So say 26 then, not 255. That's just a big invitation to a buffer overflow.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    I learning from tutorials that use arrays for reading and writing to the port.
    Now it doesn't seem to respond to reading or writing.
    Here is code that I wrote that sends numbers to the device to get it to move, and then when a key is hit 4 zeros are sent to tell it to stop.
    Code:
    #include <stdio.h>   
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/io.h>  
    #include <fcntl.h>
    #include <termios.h>  
    #include <sys/types.h>
    #include <sys/stat.h>  
    #include <sys/time.h>  
    #define SERIAL "/dev/ttyS0"
    #define PORT1 0x3F8
    #define BAUDRATE B57600
    #define _POSIX_SOURCE 1 
    
    void changemode(int);             /
    int  kbhit(void);
    int main(void)
    {
    	int n, fd, ch;
    	char a;
    	struct termios oldtio,newtio;
    	fd = open(SERIAL, O_RDWR | O_NOCTTY | O_NONBLOCK);
    	if (fd<0) {perror(SERIAL); exit(-1);} 
    
    	tcgetattr(fd,&oldtio); // save current port settings 
          // set new port settings for canonical input processing 
          newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
          newtio.c_iflag = IGNPAR | ICRNL;
          newtio.c_oflag = 0;
          newtio.c_lflag = 0;       //ICANON;
          newtio.c_cc[VMIN]=1;
          newtio.c_cc[VTIME]=0;
          tcflush(fd, TCIFLUSH);
          tcsetattr(fd,TCSANOW,&newtio);
    
    	/*Roomba Control*/
      	int begin[1];
    	begin[0] = 128;	
    	n=write(fd, begin, 1); /*Prepares Roomba to receive orders*/
    	if (n < 0)
    	printf("Error @ begin!\n");
    	begin[0] = 130;
    	n=write(fd, begin, 1); 
    	if (n < 0)
    	begin[0] = 132;
    	n=write(fd, begin, 1); 
    	/* Roomba Ready!*/
    	
    	begin[0] = 137;  /* Forward*/
    	n=write(fd, begin, 1); 
    
    	begin[0] = 255;
    	n=write(fd, begin, 1); 
    	begin[0] = 56;
    	n=write(fd, begin, 1); 
    	if (n < 0)
    	printf("Error @ begin!\n");
    	begin[0] = 128;
    	n=write(fd, begin, 1); 
    	if (n < 0)
    	printf("Error @ begin!\n");
    	begin[0] = 0;
    	n=write(fd, begin, 1); 
    	if (n < 0)
    	printf("Error @ begin!\n");
    	
    	changemode(1);
      	while ( !kbhit() )
      	{
    	putchar('.');
       	}
    	begin[0] = 137;
    	n=write(fd, begin, 1); 
    	if (n < 0)
    	printf("Error @ begin!\n"); /*Orders Roomba to stop*/
    	begin[0] = 0;
    	n=write(fd, begin, 1); 
    	n=write(fd, begin, 1);
    	n=write(fd, begin, 1);
    	n=write(fd, begin, 1);
    
    	/* restore the old port settings */
             tcsetattr(fd,TCSANOW,&oldtio);	
    	changemode(0);
      	return 0;
    	}
    
    void changemode(int dir)
    {
      static struct termios oldt, newt;
    
      if ( dir == 1 )
      {
        tcgetattr( STDIN_FILENO, &oldt);
        newt = oldt;
        newt.c_lflag &= ~( ICANON | ECHO );
        tcsetattr( STDIN_FILENO, TCSANOW, &newt);
      }
      else
        tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
    }
    
    int kbhit (void)
    {
      struct timeval tv;
      fd_set rdfs;
    
      tv.tv_sec = 0;
      tv.tv_usec = 0;
    
      FD_ZERO(&rdfs);
      FD_SET (STDIN_FILENO, &rdfs);
    
      select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
      return FD_ISSET(STDIN_FILENO, &rdfs);
    }
    It used to work every other time, but now it doesn't do anything.
    Is there a way to check if the computer did send bytes out of the port?
    What are the books on serial port programming in Linux?

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > void changemode(int); /
    Does it compile with that trailing / ?

    > It used to work every other time, but now it doesn't do anything.
    Learn about CVS
    At the very least, make regular backups of what used to work so that you can always get back to something which works, and maybe do a "diff" to find out what changed in the meantime to break it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    That is the program that use to work every other time. That's what doesn't make sense. I copied the code you see from the program that was saved for backup. How does a program work every other time and then not at all without any changes in the code?
    Also how different is inputing and outputing with microcontroller boards as apposed to PC's if the I/O is digital?

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Like Salem, I doubt this would actually compile - I haven't got a Linux machine at the moment to test it on, but I'm pretty sure it's not compiling.

    One reason that you can't communicate on the serial port may be that the /dev/ttyS0 is being used by some other process, for example the /etc/inittab has a getty on ttyS0 (remove that line if that's the case).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Apr 2007
    Posts
    9
    I don't see /etc/inittab or getty in the code. Is that somewhere in the Linux system? I'm still learning C and Linux.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by dweenigma View Post
    I don't see /etc/inittab or getty in the code. Is that somewhere in the Linux system? I'm still learning C and Linux.
    Yes, /etc is a directory. In this directory there is a file called inittab. If you have root access, you can edit that file with your favourite text editor.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Resource ICONs
    By gbaker in forum Windows Programming
    Replies: 4
    Last Post: 12-15-2003, 07:18 AM
  2. My favourite operating system
    By techie in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 07-19-2002, 06:29 AM
  3. Microsoft = The Best Operating System
    By Troll_King in forum A Brief History of Cprogramming.com
    Replies: 92
    Last Post: 02-08-2002, 01:32 PM
  4. A New Operating System
    By commanderrulz in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 01-24-2002, 01:36 PM
  5. Variable Allocation in a simple operating system
    By awkeller in forum C Programming
    Replies: 1
    Last Post: 12-08-2001, 02:26 PM

Tags for this Thread