LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-04-2009, 04:03 AM   #1
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Rep: Reputation: 0
termios confused


Hello,

I wrote a little test program to comunicate with my domotics system (www.velbus.be). Everyting in the program runs fine, but not always!
The interface is recognized as /dev/ttyACM0. I can always send strings but not always receeve them (actuators send a response when you send them a request). The only time receiving is working is when I, just before I run the program, run stty -F /dev/ttyACM0 and no matter what options (baudrate, "-a" or "-g"), after running receiving is always working by the program. So I think nothing is wrong with the program. I've tried using other ways to set termios settings, tried other settings as well (rtccts etc). Now I'm running slightly out of options.

Maybe anyone of u can help me or has suggestions?

here's the code (it's a bit unstructured because it's all just a test code)
Code:
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>



#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyACM0"
#define _POSIX_SOURCE 1         //POSIX compliant source
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

void signal_handler_IO (int status);    //definition of signal handler
int wait_flag=TRUE;                     //TRUE while no signal received
char devicename[80] = MODEMDEVICE;
int fd_glob;
long BAUD = B9600;                      // derived baud rate from command line
long DATABITS = CS8;
long STOPBITS = 0;
long PARITYON = 0;
long PARITY = 0;

FILE *input;
FILE *output;
int status;
unsigned char checksum(unsigned char*lpData, int nSize);
int check_valid(unsigned char*lpData, int nSize);
//unsigned char *pakket(unsigned char prio, unsigned char rtr, unsigned char lenght, unsigned char addres, unsigned char*lpData, unsigned char*dest);
int pakket(unsigned char prio, unsigned char rtr, unsigned char lenght, unsigned char addres, unsigned char*lpData);


main(int Parm_Count, char *Parms[])
{

   char Param_strings[7][80];
   char message[8];

   int fd, tty, c, res, i, error, pr, valid_string;
   char In1, Key;
   unsigned char In2, prio, rtr, lenght, addres;
   struct termios oldtio, newtio;       //place for old and new port settings for serial port
   struct termios oldkey, newkey;       //place tor old and new port settings for keyboard teletype
   struct sigaction saio;               //definition of signal action
   unsigned char buf[255];              //buffer for where data is put
  int sercmd, serstat,status;
   
   input = fopen("/dev/tty", "r");      //open the terminal keyboard
   output = fopen("/dev/tty", "w");     //open the terminal screen
//output = stdout;


   if (!input || !output)
   {
      fprintf(stderr, "Unable to open /dev/tty\n");
      exit(1);
   }

   error=0;
   
   //read the parameters from the command line
   if (Parm_Count==2)  //if there are the right number of parameters on the command line
   {
      for (i=1; i<Parm_Count; i++)  // for all wild search parameters
      {
         strcpy(Param_strings[i-1],Parms[i]);
      }
      i=sscanf(Param_strings[0],"%s",devicename);
      if (i != 1) error=1;
      
   }  //end of if param_count

      sprintf(message,"Device=%s\r\n",devicename); //output the received setup parameters
      fputs(message,output);

      tty = open("/dev/tty", O_RDWR | O_NOCTTY | O_NONBLOCK); //set the user console port up
      tcgetattr(tty,&oldkey); // save current port settings   
	  //so commands are interpreted right for this program
      // set new port settings for non-canonical input processing  
	  //must be NOCTTY
      newkey.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
      newkey.c_iflag = IGNPAR;
      newkey.c_oflag = 0;
      newkey.c_lflag = 0;       //ICANON;
      newkey.c_cc[VMIN]=1;
      newkey.c_cc[VTIME]=0;
      tcflush(tty, TCIFLUSH);
      tcsetattr(tty,TCSANOW,&newkey);


      //open the device(com port) to be non-blocking (read will return immediately)
      fd = open(devicename, O_RDWR | O_NOCTTY | O_NONBLOCK);
	  fd_glob = fd;
      if (fd < 0)
      {
         perror(devicename);
         exit(-1);
      }

      //install the serial handler before making the device asynchronous
      saio.sa_handler = signal_handler_IO;
      sigemptyset(&saio.sa_mask);   //saio.sa_mask = 0;
      saio.sa_flags = 0;
      saio.sa_restorer = NULL;
      sigaction(SIGIO,&saio,NULL);

      // allow the process to receive SIGIO
      fcntl(fd, F_SETOWN, getpid());
      // Make the file descriptor asynchronous (the manual page says only
      // O_APPEND and O_NONBLOCK, will work with F_SETFL...)
      fcntl(fd, F_SETFL, FASYNC);


	  memset(&oldtio, 0, sizeof(struct termios));
	  if((tcgetattr(fd,&oldtio))<0){
		  printf("error: cannot read old settings"); // save current port settings 
	  }
	  if(cfsetospeed(&newtio, B38400) < 0 || cfsetispeed(&newtio, B38400) < 0 || tcsetattr(fd,TCSAFLUSH,&newtio) < 0){
		  printf("error: cannot set baud rates");
	  }

      //tcgetattr(fd,&oldtio); // save current port settings 
	memset(&newtio, 0, sizeof(struct termios));
	  //bzero(&newtio, sizeof(newtio)); 
	if ((tcgetattr(fd,&newtio)) < 0){
		printf("error: cannot read new attribs");
	}

      // set new port settings for canonical input processing 
      //newtio.c_cflag |= BAUD | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
//	  newtio.c_cflag |= CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
	  //newtio.c_ispeed = BAUD;
	  //newtio.c_ospeed = BAUD;
//      newtio.c_iflag = IGNPAR;
//      newtio.c_oflag = 0;
//      newtio.c_lflag = 0;       //ICANON;
//      newtio.c_cc[VMIN]=1;
//      newtio.c_cc[VTIME]=0;
//		cfsetispeed(&newtio, B9600);
//		cfsetispeed(&newtio, B9600);
      //tcflush(fd, TCIFLUSH);
//		tcdrain(fd);
//      tcsetattr(fd,TCSANOW,&newtio);

	newtio.c_iflag &= ~(BRKINT | ICRNL | IGNCR | INLCR | INPCK | ISTRIP | IXON | IXOFF | PARMRK);
	newtio.c_iflag |= IGNBRK | IGNPAR;
	newtio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG);
	newtio.c_oflag &= ~(OPOST);
	newtio.c_cflag &= ~(CRTSCTS | CSIZE | HUPCL | PARENB);
	newtio.c_cflag |= (CLOCAL | CS8 | CREAD);
	
	newtio.c_cc[VMIN] = 1;
	newtio.c_cc[VTIME] = 0;
	cfmakeraw(&newtio);
	if((tcsetattr(fd, TCSAFLUSH, &newtio)) < 0){
		printf("error: cannot set new attribs");
	}
	


 tcflush(fd, TCIOFLUSH);
 fflush(NULL);



      // loop while waiting for input. normally we would do something useful here
      while (STOP==FALSE)
      {
         status = fread(&Key,1,1,input);
         if (status==1)  //if a key was hit
         {
				
				

            switch (Key)
            { /* branch to appropiate key handler */
               case 0x1b: /* Esc */
                  STOP=TRUE;
                  break;
			   case 0x61:		// letter"a"
				   addres = 0x70;
				   message[0]= 0xe5;
				   message[1]= 0x00;
				   lenght = 0x2;
				   rtr = 0x00;
				   prio = 0xfb;
				   pakket(prio, rtr, lenght, addres, message);
				   break;
			   case 0x71:		// letter"a"
				   addres = 0x71;
				   message[0]= 0xe5;
				   message[1]= 0x00;
				   lenght = 0x2;
				   rtr = 0x00;
				   prio = 0xfb;
				   pakket(prio, rtr, lenght, addres, message);
				   break;
			   case 0x7A:		// letter"z"
				   //printf("off\r\n");
				   addres = 0x04;
				   message[0]= 0xf5;
				   message[1]= 0x01;
				   lenght = 0x2;
				   rtr = 0x00;
				   prio = 0xfb;
				   pakket(prio, rtr, lenght, addres, message);
				   break;
			   case 0x65:		// letter"e"
				   //printf("on\r\n");
				   addres = 0x04;
				   message[0]= 0xf6;
				   message[1]= 0x01;
				   lenght = 0x2;
				   rtr = 0x00;
				   prio = 0xfb;
				   pakket(prio, rtr, lenght, addres, message);
				   break;
			   case 0x77:		// letter"w"
				   addres = 0x70;
				   message[0]= 0x01;
				   message[1]= 0x01;
				   lenght = 0x0;
				   rtr = 0x40;
				   prio = 0xfb;
				   pakket(prio, rtr, lenght, addres, message);
					break;
               default:			// all others
                  fputc((int) Key,output);
					//sprintf(message,"%x ",Key);  //debug
					//fputs(message,output);
                    //write(fd,&Key,1);          //write 1 byte to the port
                  break;
            }  //end of switch key
         }  //end if a key was hit
		

         // after receiving SIGIO, wait_flag = FALSE, input is available and can be read
         if (wait_flag==FALSE)  //if input is available
         {
            res = read(fd,buf,255);
            if (res>0)
            {
				if (check_valid(buf,res) == TRUE)
				{
					//printf("Valid string: ");
					if (buf[4]==0xe6)
					{
						disp_temp(buf,res);
					}
					else
					{
						disp_data(buf,res);
					}
				}  // end of valid
            }  //end if res>0
            wait_flag = TRUE;      /* wait for new input */
         }  //end if wait flag == FALSE

      }  //while stop==FALSE

      // restore old port settings
      tcsetattr(fd,TCSANOW,&oldtio);
      tcsetattr(tty,TCSANOW,&oldkey);
      close(tty);
      close(fd);        //close the com port

   fclose(input);
   fclose(output);
}  //end of main

unsigned char checksum(unsigned char*lpData, int nSize)
{
unsigned char c = 0;
int i = 0;

for(; i<(nSize-2); ++i)
	c += lpData[i];
return (-c);
}

int check_valid(unsigned char*lpData, int nSize)
{
int check = FALSE;

	if ((lpData[0]==0xF) && (lpData[nSize-1]==0x4))
	{				
		if (checksum(lpData,nSize) == lpData[nSize-2])
		{
			check = TRUE;
		}
	}

	return (check);

}
disp_data(unsigned char*lpData, int nSize)
{
	int i;
	char message[8];
	
	printf("add : %X | ",lpData[2]);

	if (lpData[1] == 0xf8)
	{
		printf("prio : high | ");
	}
	if (lpData[1] == 0xfb)
	{
		printf("prio : low  | ");
	}
	if ((lpData[3]&0xf0)==0x0)
	{
		printf("rtr : off | ");
	}
	if ((lpData[3]&0xf0)==0x40)
	{
		printf("rtr : on  | ");
	}
		
	printf("data : ");
	for (i=4; i<(nSize-2); i++)  //for all chars in string
		{
			sprintf(message,"%X",lpData[i]);
			printf("%s ",message);
		}  //end of for all chars in string
		printf("\n\r");
}

disp_temp(unsigned char*lpData, int nSize)
{
	int i;
	short result;
	float endres;

	result = lpData[5] << 8;
	result |= lpData[6];
	result = (result / 0x20);
	endres = (float)result * 0.0625;
	printf("%.2f\r\n", endres);

}


int pakket(unsigned char prio, unsigned char rtr, unsigned char lenght, unsigned char addres, unsigned char*lpData)
{
	int i;
	unsigned char dest[30];
	dest[0]=0xf;
	dest[1]=prio;
	dest[2]=addres;
	dest[3]=(0xf0 & rtr) | (0xf & lenght);
	for (i=0; i<lenght; i++)
	{
		dest[4+i]=lpData[i];
	}
	dest[lenght+4]=checksum(dest,(lenght + 6));
	dest[lenght+5]=0x4;
	disp_data(dest,(lenght + 6));
	write(fd_glob,dest,(lenght + 6));
	fflush(NULL);
	//return dest;
}
/***************************************************************************
* signal handler. sets wait_flag to FALSE, to indicate above loop that     *
* characters have been received.                                           *
***************************************************************************/

void signal_handler_IO (int status)
{
//printf("received SIGIO signal.\n\r");
   wait_flag = FALSE;
}
thanks!!
 
Old 11-04-2009, 08:15 AM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Have you confirmed that data is always sent, using a known-good terminal emulator such as minicom or C-Kermit? When communicating with devices, I generally prefer non-canonical (raw) mode, and allow my own code to deal with line terminators, etc. It isn't obvious to me what cooked mode will do in the presence of both INLCR and ICRNL (why I prefer raw mode).
--- rod.
 
Old 11-04-2009, 05:05 PM   #3
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Original Poster
Rep: Reputation: 0
The data is idd always sent. The way I can check this is looking at the light at the switches when I put them on or off (in this case letter z and e). the other commandos do a status and a temperature request wich is also transmitted looking at the send receive led's of the interface.

I thought I was also in non canocial mode (-ICANON). How would you recommend communicating othewise because I need to have some interrupt handling when receiving from the bus (ex. switch status etc)?
 
Old 11-04-2009, 06:59 PM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Okay, sorry, I misread your code (missed the '~' in your logic that clears ICANON). When I said 'sent' data, I meant by the device. Are you sure that the device is always sending data? I understand that you can see the device respond to your commands, but how do you know that the device is always sending back data to your application's serial port?
In these cases, I always start out with a known-good tool (C-Kermit is my preferred weapon), and observe data transferring correctly both ways, before I ever test a speck of my own code. There is also a tool called 'serlook' which allows you to look at serial data, along with some timing information.
Your program has quite a bit of stuff not directly related to serial comm's, so it is somewhat difficult to study closely, but I don't see anything obvious to gripe about. You seem to have used one of the common serial comm's websites as a codebase, so perhaps you could re-build a smaller version using the sample code as a kind of reference code base, leaving out as much of your own stuff as possible.
Try printing out the contents of the original termios struct, and see if you can determine what effect the stty command is having on the configuration of the port. Run the program before and after using stty, and compare the values left in the fields between runs.
Thats all I can think of for now.
--- rod.
 
Old 11-05-2009, 02:46 AM   #5
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Original Poster
Rep: Reputation: 0
Hello,
unfortunately I also tried all of that.

The first thing I did was using minicom trying to communicate and see what happend. Than using the spec of the interface as reference, builded a initial program (just dump data). Why I know that there's always data send is that the switches always send out there status when changing (the domotica system can work on it's own).
I also did a printout of the c_cflag and the c_oflag register after changing them, compared them with what stty -g prints out before, while running and after. No differences at all.

It keeps me confusing that, when I run stty just before I run the program, it all works and keeps working until I quit and run it again after a minute.

I 'll have a try with serlook to see if that can help me out ...

thanks already
 
Old 11-05-2009, 08:28 AM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
When your initial program dumped the data, what was the result? Did the device reply on every command? Did your initial program correctly receive all of the data?
What about approaching the problem from a different approach: send data to your application from another controlled source, such as another computer running minicom, or minicom talking out of another serial port on the same computer. This will allow you to send data under your control, and observe your code's behavior independently of the data source.
I understand that you say 'the switches always send out there status', but have you done anything to confirm that this actually happens, or is this simply the way it is spec'ed to be?
--- rod.
 
Old 11-05-2009, 01:43 PM   #7
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Original Poster
Rep: Reputation: 0
The result of the initial program was the same, sending ok, receiving the same problem. But I did't bother me because I had some other probs at that time.

Sending data with another comm port is a option I don't have because this is a virtual comm port (usb->comm->can(velbus)). Or I have to try to reopen the port (I 've seen it has been done in stty).

The switches are just spec'ed to do so, when I push a switch, the switch send out its stutus so that an actuator (like ex a relais) can change. The actuator in his place sends out his changed position to change in ex the backlight of a switch. As you can see, ther's enough data on the bus. Sadly I cannot receive them always ...
 
Old 11-05-2009, 04:35 PM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Okay, I knew there was more to this than I got from your initial report. Do you have any software that correctly reads from the virtual com port? Is it a generic USB-dongle-thing, or is it a dedicated component part of the overall system? In either case, where did the driver come from? Is there any documented API (thinking special ioctl()s here...) or sample code that talks to/through it in Linux?
Your description 'usb->comm->can' sounds like there is a CANbus component to this. If so, I think there could be some kind of address issue (CANbus nodes are supposed to be uniquely addressed; it's part of the messaging protocol). Are you sure you don't have to send something that causes the USB-thingy to acquire an address? Might not be a message, per se, but some kind of out-of-band signal, such as an interpretation of something that would ordinarily be applied to a serial port (wild speculation). It would make sense that a message could be sent, but not received if the message was addressed to your device.

Have you tried using blocking read()s from the device, rather than using the asynchronous signaling that your sample code shows? You have set VMIN=1 while VTIME=0. So your read()s can potentially return with a single byte, yet you test the buffer in check_valid() as if it always has more than one byte. Do you have a version of the code that simply dumps each received byte, or array of bytes, to stdout (print in hex, so you don't bork your terminal)? While you're at it, wouldn't hurt to dump the size of each returned buffer, just to see how much data is returning on each read().

--- rod.

Last edited by theNbomr; 11-05-2009 at 04:39 PM.
 
Old 11-05-2009, 04:41 PM   #9
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
One more thought; what are the permissions on /dev/ttyACM0? Do you have read access to the device?
--- rod.
 
Old 11-06-2009, 05:35 AM   #10
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Original Poster
Rep: Reputation: 0
I have windows software working with the interface + protocol definition + vb code examples. In windows it uses the usbser.sys driver thus normally recognized as a comm port. In linux there are no code examples available, I'm the first one to try.
The can bus in this problem shouldn't be an issue, all the handling is done by the processor on the interfcace, the interface listens to all the data on the bus and has no addres. I'm for 100% sure that sending always works because I can always turn my lights on/off. I'm also sure about the the other data I put on the bus, and know what to expect back. This part of the code has been proven to work.

Is there a need to install a driver in linux because at the moment it's been recognized as ttyACM0?

The first thing I tried was the code I used as template ( http://www.comptechdoc.org/os/linux/...pgcserial.html ) and than builded further with error checking etc. With this code I had just the same problem, but like I said before at that time it wasn't a concern and I was happy already that I could talk and read the device and had same representive results like expected.

What excactly do you mean with blocking read?

As for the permissions root has read/write acces and programming as root, don't think that's the problem?!?
 
Old 11-06-2009, 08:09 AM   #11
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
As I understand it, there must be a driver of some sort, in order to populate the appropriate /dev tree. The driver essentially creates the device by doing so. You may be able to see where this is happening by scanning the output of dmesg. Since you didn't deliberately install a driver, I am guessing that Linux detected the device and knows about an existing included driver for it.

If the device uses CANbus, it must have an address. It is either a default address, or one that gets assigned. CANbus cannot work without one, unless all messaging is done as broadcasts. Since it seems that messages must be destined for specific devices in your application, it seems logical that there must be addressing assigned in some way. Since you haven't stated otherwise, is it correct that CANbus is actually involved?

What I mean by blocking read()s is that rather than setting up a signal handler to flag incoming data, simply send your data, and then call read() on the device. The read() call will block (wait for some data) until data arrives. This method is probably not appropriate for your final application (read() may block forever); I am suggesting it as a diagnostic aid only. Another method commonly used to prevent indefinite blocking is the use of the select() call. This performs a yes/no check for input on any of a definable list of file descriptors, with a definable timeout. It provides a bitmap of which file descriptors are ready to be read. You can use this on stdin, as well.

The received data may be less than one complete message, so you will have to accumulate bytes until you've identified that a complete message has been received. This, you should do in any case, even with the code structured as you presently have it.

It sounds like access is not an issue, although many would suggest that developing code and testing new code as root might be.

--- rod.
 
Old 11-06-2009, 05:58 PM   #12
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Original Poster
Rep: Reputation: 0
ok I think I can't get more basic like the next code:
Code:
#include <stdio.h>   /* Standard input/output definitions */
 #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 definitions */


 int open_port(void)
 {
   int fd;                                   /* File descriptor for the port */

   fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);

   if (fd == -1)
   {                                              /* Could not open the port */
     fprintf(stderr, "open_port: Unable to open /dev/ttyACM0 - %s\n",
             strerror(errno));
   }

   return (fd);
 }

main()
{
 int mainfd=0;                                            /* File descriptor */
 unsigned char chout;
 struct termios options;
   
 mainfd = open_port();

 fcntl(mainfd, F_SETFL, FNDELAY);                  /* Configure port reading */

 memset(&options, 0, sizeof(struct termios));	/* clear all settings */

 cfsetispeed(&options, B38400);                 /* Set the baud rates to 38400 */
 cfsetospeed(&options, B38400);
    
                                  
 options.c_cflag |= (CLOCAL | CREAD);	 /* Enable the receiver and set local mode */
 options.c_cflag |=  CS8;                              /* Select 8 data bits */
 options.c_cflag |= CRTSCTS;               /* Enable hardware flow control */  
      
                                        /* Set the new options for the port */
 tcsetattr(mainfd, TCSANOW, &options);
                         
 while (1)
 {
   read(mainfd, &chout, sizeof(chout));          /* Read character */
   
   if (chout != 0)
      printf("Got %x.\n", chout);

   chout=0;

 }
                                                    /* Close the serial port */
  close(mainfd);
 }
Still the same problem. When I run the program at first nothing works. Doing a stty -F /dev/ttyACM0 doesn't matter what options I do and then run the program, everyting receives just fine. All bytes wanted are there.

No need to configure the CAN, It uses the CAN protocol internally or maybe better said, the CAN hardware @ lower speed for long wires. The code above proves that nothing has to be setted. Never done that also ni the visual basic programs. The reason why I want this in linux is of course the stabillity of the server I'm running (windows likes to crash) and the need for more functionallity (ex conditional logic, logging).

Is there a possble way to change the way linux detects the hardware. By now it's been detected as a ACM device, can I change this in ex an usbserial device? (my linux knowledge doesn't reach that far I'm affraid)
 
Old 11-06-2009, 07:14 PM   #13
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
ok I think I can't get more basic like the next code:
Well, yeah, you can... but it won't change anything. You've already opened the device with O_NDELAY and then use fcntl() to set FNDELAY. However, that is nothing more than redundant.

Okay, I'm now running out of ideas. But:
Quote:
I also did a printout of the c_cflag and the c_oflag register after changing them, compared them with what stty -g prints out before, while running and after
What about c_iflag? I overlooked this oversight ;-) c_iflag is the register that has everything to do with data input.
Also, have you looked at dmesg to see if it reveals anything about the device and its driver? Perhaps explore whether the existing driver has been updated/replaced. Thats a bit of a reach, but like I said, I'm pretty much at the end of my rope.

I still would like to verify that the device is actually replying with a message, too. I think it is possible that there is something different about the outgoing message, that causes the device to either reply, or not. I don't suppose you have an oscilloscope...?

--- rod.
 
Old 11-07-2009, 04:58 AM   #14
jeroends
LQ Newbie
 
Registered: Nov 2009
Posts: 8

Original Poster
Rep: Reputation: 0
ok, did a printout of them again. One just after compiling (when I know it won't work) and one after running stty:

screenshot

unfortunately they are the same and as you can see, the second time I run it it receives the things I want (to me obvious what I see 0x0f as start 0x04 as end of the string).

the output of dmesg.
the cdc_acm driver is used, wich I think is the right one. Looking at the app notes of michochip usb communication they practicly always uses the cdc_acm protocol for there virtual devices. I don't think the manufactor of the domotics system is going to write there own communications layer when it's already available.

Is there a way to let linux use another driver?

It keeps me confusing why it all works when I run stty first?!? Maybe I've to contact the writer of the program, see what he can tell me more? (don't know if he would appreciate it)

btw yes I had an osciloscoop but the bus is working just fine, i can recieve the commands as you can see without sending a request first (in this case it was a thermostat wanted to start the heater).
 
Old 11-07-2009, 01:54 PM   #15
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Okay, I'm convinced that the device is sending, and that stty is actually doing something to affect the device or device driver. So, I guess the only thing left is to dig into the source code for stty, and see what it does. It must be opening the device, and since you say it doesn't matter what commands you give to stty, I guess I would focus on the way stty opens the device. Perhaps you could look at what option flags are available with the open() call; O_ASYNC sounds like a good prospect.
--- rod.
 
  


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
set baudrate to 256000 within termios.h agostain Linux - Hardware 3 01-02-2009 07:56 AM
Assistance With Termios Settings Please Peatmoss Linux - Newbie 3 06-01-2008 09:54 PM
managing termios for ser ports DavidHB Linux - Software 2 09-21-2006 07:37 AM
problem with serial port in loopback mode .. (termios) mta Programming 1 06-06-2006 11:56 AM
Figuring out a 'c_oflag'(man termios) that will help in stdout supression. Tarts Programming 13 08-11-2003 09:04 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:42 PM.

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