All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Xenomai serial port c++ code and / or xeno-- (xenomm-0.0.1) install problem
@ 2008-04-22 22:46 Karch, Joshua
  2008-04-23  0:12 ` Gilles Chanteperdrix
       [not found] ` <51B669A8A7D2914E9AB2B3F40AC6553E646F52@domain.hid>
  0 siblings, 2 replies; 30+ messages in thread
From: Karch, Joshua @ 2008-04-22 22:46 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 2312 bytes --]


Hello,

I recently installed Xenomai on a PC/104 and began writing a C++ program that makes use of the serial port.  I tried using the Xenomai Serial port example program cross-link.c and I was successful in getting that to run. I edited cross-link.c to read only from a device running at 115200 on the serial port.  I have found the standard /dev/ttyS0 serial port to be useless for my application since I get overrun errors on my system.  

My C++ program reads byte at a time from a serial port, processes the byte, then repeats until a checksummed packet is received.  I have two specific questions as to how to get the serial port to work under Xenomai with c++

The way I understand port reading is as follows:

1) Open device using read_fd = rt_dev_open( READ_FILE, 0 ) and set it up
    err = rt_dev_ioctl(read_fd, RTSER_RTIOC_SET_CONFIG, &read_config);
2) It is necessary to create an RT_TASK analogous to a thread to service the serial port task
    err = rt_task_create(&read_task, "read_task", 0, 51, 0);
3) for each byte read, activate the read task with rt_task_start
    err = rt_task_start(&read_task,&read_task_proc,NULL);
    4) Within the Real Time read_task_proc, request one byte at a time within the rt_task_process using
        err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
        read = rt_dev_read(read_fd, buffer, 1);
5)  read from the buffer into the user application in non-real time mode

6)  close when done

The problem I am having with this method is that 
int 	rt_task_start (RT_TASK *task, void(*fun)(void *cookie), void *cookie)
won't accept a pointer to an object method and requires a pointer to an instance to map into the void(*fun)(void *cookie), void *cookie section.

With Pthreads, I instantiate a threaded main loop within an object as follows:
void * serial::thunk(void * param)
{
	serial *instance = (serial *) param;
	instance->read_task_proc();

}

Is there a similar way to do this with rt_tasks?  In particular, if a c++ based serial read example were available for byte-at-a-time, that would be very useful.

Also, xenomm-0.0.1 failed under ./configure with "checking value of TM_UNSET in native/timer.h"-- any ideas on how to get xenomm (xeno--) working?  Is it useful?

Thank you,

Joshua Karch


[-- Attachment #2: Type: text/html, Size: 3211 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno-- (xenomm-0.0.1) install problem
  2008-04-22 22:46 [Xenomai-help] Xenomai serial port c++ code and / or xeno-- (xenomm-0.0.1) install problem Karch, Joshua
@ 2008-04-23  0:12 ` Gilles Chanteperdrix
       [not found]   ` <51B669A8A7D2914E9AB2B3F40AC6553E646F15@domain.hid>
       [not found] ` <51B669A8A7D2914E9AB2B3F40AC6553E646F52@domain.hid>
  1 sibling, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-23  0:12 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
 > 
 > Hello,
 > 
 > I recently installed Xenomai on a PC/104 and began writing a C++ program that makes use of the serial port.  I tried using the Xenomai Serial port example program cross-link.c and I was successful in getting that to run. I edited cross-link.c to read only from a device running at 115200 on the serial port.  I have found the standard /dev/ttyS0 serial port to be useless for my application since I get overrun errors on my system.  
 > 
 > My C++ program reads byte at a time from a serial port, processes the byte, then repeats until a checksummed packet is received.  I have two specific questions as to how to get the serial port to work under Xenomai with c++
 > 
 > The way I understand port reading is as follows:
 > 
 > 1) Open device using read_fd = rt_dev_open( READ_FILE, 0 ) and set it up
 >     err = rt_dev_ioctl(read_fd, RTSER_RTIOC_SET_CONFIG, &read_config);
 > 2) It is necessary to create an RT_TASK analogous to a thread to service the serial port task
 >     err = rt_task_create(&read_task, "read_task", 0, 51, 0);
 > 3) for each byte read, activate the read task with rt_task_start
 >     err = rt_task_start(&read_task,&read_task_proc,NULL);

I do not think it is a good idea to call rt_task_start for each byte
read. At least, I do not think it is what rt_task_start was initially
designed for.

 >     4) Within the Real Time read_task_proc, request one byte at a time within the rt_task_process using
 >         err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
 >         read = rt_dev_read(read_fd, buffer, 1);

What is the point of waiting for an event before reading ? If you read
directly, it will make one less system call, and rt_dev_read will
block just like rt_dev_ioctl.

 > 5)  read from the buffer into the user application in non-real time mode
 > 
 > 6)  close when done
 > 
 > The problem I am having with this method is that 
 > int 	rt_task_start (RT_TASK *task, void(*fun)(void *cookie), void *cookie)
 > won't accept a pointer to an object method and requires a pointer to an instance to map into the void(*fun)(void *cookie), void *cookie section.
 > 
 > With Pthreads, I instantiate a threaded main loop within an object as follows:
 > void * serial::thunk(void * param)
 > {
 > 	serial *instance = (serial *) param;
 > 	instance->read_task_proc();
 > 
 > }

 > 
 > Is there a similar way to do this with rt_tasks?  In particular, if a c++ based serial read example were available for byte-at-a-time, that would be very useful.

There is no difference between pthread_create and rt_task_start. The
usual trick is to pass them a pointer to a class static method: a class
static method pointer is a valid C function pointer.

 > 
 > Also, xenomm-0.0.1 failed under ./configure with "checking value of TM_UNSET in native/timer.h"-- any ideas on how to get xenomm (xeno--) working?

Maybe xenomm was made for an earlier version of xenomai and has not been
updated since Xenomai was updated ?

 >  Is it useful?

I guess it has a nice C++ wrapper class to rt_task_create/rt_task_start.

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
       [not found]   ` <51B669A8A7D2914E9AB2B3F40AC6553E646F15@domain.hid>
@ 2008-04-23 13:58     ` Gilles Chanteperdrix
  2008-04-23 14:25       ` Karch, Joshua
  0 siblings, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-23 13:58 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai-help

On Wed, Apr 23, 2008 at 3:47 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>
>
>
>
> Gilles,

Please keep sending copies to the mailing list, other might be
interested by your questions.

>
>  thank you for responding to my query.  What would be the right method for
> reading byte-at-a-time using the Xenomai drivers?

I do not pretend to know a "right" method. However, what looks simpler
is to call rt_dev_read in a loop.

> Do I even need an RT task to read from the serial driver?

Yes, if the task needs to be suspended (because there is no byte ready
yet), it has to be a real-time task.

Regards.

-- 
 Gilles


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
  2008-04-23 13:58     ` [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) " Gilles Chanteperdrix
@ 2008-04-23 14:25       ` Karch, Joshua
  2008-04-23 14:30         ` Gilles Chanteperdrix
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-23 14:25 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-help

[-- Attachment #1: Type: text/plain, Size: 1946 bytes --]


Hi Gilles,

>From what you're saying it appears a task is necessary to read a byte in a loop.  That method works.  The issue is, I want to be able to issue a read command to get a byte on demand from the calling thread.

With the /dev/ttyS0 driver, I used to be able to read a byte after using select statement without polling: My old code did the following:
 
realserial *serial = new realserial();
serial->startup("serialportdevice",115200);

then in a pthreaded loop I request a read

int count= serial->readbyte();
    then I access the buffer if count>0;
char inchar=serial->getreadbyte();
    process inchar
    loop again.

I split read byte and get-read byte into two parts in order to check for 1 second time-outs for data.

Is it possible to do this using the rtser0 driver?  If I have to use a task,
can I make the task run for only one iteration of the loop, then suspend it to process the byte, 
and then reactivate it againwhen another byte is needed?

Sincerely,

Joshua Karch





-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Wed 4/23/2008 9:58 AM
To: Karch, Joshua
Cc: xenomai-help
Subject: Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
 
On Wed, Apr 23, 2008 at 3:47 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>
>
>
>
> Gilles,

Please keep sending copies to the mailing list, other might be
interested by your questions.

>
>  thank you for responding to my query.  What would be the right method for
> reading byte-at-a-time using the Xenomai drivers?

I do not pretend to know a "right" method. However, what looks simpler
is to call rt_dev_read in a loop.

> Do I even need an RT task to read from the serial driver?

Yes, if the task needs to be suspended (because there is no byte ready
yet), it has to be a real-time task.

Regards.

-- 
 Gilles


[-- Attachment #2: Type: text/html, Size: 2835 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
  2008-04-23 14:25       ` Karch, Joshua
@ 2008-04-23 14:30         ` Gilles Chanteperdrix
  2008-04-23 15:43           ` Karch, Joshua
  0 siblings, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-23 14:30 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai-help

On Wed, Apr 23, 2008 at 4:25 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>
>
>
>
> Hi Gilles,
>
>  From what you're saying it appears a task is necessary to read a byte in a
> loop.  That method works.  The issue is, I want to be able to issue a read
> command to get a byte on demand from the calling thread.
>
>  With the /dev/ttyS0 driver, I used to be able to read a byte after using
> select statement without polling: My old code did the following:

Using read (or rt_dev_read) does not do any more polling than using
select, it just suspends the calling thread until some bytes are ready
to be processed.

>
>  realserial *serial = new realserial();
>  serial->startup("serialportdevice",115200);
>
>  then in a pthreaded loop I request a read
>
>  int count= serial->readbyte();
>      then I access the buffer if count>0;
>  char inchar=serial->getreadbyte();
>      process inchar
>      loop again.
>
>  I split read byte and get-read byte into two parts in order to check for 1
> second time-outs for data.
>
>  Is it possible to do this using the rtser0 driver?  If I have to use a
> task,
>  can I make the task run for only one iteration of the loop, then suspend it
> to process the byte,
>  and then reactivate it againwhen another byte is needed?

I am sorry but I really do not understand your problem. There is no
real difference between calling read in a pthread and calling
rt_dev_read in a real-time thread. The things that work with
/dev/ttyS0 should work automatically with rtser0.

If that does not work, please post a full example of code.

-- 
 Gilles


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
  2008-04-23 14:30         ` Gilles Chanteperdrix
@ 2008-04-23 15:43           ` Karch, Joshua
  2008-04-23 18:10             ` Gilles Chanteperdrix
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-23 15:43 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-help

[-- Attachment #1: Type: text/plain, Size: 8323 bytes --]

Gilles,

I've attached my old serial port code that uses the /dev/ttyS0 port.  What I have here is a "read byte on demand" function that uses the select statement to block until data is ready.  My initial goal was to replicate this functionality using the Xenomai Serial Driver.  It seems, however, that the following is not possible under Xenomai.  What I'm starting to conclude is that I can only receive data from a serial port within the context of a task, and that printing error codes from strerr produce "Operation not permitted" If I directly call read in a manner similar to the linux serial port code (posted below) by requesting a read from my sensor packet processing thread without using an RT_TASK.  Here is what my sensor thread used to do to get data from /dev/ttyS0


in the Pthread sensor processing thread...

void sensorthreadmainloop()
{
    while(1)
    {

	if(serialport->readbyte())
			{
				SENSORID=sensorpacket->processChar(ser->getreadbyte());
			}
			else
			{
				printf("One Second timeout detected on serial port, sensor data not received\n");
			}
			
                        // measure timestamp, process byte, checksum, etc, if timestamp is too
                        //great an error has occurred, etc.  If valid packet is received, send a
                        //condition variable signal to the main loop that data is available
                        //break out of loop if the application requests thread termination
                        .
                        .
                        .
                        //
    }
}

It appears that I have to do something else with Xenomai-- set up a real time task which reads bytes from the rtser0 device. 
When data is received, trigger a semaphore/condition variable to the above thread that one byte is ready for processing.

What this basically means is that I would have an rt task like the following in the serial port reader code where the task has been pre-initialized and started. 
 
void read_task_proc(void *arg)
{
	while (1)
        {
		int read = rt_dev_read(read_fd, inbyte, 2250);
		if (read <0) {
			printf("error on rt_dev_read, code %s\n",
			       strerror(-err));
			break;
		}
                else
                {
                          //data received, trigger  condition variable
			  pthread_mutex_lock(&run_mutex);
		          pthread_cond_signal(&run_cv);
			  pthread_mutex_unlock(&run_mutex);

		}

	}


}

In my sensor  thread I would have the following:

void sensorthreadmainloop()
{
    while(1)
    {

	
		pthread_mutex_lock(&run_mutex);
		pthread_cond_wait(&run_cv, &run_mutex);
		pthread_mutex_unlock(&run_mutex);
                //if data received
		SENSORID=sensorpacket->processChar(ser->getreadbyte());
		//and figure out a way to signal other important information such as timeouts	
                        // measure timestamp, process byte, checksum, etc, if timestamp is too
                        //great an error has occurred, etc.  If valid packet is received, send a
                        //condition variable signal to the main loop that a completed sensor packet is available
                        //break out of loop if the application requests thread termination
                        .
                        .
                        .
                        //
    }
}
If I use a condition variable from a continuously running RT_TASK that reads from the serial port to trigger processing, is that the right way to make this work? 
Can I mix pthreads, mutexes, and tasks together, or should every thread my program has (and it reads 3 sensors using the above methods) all use RT_TASKS and specially set up Mutexes/Condition variables.


Here is my old serial port code which I hoped I could replicate with the Xenomai driver--


Thank you,

Joshua Karch


#include "serial.h"  //class definitions

serialport::serialport()
{

}

serialport::~serialport()
{

}


int serialport::startup(char * dev, speed_t baudrate)
{
	outptr=0;
	inptr=0;
	fd = open (dev, O_RDWR | O_NOCTTY);
	if (fd == -1)
	{
		printf ("invalid device or error\n");
		return(-1);
	}
	// set low latency mode, so we don't get 10msec scheduling granularity
	// this is the same as 'setserial /dev/ttyS0 low_latency',
	// but it won't complete if we aren't root
	if ( ioctl( fd, TIOCGSERIAL, &serinfo ) < 0 ) {
		printf( "Cannot get serial info.  It is probably a usb-serial converter\n " );
	}
	serinfo.flags |= ASYNC_LOW_LATENCY;
	if ( ioctl( fd, TIOCSSERIAL, &serinfo ) < 0 ) {
		printf( "Cannot get serial info.  It is probably a usb-serial converter Flags\n " );
	}

	tcgetattr (fd, &oldtio); ///< save current serial port settingsBRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF);
	tcgetattr (fd, &newtio); ///< save current serial port settings to new struct
	cfsetispeed(&newtio, baudrate);//input speed
	cfsetospeed(&newtio, baudrate);//output speed
	newtio.c_cflag &= ~(CSIZE | PARENB |CRTSCTS | CSTOPB);
	newtio.c_cflag |= (CS8 | CLOCAL | CREAD);
	newtio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG | ECHOE);//  choose raw input
    newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF);
    newtio.c_oflag &= ~OPOST;
	newtio.c_cc[VMIN]=1;
	newtio.c_cc[VTIME]=0;
	newtio.c_cc[NCCS]=0;
	newtio.c_ispeed=baudrate;
	newtio.c_ospeed=baudrate;
	newtio.c_cc[VMIN]=1;
	newtio.c_cc[VTIME]=0;
	tcflush(fd, TCIFLUSH);
	tcsetattr(fd, TCSANOW, &newtio);
	timeout.tv_sec=1;
	timeout.tv_usec=0;
	devicename=dev;
	return(0);
}


void serialport::shutdown()
{
	tcflush(fd, TCIFLUSH);
	tcsetattr(fd, TCSANOW, &oldtio);
}

///send data over serialport. Lock mutexes when sending data
void serialport::SendSerial(char *val, int length)
{
    /// Send a serial byte down the line
    write(fd, val, length);
}

///wait for one character
int serialport::readbyte()
{
	FD_ZERO (&rfds);
	FD_SET (fd, &rfds);
	int retval = select (fd + 1, &rfds, NULL, NULL, &timeout);
	timeout.tv_sec=1;
	timeout.tv_usec=0;
	if (retval)
	{
		return 1;
	}
	else
	{
		printf("Timeout of 1 seconds waiting for serial input on %s with retval of %d\n",devicename,retval);
		return 0;
	}
}

///get the read byte from the serial port
char serialport::getreadbyte()
{
	read(fd,&line[0],1);
	return line[0];
}


-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Wed 4/23/2008 10:30 AM
To: Karch, Joshua
Cc: xenomai-help
Subject: Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
 
On Wed, Apr 23, 2008 at 4:25 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>
>
>
>
> Hi Gilles,
>
>  From what you're saying it appears a task is necessary to read a byte in a
> loop.  That method works.  The issue is, I want to be able to issue a read
> command to get a byte on demand from the calling thread.
>
>  With the /dev/ttyS0 driver, I used to be able to read a byte after using
> select statement without polling: My old code did the following:

Using read (or rt_dev_read) does not do any more polling than using
select, it just suspends the calling thread until some bytes are ready
to be processed.

>
>  realserial *serial = new realserial();
>  serial->startup("serialportdevice",115200);
>
>  then in a pthreaded loop I request a read
>
>  int count= serial->readbyte();
>      then I access the buffer if count>0;
>  char inchar=serial->getreadbyte();
>      process inchar
>      loop again.
>
>  I split read byte and get-read byte into two parts in order to check for 1
> second time-outs for data.
>
>  Is it possible to do this using the rtser0 driver?  If I have to use a
> task,
>  can I make the task run for only one iteration of the loop, then suspend it
> to process the byte,
>  and then reactivate it againwhen another byte is needed?

I am sorry but I really do not understand your problem. There is no
real difference between calling read in a pthread and calling
rt_dev_read in a real-time thread. The things that work with
/dev/ttyS0 should work automatically with rtser0.

If that does not work, please post a full example of code.

-- 
 Gilles








[-- Attachment #2: Type: text/html, Size: 18238 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
  2008-04-23 15:43           ` Karch, Joshua
@ 2008-04-23 18:10             ` Gilles Chanteperdrix
       [not found]               ` <51B669A8A7D2914E9AB2B3F40AC6553E646F1D@afsexc01.aurora.aero>
  0 siblings, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-23 18:10 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai-help

Karch, Joshua wrote:
 > Gilles,
 > 
 > I've attached my old serial port code that uses the /dev/ttyS0 port.
 > What I have here is a "read byte on demand" function that uses the
 > select statement to block until data is ready.  My initial goal was
 > to replicate this functionality using the Xenomai Serial Driver.  It
 > seems, however, that the following is not possible under Xenomai.

It is possible, the serial driver has two things that may help you:
the RTSER_RTIOC_WAIT_EVENT ioctl, which will work like select.
the RTSER_SET_TIMEOUT_RX configuration bit, that will let you define a
timeout for data reception. 
If you wonder where these things are documented, have a look at:
http://www.xenomai.org/documentation/branches/v2.4.x/html/api/index.html

With a timeout on reception, you can call read directly, this will save
you a system call, this matters for latency.

 > What I'm starting to conclude is that I can only receive data from a
 > serial port within the context of a task, and that printing error
 > codes from strerr produce "Operation not permitted" If I directly call
 > read in a manner similar to the linux serial port code (posted below)
 > by requesting a read from my sensor packet processing thread without
 > using an RT_TASK.  Here is what my sensor thread used to do to get
 > data from /dev/ttyS0 
 > 
 > 
 > in the Pthread sensor processing thread...
 > 
 > void sensorthreadmainloop()
 > {
 >     while(1)
 >     {
 > 
 > 	if(serialport->readbyte())
 > 			{
 > 				SENSORID=sensorpacket->processChar(ser->getreadbyte());
 > 			}
 > 			else
 > 			{
 > 				printf("One Second timeout detected on serial port, sensor data not received\n");
 > 			}
 > 			
 >                         // measure timestamp, process byte, checksum, etc, if timestamp is too
 >                         //great an error has occurred, etc.  If valid packet is received, send a
 >                         //condition variable signal to the main loop that data is available
 >                         //break out of loop if the application requests thread termination
 >                         .
 >                         .
 >                         .
 >                         //
 >     }
 > }
 > 
 > It appears that I have to do something else with Xenomai-- set up a real time task which reads bytes from the rtser0 device. 
 > When data is received, trigger a semaphore/condition variable to the above thread that one byte is ready for processing.
 > 
 > What this basically means is that I would have an rt task like the following in the serial port reader code where the task has been pre-initialized and started. 
 >  
 > void read_task_proc(void *arg)
 > {
 > 	while (1)
 >         {
 > 		int read = rt_dev_read(read_fd, inbyte, 2250);
 > 		if (read <0) {
 > 			printf("error on rt_dev_read, code %s\n",
 > 			       strerror(-err));
 > 			break;
 > 		}
 >                 else
 >                 {
 >                           //data received, trigger  condition variable
 > 			  pthread_mutex_lock(&run_mutex);
 > 		          pthread_cond_signal(&run_cv);
 > 			  pthread_mutex_unlock(&run_mutex);
 > 
 > 		}
 > 
 > 	}
 > 
 > 
 > }
 > 
 > In my sensor  thread I would have the following:
 > 
 > void sensorthreadmainloop()
 > {
 >     while(1)
 >     {
 > 
 > 	
 > 		pthread_mutex_lock(&run_mutex);
 > 		pthread_cond_wait(&run_cv, &run_mutex);
 > 		pthread_mutex_unlock(&run_mutex);
 >                 //if data received
 > 		SENSORID=sensorpacket->processChar(ser->getreadbyte());
 > 		//and figure out a way to signal other important information such as timeouts	
 >                         // measure timestamp, process byte, checksum, etc, if timestamp is too
 >                         //great an error has occurred, etc.  If valid packet is received, send a
 >                         //condition variable signal to the main loop that a completed sensor packet is available
 >                         //break out of loop if the application requests thread termination
 >                         .
 >                         .
 >                         .
 >                         //
 >     }
 > }
 > If I use a condition variable from a continuously running RT_TASK that reads from the serial port to trigger processing, is that the right way to make this work? 
 > Can I mix pthreads, mutexes, and tasks together, or should every
 > thread my program has (and it reads 3 sensors using the above
 > methods) all use RT_TASKS and specially set up Mutexes/Condition
 > variables. 

Everything is possible, but let us keep something in mind: if you use
Xenomai it is because you are not satisfied with Linux natural
latency. You probably have some treatment to do upon reception of a
character on the serial line, some time of real-time control loop. If:
- you transfer control from the real time task receiving characters to a
  non real-time task to to the treatment;
- or you call some non real-time services from the task receiving
  characters; 
- or you have the real-time task receiving character wait for a non
  real-time task;
the real-time task receiving characters from the serial line will depend
on Linux latencies. In other words, you loose any interest in using
Xenomai.

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Xenomai-help] FW: Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
       [not found]               ` <51B669A8A7D2914E9AB2B3F40AC6553E646F1D@afsexc01.aurora.aero>
@ 2008-04-23 21:20                 ` Karch, Joshua
  2008-04-23 21:28                 ` [Xenomai-help] " Gilles Chanteperdrix
  1 sibling, 0 replies; 30+ messages in thread
From: Karch, Joshua @ 2008-04-23 21:20 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 7278 bytes --]




-----Original Message-----
From: Karch, Joshua
Sent: Wed 4/23/2008 5:15 PM
To: Gilles Chanteperdrix
Subject: RE: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
 

Gilles,

I decided to eliminate the pthread and create a task that handles the entire packet process, from reading the serial port, to decoding data, to disk io (saving the data to disk)  The only thing that's serviced occasionally is the main loop, which looks every half second for a keypress to quit.

Now, I get overrun errors once every 10 seconds to 30 seconds.  The machine is a PC/104 and I'm using fprintf to print the data received from the sensor to file-- should I use perhaps an RT version?.
I know it's an overrun because the CRC error is triggered, and then I did an IOCTL to find out what was wrong with the status register on that error.
rtser_status_t serstatus;
err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);

	if(!serstatus.line_status==96)
	     printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);

        I get a line_status code of rtser_status_t (serstatus) = 98 when the crc fails, which corresponds to 1100010.  the second lsb corresponds to overrun.  

This is the famous overrun I had with regular linux, it only happens much less often. 

The packet processing task was started with the following priority
	err = rt_task_create(&read_task, "read_task", 0, 51, 0);

I appreciate your help with this-- I agree that I should keep mutexes out, etc.

Thank you,

Joshua Karch




-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Wed 4/23/2008 2:10 PM
To: Karch, Joshua
Cc: xenomai-help
Subject: RE: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
 
Karch, Joshua wrote:
 > Gilles,
 > 
 > I've attached my old serial port code that uses the /dev/ttyS0 port.
 > What I have here is a "read byte on demand" function that uses the
 > select statement to block until data is ready.  My initial goal was
 > to replicate this functionality using the Xenomai Serial Driver.  It
 > seems, however, that the following is not possible under Xenomai.

It is possible, the serial driver has two things that may help you:
the RTSER_RTIOC_WAIT_EVENT ioctl, which will work like select.
the RTSER_SET_TIMEOUT_RX configuration bit, that will let you define a
timeout for data reception. 
If you wonder where these things are documented, have a look at:
http://www.xenomai.org/documentation/branches/v2.4.x/html/api/index.html

With a timeout on reception, you can call read directly, this will save
you a system call, this matters for latency.

 > What I'm starting to conclude is that I can only receive data from a
 > serial port within the context of a task, and that printing error
 > codes from strerr produce "Operation not permitted" If I directly call
 > read in a manner similar to the linux serial port code (posted below)
 > by requesting a read from my sensor packet processing thread without
 > using an RT_TASK.  Here is what my sensor thread used to do to get
 > data from /dev/ttyS0 
 > 
 > 
 > in the Pthread sensor processing thread...
 > 
 > void sensorthreadmainloop()
 > {
 >     while(1)
 >     {
 > 
 > 	if(serialport->readbyte())
 > 			{
 > 				SENSORID=sensorpacket->processChar(ser->getreadbyte());
 > 			}
 > 			else
 > 			{
 > 				printf("One Second timeout detected on serial port, sensor data not received\n");
 > 			}
 > 			
 >                         // measure timestamp, process byte, checksum, etc, if timestamp is too
 >                         //great an error has occurred, etc.  If valid packet is received, send a
 >                         //condition variable signal to the main loop that data is available
 >                         //break out of loop if the application requests thread termination
 >                         .
 >                         .
 >                         .
 >                         //
 >     }
 > }
 > 
 > It appears that I have to do something else with Xenomai-- set up a real time task which reads bytes from the rtser0 device. 
 > When data is received, trigger a semaphore/condition variable to the above thread that one byte is ready for processing.
 > 
 > What this basically means is that I would have an rt task like the following in the serial port reader code where the task has been pre-initialized and started. 
 >  
 > void read_task_proc(void *arg)
 > {
 > 	while (1)
 >         {
 > 		int read = rt_dev_read(read_fd, inbyte, 2250);
 > 		if (read <0) {
 > 			printf("error on rt_dev_read, code %s\n",
 > 			       strerror(-err));
 > 			break;
 > 		}
 >                 else
 >                 {
 >                           //data received, trigger  condition variable
 > 			  pthread_mutex_lock(&run_mutex);
 > 		          pthread_cond_signal(&run_cv);
 > 			  pthread_mutex_unlock(&run_mutex);
 > 
 > 		}
 > 
 > 	}
 > 
 > 
 > }
 > 
 > In my sensor  thread I would have the following:
 > 
 > void sensorthreadmainloop()
 > {
 >     while(1)
 >     {
 > 
 > 	
 > 		pthread_mutex_lock(&run_mutex);
 > 		pthread_cond_wait(&run_cv, &run_mutex);
 > 		pthread_mutex_unlock(&run_mutex);
 >                 //if data received
 > 		SENSORID=sensorpacket->processChar(ser->getreadbyte());
 > 		//and figure out a way to signal other important information such as timeouts	
 >                         // measure timestamp, process byte, checksum, etc, if timestamp is too
 >                         //great an error has occurred, etc.  If valid packet is received, send a
 >                         //condition variable signal to the main loop that a completed sensor packet is available
 >                         //break out of loop if the application requests thread termination
 >                         .
 >                         .
 >                         .
 >                         //
 >     }
 > }
 > If I use a condition variable from a continuously running RT_TASK that reads from the serial port to trigger processing, is that the right way to make this work? 
 > Can I mix pthreads, mutexes, and tasks together, or should every
 > thread my program has (and it reads 3 sensors using the above
 > methods) all use RT_TASKS and specially set up Mutexes/Condition
 > variables. 

Everything is possible, but let us keep something in mind: if you use
Xenomai it is because you are not satisfied with Linux natural
latency. You probably have some treatment to do upon reception of a
character on the serial line, some time of real-time control loop. If:
- you transfer control from the real time task receiving characters to a
  non real-time task to to the treatment;
- or you call some non real-time services from the task receiving
  characters; 
- or you have the real-time task receiving character wait for a non
  real-time task;
the real-time task receiving characters from the serial line will depend
on Linux latencies. In other words, you loose any interest in using
Xenomai.

-- 


					    Gilles.



[-- Attachment #2: Type: text/html, Size: 14734 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
       [not found]               ` <51B669A8A7D2914E9AB2B3F40AC6553E646F1D@afsexc01.aurora.aero>
  2008-04-23 21:20                 ` [Xenomai-help] FW: " Karch, Joshua
@ 2008-04-23 21:28                 ` Gilles Chanteperdrix
  2008-04-23 21:36                   ` Karch, Joshua
  2008-04-23 22:14                   ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
  1 sibling, 2 replies; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-23 21:28 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
 > 
 > Gilles,
 > 
 > I decided to eliminate the pthread and create a task that handles the entire packet process, from reading the serial port, to decoding data, to disk io (saving the data to disk)  The only thing that's serviced occasionally is the main loop, which looks every half second for a keypress to quit.
 > 
 > Now, I get overrun errors once every 10 seconds to 30 seconds.  The machine is a PC/104 and I'm using fprintf to print the data received from the sensor to file-- should I use perhaps an RT version?.

No, as I already explained, you can not use fprintf and hope remaining
deterministic.

There is no function writing data to disk while remaining
deterministic. That would mean have disk drivers and so on written for
xenomai.

You have to design your application with an rt-task doing the rt work,
and a non rt-task doing the non rt work. This non rt-task can be a
classical pthread, in which case you will have to use an rt_pipe for
communications between the two tasks. Or the non rt-task can be a
xenomai thread with priority 0, in which case you can use any other
IPC.

For assistance in the daunting task of keeping deterministic, see the
bit T_WARNSW of the rt_task_set_mode service, or the bit PTHREAD_WARNSW
of the pthread_set_mode_np service.

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
  2008-04-23 21:28                 ` [Xenomai-help] " Gilles Chanteperdrix
@ 2008-04-23 21:36                   ` Karch, Joshua
  2008-04-23 22:14                   ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
  1 sibling, 0 replies; 30+ messages in thread
From: Karch, Joshua @ 2008-04-23 21:36 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 2113 bytes --]

Gilles,

thank you for your information about this-- I guess the handling of all error reporting, writing to disk, etc has to be handled in another thread.  In terms of priorities, should I set the serial task to have a priority of 99?  I was also advised to make a smaller buffer to flush data to disk. I'm currently using the defaults which might be a large cached buffer.  If I flush data to disk at regular intervals I can lower blockages.  Nonetheless, the writing to disk is a data-logging task and could be moved out of the RT-Task, leaving only the capture of data and processing of packets in the RT Task.  I assume tools like hdparm (which unmask serial interrupts) have no place in the xenomai world, right?

Take care,

Joshua Karch




Karch, Joshua wrote:
 > 
 > Gilles,
 > 
 > I decided to eliminate the pthread and create a task that handles the entire packet process, from reading the serial port, to decoding data, to disk io (saving the data to disk)  The only thing that's serviced occasionally is the main loop, which looks every half second for a keypress to quit.
 > 
 > Now, I get overrun errors once every 10 seconds to 30 seconds.  The machine is a PC/104 and I'm using fprintf to print the data received from the sensor to file-- should I use perhaps an RT version?.

No, as I already explained, you can not use fprintf and hope remaining
deterministic.

There is no function writing data to disk while remaining
deterministic. That would mean have disk drivers and so on written for
xenomai.

You have to design your application with an rt-task doing the rt work,
and a non rt-task doing the non rt work. This non rt-task can be a
classical pthread, in which case you will have to use an rt_pipe for
communications between the two tasks. Or the non rt-task can be a
xenomai thread with priority 0, in which case you can use any other
IPC.

For assistance in the daunting task of keeping deterministic, see the
bit T_WARNSW of the rt_task_set_mode service, or the bit PTHREAD_WARNSW
of the pthread_set_mode_np service.

-- 


					    Gilles.


[-- Attachment #2: Type: text/html, Size: 3021 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Xenomai-help] serial port overrun problem RT TASK
  2008-04-23 21:28                 ` [Xenomai-help] " Gilles Chanteperdrix
  2008-04-23 21:36                   ` Karch, Joshua
@ 2008-04-23 22:14                   ` Karch, Joshua
  2008-04-24  6:43                     ` Gilles Chanteperdrix
  1 sibling, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-23 22:14 UTC (permalink / raw)
  To: Gilles Chanteperdrix, xenomai

[-- Attachment #1: Type: text/plain, Size: 3379 bytes --]

Gilles, (and anyone else who has had overrun errors or has experience with the Xenomai serial port driver)

It seems that even though I turned off fprintf and even though I stopped logging to disk, I still get the same number of overrun errors.  I broke the loop down to the bare basics.

my task now consists of the following

Task was launched as follows:rt_task_create(&read_task, "read_task", 0, 51, 0);


void sensor::mainloop()
{


	//set up serial read
	struct rtser_event rx_event;
	rtser_status_t serstatus;
	int numread,err;

		 while(1)
		 {
			if(exitprogram)		//
				 break;

			err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);

			if (err)
			{
				printf(RTASK_PREFIX
					       "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
				  strerror(-err));
				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);

			}

			else
			{
				numread = rt_dev_read(read_fd, buf, 1);
				{
					printf(RTASK_PREFIX "error on rt_dev_read, code %d %s\n",numread,
					       strerror(-numread));
					err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
					printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
					continue;
				}
			else
			{
				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);  //if data received normally, make sure 96 was received, 98 = overrun
				if(!serstatus.line_status==96)
				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
			}
		}
}

Thank you,

Joshua Karch


-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Wed 4/23/2008 5:28 PM
To: Karch, Joshua
Cc: xenomai@xenomai.org
Subject: RE: [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) install problem
 
Karch, Joshua wrote:
 > 
 > Gilles,
 > 
 > I decided to eliminate the pthread and create a task that handles the entire packet process, from reading the serial port, to decoding data, to disk io (saving the data to disk)  The only thing that's serviced occasionally is the main loop, which looks every half second for a keypress to quit.
 > 
 > Now, I get overrun errors once every 10 seconds to 30 seconds.  The machine is a PC/104 and I'm using fprintf to print the data received from the sensor to file-- should I use perhaps an RT version?.

No, as I already explained, you can not use fprintf and hope remaining
deterministic.

There is no function writing data to disk while remaining
deterministic. That would mean have disk drivers and so on written for
xenomai.

You have to design your application with an rt-task doing the rt work,
and a non rt-task doing the non rt work. This non rt-task can be a
classical pthread, in which case you will have to use an rt_pipe for
communications between the two tasks. Or the non rt-task can be a
xenomai thread with priority 0, in which case you can use any other
IPC.

For assistance in the daunting task of keeping deterministic, see the
bit T_WARNSW of the rt_task_set_mode service, or the bit PTHREAD_WARNSW
of the pthread_set_mode_np service.

-- 


					    Gilles.


[-- Attachment #2: Type: text/html, Size: 9476 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-23 22:14                   ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
@ 2008-04-24  6:43                     ` Gilles Chanteperdrix
  2008-04-24  7:04                       ` Jan Kiszka
  2008-04-24 13:59                       ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
  0 siblings, 2 replies; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-24  6:43 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
 > Gilles, (and anyone else who has had overrun errors or has experience with the Xenomai serial port driver)
 > 
 > It seems that even though I turned off fprintf and even though I stopped logging to disk, I still get the same number of overrun errors.  I broke the loop down to the bare basics.
 > 
 > my task now consists of the following
 > 
 > Task was launched as follows:rt_task_create(&read_task, "read_task", 0, 51, 0);
 > 
 > 
 > void sensor::mainloop()
 > {
 > 
 > 
 > 	//set up serial read
 > 	struct rtser_event rx_event;
 > 	rtser_status_t serstatus;
 > 	int numread,err;
 > 
 > 		 while(1)
 > 		 {
 > 			if(exitprogram)		//
 > 				 break;
 > 
 > 			err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
 > 

As I already said, using read with timeout directly without first
calling ioctl leads to a better latency because of the fewer system
calls.

 > 			if (err)
 > 			{
 > 				printf(RTASK_PREFIX
 > 					       "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
 > 				  strerror(-err));
 > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
 > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
 > 
 > 			}
 > 
 > 			else
 > 			{
 > 				numread = rt_dev_read(read_fd, buf, 1);
 > 				{
 > 					printf(RTASK_PREFIX "error on rt_dev_read, code %d %s\n",numread,
 > 					       strerror(-numread));
 > 					err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
 > 					printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
 > 					continue;
 > 				}
 > 			else
 > 			{
 > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);  //if data received normally, make sure 96 was received, 98 = overrun
 > 				if(!serstatus.line_status==96)
 > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
 > 			}

On compilers I know if () { } else { } else {} does not even
compile. Are you sure you are showing us the code you are really running
? Have you tried T_WARNSW as I suggested in a previous mail ?

At what frequency do characters arrive on the serial line ? Did you try
to run the latency test with the same frequency to see if Xenomai on
your hardware is able to support this frequency ? Try latency -t 1 or -t
2 to see if switching to kernel-space would improve situation. Do you
observe unexpected peaks (such as those caused by SMIs) when running
latency ?

Is not it possible to enable hardware buffering so as to receive more
than one character at a time when overflow occurs ?

If you need ultra-high frequencies, you should probably write some part
of your application (at least the real-time control loop) in
kernel-space.

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24  6:43                     ` Gilles Chanteperdrix
@ 2008-04-24  7:04                       ` Jan Kiszka
  2008-04-24 14:16                         ` Karch, Joshua
  2008-04-24 13:59                       ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
  1 sibling, 1 reply; 30+ messages in thread
From: Jan Kiszka @ 2008-04-24  7:04 UTC (permalink / raw)
  To: Gilles Chanteperdrix, Karch, Joshua; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 3512 bytes --]

Gilles Chanteperdrix wrote:
> Karch, Joshua wrote:
>  > Gilles, (and anyone else who has had overrun errors or has experience with the Xenomai serial port driver)
>  > 
>  > It seems that even though I turned off fprintf and even though I stopped logging to disk, I still get the same number of overrun errors.  I broke the loop down to the bare basics.
>  > 
>  > my task now consists of the following
>  > 
>  > Task was launched as follows:rt_task_create(&read_task, "read_task", 0, 51, 0);
>  > 
>  > 
>  > void sensor::mainloop()
>  > {
>  > 
>  > 
>  > 	//set up serial read
>  > 	struct rtser_event rx_event;
>  > 	rtser_status_t serstatus;
>  > 	int numread,err;
>  > 
>  > 		 while(1)
>  > 		 {
>  > 			if(exitprogram)		//
>  > 				 break;
>  > 
>  > 			err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
>  > 
> 
> As I already said, using read with timeout directly without first
> calling ioctl leads to a better latency because of the fewer system
> calls.
> 
>  > 			if (err)
>  > 			{
>  > 				printf(RTASK_PREFIX
>  > 					       "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
>  > 				  strerror(-err));
>  > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
>  > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
>  > 
>  > 			}
>  > 
>  > 			else
>  > 			{
>  > 				numread = rt_dev_read(read_fd, buf, 1);
>  > 				{
>  > 					printf(RTASK_PREFIX "error on rt_dev_read, code %d %s\n",numread,
>  > 					       strerror(-numread));
>  > 					err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
>  > 					printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
>  > 					continue;
>  > 				}
>  > 			else
>  > 			{
>  > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);  //if data received normally, make sure 96 was received, 98 = overrun
>  > 				if(!serstatus.line_status==96)
>  > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
>  > 			}
> 
> On compilers I know if () { } else { } else {} does not even
> compile. Are you sure you are showing us the code you are really running
> ? Have you tried T_WARNSW as I suggested in a previous mail ?
> 
> At what frequency do characters arrive on the serial line ? Did you try
> to run the latency test with the same frequency to see if Xenomai on
> your hardware is able to support this frequency ? Try latency -t 1 or -t
> 2 to see if switching to kernel-space would improve situation. Do you
> observe unexpected peaks (such as those caused by SMIs) when running
> latency ?
> 
> Is not it possible to enable hardware buffering so as to receive more
> than one character at a time when overflow occurs ?
> 
> If you need ultra-high frequencies, you should probably write some part
> of your application (at least the real-time control loop) in
> kernel-space.

The 16650A driver architecture is know to be able to handle multiple
500kBit/s serial streams on a Pentium III 700 box (granted, with 128
byte RX fifos then).

But if you are at the limits of your system can be analyzed via
/proc/xenomai/stat (see also the Wiki, IIRC). If you aren't, you should
check of you box suffers from hardware-related latency peaks. What do
standard Xenomai latency tools tell you about this (like 'latency')?

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24  6:43                     ` Gilles Chanteperdrix
  2008-04-24  7:04                       ` Jan Kiszka
@ 2008-04-24 13:59                       ` Karch, Joshua
  2008-04-24 14:01                         ` Gilles Chanteperdrix
  1 sibling, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-24 13:59 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 4880 bytes --]


Gilles,

You're right about the code formatting-- when I cut and paste the code in I removed some unneeded code- the other else is within a nested if statement. I had errors with or without the extra ioctl.  Without the extra ioctl for RTSER_RTIOC_WAIT_EVENT my number of errors is about once every 8 seconds(basically commented out the first if else statement).  My baud rate is 115200, but I only receive 2520 bytes per second (45 bytes at 50 Hz).  I am using a Versalogic Puma board PC/104 with a Geode GX2.  It uses a CS5536 chipset.  I will try the T_WARNSW option now.

Thank you,
Joshua Karch





			if (err)
			{
				printf(RTASK_PREFIX
					       "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
				  strerror(-err));
				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);

			}

			else
			{
				numread = rt_dev_read(read_fd, buf, 1);
							
							if(numread<0)
							{

								printf(RTASK_PREFIX "error on rt_dev_read, code %d %s\n",numread,
								       strerror(-numread));
								err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
								printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
								
								continue;
							}
							else
							{
								err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);

																if(!serstatus.line_status==96)
																	printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
								//SENSORID=midgpacket->processChar(buf[0]);
							}

			}



-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Thu 4/24/2008 2:43 AM
To: Karch, Joshua
Cc: xenomai@xenomai.org
Subject: Re: serial port overrun problem RT TASK
 
Karch, Joshua wrote:
 > Gilles, (and anyone else who has had overrun errors or has experience with the Xenomai serial port driver)
 > 
 > It seems that even though I turned off fprintf and even though I stopped logging to disk, I still get the same number of overrun errors.  I broke the loop down to the bare basics.
 > 
 > my task now consists of the following
 > 
 > Task was launched as follows:rt_task_create(&read_task, "read_task", 0, 51, 0);
 > 
 > 
 > void sensor::mainloop()
 > {
 > 
 > 
 > 	//set up serial read
 > 	struct rtser_event rx_event;
 > 	rtser_status_t serstatus;
 > 	int numread,err;
 > 
 > 		 while(1)
 > 		 {
 > 			if(exitprogram)		//
 > 				 break;
 > 
 > 			err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
 > 

As I already said, using read with timeout directly without first
calling ioctl leads to a better latency because of the fewer system
calls.

 > 			if (err)
 > 			{
 > 				printf(RTASK_PREFIX
 > 					       "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
 > 				  strerror(-err));
 > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
 > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
 > 
 > 			}
 > 
 > 			else
 > 			{
 > 				numread = rt_dev_read(read_fd, buf, 1);
 > 				{
 > 					printf(RTASK_PREFIX "error on rt_dev_read, code %d %s\n",numread,
 > 					       strerror(-numread));
 > 					err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
 > 					printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
 > 					continue;
 > 				}
 > 			else
 > 			{
 > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);  //if data received normally, make sure 96 was received, 98 = overrun
 > 				if(!serstatus.line_status==96)
 > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
 > 			}

On compilers I know if () { } else { } else {} does not even
compile. Are you sure you are showing us the code you are really running
? Have you tried T_WARNSW as I suggested in a previous mail ?

At what frequency do characters arrive on the serial line ? Did you try
to run the latency test with the same frequency to see if Xenomai on
your hardware is able to support this frequency ? Try latency -t 1 or -t
2 to see if switching to kernel-space would improve situation. Do you
observe unexpected peaks (such as those caused by SMIs) when running
latency ?

Is not it possible to enable hardware buffering so as to receive more
than one character at a time when overflow occurs ?

If you need ultra-high frequencies, you should probably write some part
of your application (at least the real-time control loop) in
kernel-space.

-- 


					    Gilles.


[-- Attachment #2: Type: text/html, Size: 18898 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24 13:59                       ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
@ 2008-04-24 14:01                         ` Gilles Chanteperdrix
  0 siblings, 0 replies; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-24 14:01 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

On Thu, Apr 24, 2008 at 3:59 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>
>
>
>
> Gilles,
>
>  You're right about the code formatting-- when I cut and paste the code in I
> removed some unneeded code- the other else is within a nested if statement.
> I had errors with or without the extra ioctl.  Without the extra ioctl for
> RTSER_RTIOC_WAIT_EVENT my number of errors is about once every 8
> seconds(basically commented out the first if else statement).  My baud rate
> is 115200, but I only receive 2520 bytes per second (45 bytes at 50 Hz).  I
> am using a Versalogic Puma board PC/104 with a Geode GX2.  It uses a CS5536
> chipset.  I will try the T_WARNSW option now.

The first thing to do is to run the latency test to see if you have
hardware problems.

-- 
 Gilles


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24  7:04                       ` Jan Kiszka
@ 2008-04-24 14:16                         ` Karch, Joshua
  2008-04-24 14:30                           ` Gilles Chanteperdrix
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-24 14:16 UTC (permalink / raw)
  To: Jan Kiszka, xenomai

[-- Attachment #1: Type: text/plain, Size: 6326 bytes --]


Jan,  I'm running a Geode GX2 processor with a CS5536 chipset.  It's a Versalogic Puma board with a 16550A 16 byte buffer fifo.  I really need to have the interrupt trigger on byte at a time.  I usually receive 45 bytes at 50 Hz at a data rate of 115200.  Occasionally I receive larger or smaller packets, which is why I need byte at a time.  I'm using this to drive a control system.  I actually need to control 3 serial ports like this.

Here is /proc/xenomai/stat in idle mode
 
:~# cat /proc/xenomai/stat
CPU  PID    MSW        CSW        PF    STAT       %CPU  NAME
  0  0      0          18270412   0     00500080   99.5  ROOT
  0  0      0          40165525   0     00000000    0.4  IRQ0: [timer]


Latency did not work with -t1 or -t2  couldn't find benchmark device, error code -19.  I think the benchmark drivers have to be installed.


monkeyant:/usr/xenomai/bin# ./latency
== Sampling period: 100 us
== Test mode: periodic user-mode task
== All results in microseconds
warming up...
RTT|  00:00:01  (periodic user-mode task, 100 us period, priority 99)
RTH|-----lat min|-----lat avg|-----lat max|-overrun|----lat best|---lat worst
RTD|     -62.020|     -39.391|    1656.075|     138|     -62.020|    1656.075
RTD|     -56.991|     -38.553|    1965.333|     272|     -62.020|    1965.333
RTD|     -56.153|     -38.553|    1682.056|     405|     -62.020|    1965.333
RTD|     -56.991|     -37.715|    1695.466|     540|     -62.020|    1965.333
RTD|     -56.991|     -38.553|    1962.818|     674|     -62.020|    1965.333
RTD|     -56.153|     -38.553|    1675.352|     810|     -62.020|    1965.333
RTD|     -56.991|     -38.553|    1661.942|     946|     -62.020|    1965.333
RTD|     -56.991|     -38.553|    2055.847|    1083|     -62.020|    2055.847
RTD|     -56.991|     -38.553|    1682.056|    1227|     -62.020|    2055.847
RTD|     -56.153|     -38.553|    1652.723|    1360|     -62.020|    2055.847
RTD|     -56.153|     -38.553|    1961.142|    1498|     -62.020|    2055.847
RTD|     -56.991|     -38.553|    1702.171|    1632|     -62.020|    2055.847
RTD|     -56.991|     -38.553|    1660.266|    1771|     -62.020|    2055.847
RTD|     -56.153|     -38.553|    1967.009|    1904|     -62.020|    2055.847
RTD|     -56.991|     -38.553|    1681.218|    2049|     -62.020|    2055.847
RTD|     -56.991|     -38.553|    1669.485|    2189|     -62.020|    2055.847
RTD|     -56.153|     -38.553|    1951.085|    2319|     -62.020|    2055.847

Any ideas?

Thank you,

Joshua Karch










-----Original Message-----
From: Jan Kiszka [mailto:jan.kiszka@domain.hid]
Sent: Thu 4/24/2008 3:04 AM
To: Gilles Chanteperdrix; Karch, Joshua
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] serial port overrun problem RT TASK
 
Gilles Chanteperdrix wrote:
> Karch, Joshua wrote:
>  > Gilles, (and anyone else who has had overrun errors or has experience with the Xenomai serial port driver)
>  > 
>  > It seems that even though I turned off fprintf and even though I stopped logging to disk, I still get the same number of overrun errors.  I broke the loop down to the bare basics.
>  > 
>  > my task now consists of the following
>  > 
>  > Task was launched as follows:rt_task_create(&read_task, "read_task", 0, 51, 0);
>  > 
>  > 
>  > void sensor::mainloop()
>  > {
>  > 
>  > 
>  > 	//set up serial read
>  > 	struct rtser_event rx_event;
>  > 	rtser_status_t serstatus;
>  > 	int numread,err;
>  > 
>  > 		 while(1)
>  > 		 {
>  > 			if(exitprogram)		//
>  > 				 break;
>  > 
>  > 			err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
>  > 
> 
> As I already said, using read with timeout directly without first
> calling ioctl leads to a better latency because of the fewer system
> calls.
> 
>  > 			if (err)
>  > 			{
>  > 				printf(RTASK_PREFIX
>  > 					       "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
>  > 				  strerror(-err));
>  > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
>  > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
>  > 
>  > 			}
>  > 
>  > 			else
>  > 			{
>  > 				numread = rt_dev_read(read_fd, buf, 1);
>  > 				{
>  > 					printf(RTASK_PREFIX "error on rt_dev_read, code %d %s\n",numread,
>  > 					       strerror(-numread));
>  > 					err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);
>  > 					printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
>  > 					continue;
>  > 				}
>  > 			else
>  > 			{
>  > 				err = rt_dev_ioctl(read_fd, RTSER_RTIOC_GET_STATUS, &serstatus);  //if data received normally, make sure 96 was received, 98 = overrun
>  > 				if(!serstatus.line_status==96)
>  > 				printf(RTASK_PREFIX "Error code line_status=%d modem_status=%d\n",serstatus.line_status, serstatus.modem_status);
>  > 			}
> 
> On compilers I know if () { } else { } else {} does not even
> compile. Are you sure you are showing us the code you are really running
> ? Have you tried T_WARNSW as I suggested in a previous mail ?
> 
> At what frequency do characters arrive on the serial line ? Did you try
> to run the latency test with the same frequency to see if Xenomai on
> your hardware is able to support this frequency ? Try latency -t 1 or -t
> 2 to see if switching to kernel-space would improve situation. Do you
> observe unexpected peaks (such as those caused by SMIs) when running
> latency ?
> 
> Is not it possible to enable hardware buffering so as to receive more
> than one character at a time when overflow occurs ?
> 
> If you need ultra-high frequencies, you should probably write some part
> of your application (at least the real-time control loop) in
> kernel-space.

The 16650A driver architecture is know to be able to handle multiple
500kBit/s serial streams on a Pentium III 700 box (granted, with 128
byte RX fifos then).

But if you are at the limits of your system can be analyzed via
/proc/xenomai/stat (see also the Wiki, IIRC). If you aren't, you should
check of you box suffers from hardware-related latency peaks. What do
standard Xenomai latency tools tell you about this (like 'latency')?

Jan



[-- Attachment #2: Type: text/html, Size: 14175 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24 14:16                         ` Karch, Joshua
@ 2008-04-24 14:30                           ` Gilles Chanteperdrix
  2008-04-24 16:58                             ` Karch, Joshua
  0 siblings, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-24 14:30 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai, Jan Kiszka

On Thu, Apr 24, 2008 at 4:16 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>  RTD|     -56.153|     -38.553|    1951.085|    2319|     -62.020|
> 2055.847
>
>  Any ideas?

You definitely have a hardware issue. Geode are known for at least two things:
- they may stop their tsc when idle, this is bad since Xenomai relies
on a continuously ticking tsc, AFAIK, this can be worked around by
passing the idle=poll parameter on the kernel command line;
- they may use SMI, fortunately SMIs may be disabled with a few outbs,
as explained in this
https://mail.rtai.org/pipermail/rtai/2005-July/012474.html

ISTR that there are issues with graphic mode, and the workaround may
be to switch to framebuffer mode, but I am not sure.

Look for geode in RTAI mailing list archives to find additional informations.
When this is done, it would be nice if you could create a page about
Geode on Xenomai wiki summarizing your findings.

-- 
 Gilles


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24 14:30                           ` Gilles Chanteperdrix
@ 2008-04-24 16:58                             ` Karch, Joshua
  2008-04-24 17:16                               ` Gilles Chanteperdrix
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-24 16:58 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai, Jan Kiszka

[-- Attachment #1: Type: text/plain, Size: 1593 bytes --]


Gilles, Jan,

I tried idle=poll and disabling smi in a new kernel, and that brought the error rate down to once every 30 seconds  Worst case latency dropped to 1763 uS

This Geode GX500 (GX2) seems to have some compatibility problems with the Xenomai system.

I'm still unable to open the benchmark device code -19 when running latency -t 2


Thank you,
Joshua Karch.


-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Thu 4/24/2008 10:30 AM
To: Karch, Joshua
Cc: Jan Kiszka; xenomai@xenomai.org
Subject: Re: [Xenomai-help] serial port overrun problem RT TASK
 
On Thu, Apr 24, 2008 at 4:16 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>  RTD|     -56.153|     -38.553|    1951.085|    2319|     -62.020|
> 2055.847
>
>  Any ideas?

You definitely have a hardware issue. Geode are known for at least two things:
- they may stop their tsc when idle, this is bad since Xenomai relies
on a continuously ticking tsc, AFAIK, this can be worked around by
passing the idle=poll parameter on the kernel command line;
- they may use SMI, fortunately SMIs may be disabled with a few outbs,
as explained in this
https://mail.rtai.org/pipermail/rtai/2005-July/012474.html

ISTR that there are issues with graphic mode, and the workaround may
be to switch to framebuffer mode, but I am not sure.

Look for geode in RTAI mailing list archives to find additional informations.
When this is done, it would be nice if you could create a page about
Geode on Xenomai wiki summarizing your findings.

-- 
 Gilles


[-- Attachment #2: Type: text/html, Size: 2422 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK
  2008-04-24 16:58                             ` Karch, Joshua
@ 2008-04-24 17:16                               ` Gilles Chanteperdrix
  2008-04-24 22:37                                 ` [Xenomai-help] serial port overrun problem RT TASK geode latencies too high Karch, Joshua
  0 siblings, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-24 17:16 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai, Jan Kiszka

Karch, Joshua wrote:
 > 
 > Gilles, Jan,
 > 
 > I tried idle=poll and disabling smi in a new kernel, and that brought the error rate down to once every 30 seconds  Worst case latency dropped to 1763 uS

A worst case latency of 1ms is way too high. You still have an hardware
issue. How do you disable SMI ? Do you use the outbs from the link I
sent ? Maybe they are for Geode GX1, and you have a Geode GX2. You
should look for the proper outb in a geode GX2 datasheet.

Have you kept away from the CPUFREQ and ACPI_PROCESSOR options ? Did you
check the BIOS settings ?

Also, what about the graphical problem ? Did you switch to framebuffer ?

 > 
 > This Geode GX500 (GX2) seems to have some compatibility problems with the Xenomai system.

These are just problems due to power saving, but there should hopefully
be workarounds. Also notes that these problems are not specific to
Xenomai, they also happen with Linux. Only, they are not considered
abnormal. There are people actually using happily Xenomai on Geode
processors.

 > 
 > I'm still unable to open the benchmark device code -19 when running latency -t 2

Have you enabled the timerbench driver in xenomai configuration ?

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK geode latencies too high
  2008-04-24 17:16                               ` Gilles Chanteperdrix
@ 2008-04-24 22:37                                 ` Karch, Joshua
  2008-04-24 22:59                                   ` Gilles Chanteperdrix
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-24 22:37 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai, Jan Kiszka

[-- Attachment #1: Type: text/plain, Size: 1858 bytes --]

Gilles,

The framebuffer support was added to the kernel, and magically the latency is now down to the 1300 range. I modprobed the timerbench module and so the number 1340 is the worst I've seen.   The next thing to do is to play around with the outb and SMI. I got to the point where I haven't found any errors in a two minute test.

Take care,

Josh


-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Thu 4/24/2008 1:16 PM
To: Karch, Joshua
Cc: Jan Kiszka; xenomai@xenomai.org
Subject: RE: [Xenomai-help] serial port overrun problem RT TASK
 
Karch, Joshua wrote:
 > 
 > Gilles, Jan,
 > 
 > I tried idle=poll and disabling smi in a new kernel, and that brought the error rate down to once every 30 seconds  Worst case latency dropped to 1763 uS

A worst case latency of 1ms is way too high. You still have an hardware
issue. How do you disable SMI ? Do you use the outbs from the link I
sent ? Maybe they are for Geode GX1, and you have a Geode GX2. You
should look for the proper outb in a geode GX2 datasheet.

Have you kept away from the CPUFREQ and ACPI_PROCESSOR options ? Did you
check the BIOS settings ?

Also, what about the graphical problem ? Did you switch to framebuffer ?

 > 
 > This Geode GX500 (GX2) seems to have some compatibility problems with the Xenomai system.

These are just problems due to power saving, but there should hopefully
be workarounds. Also notes that these problems are not specific to
Xenomai, they also happen with Linux. Only, they are not considered
abnormal. There are people actually using happily Xenomai on Geode
processors.

 > 
 > I'm still unable to open the benchmark device code -19 when running latency -t 2

Have you enabled the timerbench driver in xenomai configuration ?

-- 


					    Gilles.


[-- Attachment #2: Type: text/html, Size: 2835 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] serial port overrun problem RT TASK geode latencies too high
  2008-04-24 22:37                                 ` [Xenomai-help] serial port overrun problem RT TASK geode latencies too high Karch, Joshua
@ 2008-04-24 22:59                                   ` Gilles Chanteperdrix
  2008-04-25 16:04                                     ` [Xenomai-help] Geode Latency Problem (Was: serial port overrun problem) Karch, Joshua
  0 siblings, 1 reply; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-24 22:59 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai, Jan Kiszka

Karch, Joshua wrote:
 > Gilles,
 > 
 > The framebuffer support was added to the kernel, and magically the latency is now down to the 1300 range. I modprobed the timerbench module and so the number 1340 is the worst I've seen.   The next thing to do is to play around with the outb and SMI. I got to the point where I haven't found any errors in a two minute test.

1300 is still way too high. A normal latency is something less than
100us, probably even less than 50us. 

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Xenomai-help] Geode Latency Problem (Was: serial port overrun problem)
  2008-04-24 22:59                                   ` Gilles Chanteperdrix
@ 2008-04-25 16:04                                     ` Karch, Joshua
  2008-04-25 16:12                                       ` Gilles Chanteperdrix
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-25 16:04 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai, Jan Kiszka

[-- Attachment #1: Type: text/plain, Size: 1813 bytes --]

Gilles, Jan,

we disabled "System Management Mode" in the Geode GX500 (Versalogic Puma) bios which disables USB, all Video, ethernet-- everything.  We enabled the Getty serial console and boot from serial in Grub, and booted linux off of the serial port which we'd eventually like to use for our sensor acquisition.  However, upon running latency -t2, our latencies dropped to 40 usec max.  Amazing!    We used VGA mode 791 in the kernel options before and got a reduction by 400 usec.  The thing is-- we still need ethernet, and we need our serial port for our RT work.  Also, in order to get out of System Management Mode we have to reset the bios by jumper since there is no serial menu.  Any ideas?

We looked through all of the forums and were not able to find any more information as to how to selectively disable the unwanted SMI calls that are causing the latency.  We definitely would like basic video, though primarily we only need ethernet and serial, and then we can ssh in.

Sincerely,

Joshua Karch



-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
Sent: Thu 4/24/2008 6:59 PM
To: Karch, Joshua
Cc: Jan Kiszka; xenomai@xenomai.org
Subject: RE: [Xenomai-help] serial port overrun problem RT TASK geode latencies too high
 
Karch, Joshua wrote:
 > Gilles,
 > 
 > The framebuffer support was added to the kernel, and magically the latency is now down to the 1300 range. I modprobed the timerbench module and so the number 1340 is the worst I've seen.   The next thing to do is to play around with the outb and SMI. I got to the point where I haven't found any errors in a two minute test.

1300 is still way too high. A normal latency is something less than
100us, probably even less than 50us. 

-- 


					    Gilles.


[-- Attachment #2: Type: text/html, Size: 2708 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Geode Latency Problem (Was: serial port overrun problem)
  2008-04-25 16:04                                     ` [Xenomai-help] Geode Latency Problem (Was: serial port overrun problem) Karch, Joshua
@ 2008-04-25 16:12                                       ` Gilles Chanteperdrix
  0 siblings, 0 replies; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-25 16:12 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai, Jan Kiszka

On Fri, Apr 25, 2008 at 6:04 PM, Karch, Joshua <jkarch@domain.hid> wrote:
>
>
>
> Gilles, Jan,
>
>  we disabled "System Management Mode" in the Geode GX500 (Versalogic Puma)
> bios which disables USB, all Video, ethernet-- everything.  We enabled the
> Getty serial console and boot from serial in Grub, and booted linux off of
> the serial port which we'd eventually like to use for our sensor
> acquisition.  However, upon running latency -t2, our latencies dropped to 40
> usec max.  Amazing!    We used VGA mode 791 in the kernel options before and
> got a reduction by 400 usec.  The thing is-- we still need ethernet, and we
> need our serial port for our RT work.  Also, in order to get out of System
> Management Mode we have to reset the bios by jumper since there is no serial
> menu.  Any ideas?
>
>  We looked through all of the forums and were not able to find any more
> information as to how to selectively disable the unwanted SMI calls that are
> causing the latency.  We definitely would like basic video, though primarily
> we only need ethernet and serial, and then we can ssh in.

The CS5530 geode companion chip seems to offer function-per-function
SMI control bit.
http://alsa.cybermirror.org/datasheets/nsc/CS5530.pdf

-- 
 Gilles


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Xenomai-help] Segfault Problems with Message Queues
       [not found]                     ` <48187366.2060006@domain.hid>
@ 2008-04-30 18:13                       ` Karch, Joshua
  2008-04-30 18:31                         ` Philippe Gerum
                                           ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Karch, Joshua @ 2008-04-30 18:13 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 3455 bytes --]

Hi All,

I tried implementing inter-task message queues and following the msg_queue.c example
(http://www.xenomai.org/documentation/trunk/html/api/msg__queue_8c-example.html)
and when I try to run the implementation after fixing some of the code (declaring fail() to printf an error, declaring int err, and changing &task_body to &consumer), I get the following error
msg_queue[3897]: segfault at 00000000 eip b7cf8933 esp bf8dce04 error 6.  This comes out of the rt_queue_alloc function.

Has the implementation of message passing between userspace tasks changed?  Is there a more recent example?  My end goal is to send non blocking messages from one producer task at 50Hz to two reading tasks tasks with similar (though not exactly same) loop rates-- i.e. None of the tasks are synchronized, though they all run at about 50Hz.  Should I use message queues to do this?

Thank you,

Joshua Karch

Attached is the code I used..

#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <native/task.h>
#include <native/queue.h>

#define TASK_PRIO  99 /* Highest RT priority */
#define TASK_MODE  0  /* No flags */
#define TASK_STKSZ 0  /* Stack size (use default one) */

RT_QUEUE q_desc;

RT_TASK task_desc;

void fail()
{
	printf("error\n");
}


void consumer (void *cookie)

{
    ssize_t len;
    void *msg;
    int err;

    /* Bind to a queue which has been created elsewhere, either in
       kernel or user-space. The call will block us until such queue
       is created with the expected name. The queue should have been
       created with the Q_SHARED mode set, which is implicit when
       creation takes place in user-space. */

    err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);

    if (err)
        fail();

    /* Collect each message sent to the queue by the queuer() routine,
       until the queue is eventually removed from the system by a call
       to rt_queue_delete(). */

    while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
        {
        printf("received message> len=%d bytes, ptr=%p, s=%s\n",
               len,msg,(const char *)msg);
        rt_queue_free(&q_desc,msg);
        }

    /* We need to unbind explicitly from the queue in order to
       properly release the underlying memory mapping. Exiting the
       process unbinds all mappings automatically. */

    rt_queue_unbind(&q_desc);

    if (len != -EIDRM)
        /* We received some unexpected error notification. */
        fail();

    /* ... */
}


int main (int argc, char *argv[])

{
    static char *messages[] = { "hello", "world", NULL };
    int n, len;
    void *msg;
    int err;

    mlockall(MCL_CURRENT|MCL_FUTURE);

    err = rt_task_create(&task_desc,
                         "MyTaskName",
                         TASK_STKSZ,
                         TASK_PRIO,
                         TASK_MODE);
    if (!err)
        rt_task_start(&task_desc,&consumer,NULL);

    /* ... */

    for (n = 0; messages[n] != NULL; n++)
        {
        len = strlen(messages[n]) + 1;
        /* Get a message block of the right size. */
        msg = rt_queue_alloc(&q_desc,len);

        if (!msg)
            /* No memory available. */
            fail();

        strcpy((char *)msg,messages[n]);
        rt_queue_send(&q_desc,msg,len,Q_NORMAL);
        }

    rt_task_delete(&task_desc);
}


[-- Attachment #2: Type: text/html, Size: 6408 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Segfault Problems with Message Queues
  2008-04-30 18:13                       ` [Xenomai-help] Segfault Problems with Message Queues Karch, Joshua
@ 2008-04-30 18:31                         ` Philippe Gerum
  2008-04-30 18:41                           ` Karch, Joshua
  2008-04-30 18:36                         ` Philippe Gerum
  2008-04-30 19:19                         ` Gilles Chanteperdrix
  2 siblings, 1 reply; 30+ messages in thread
From: Philippe Gerum @ 2008-04-30 18:31 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
> Hi All,
> 
> I tried implementing inter-task message queues and following the
> msg_queue.c example
> (http://www.xenomai.org/documentation/trunk/html/api/msg__queue_8c-example.html)
> and when I try to run the implementation after fixing some of the code
> (declaring fail() to printf an error, declaring int err, and changing
> &task_body to &consumer), I get the following error
> msg_queue[3897]: segfault at 00000000 eip b7cf8933 esp bf8dce04 error
> 6.  This comes out of the rt_queue_alloc function.
> 
> Has the implementation of message passing between userspace tasks
> changed?  Is there a more recent example?  My end goal is to send non
> blocking messages from one producer task at 50Hz to two reading tasks
> tasks with similar (though not exactly same) loop rates-- i.e. None of
> the tasks are synchronized, though they all run at about 50Hz.  Should I
> use message queues to do this?
> 
> Thank you,
> 
> Joshua Karch
> 
> Attached is the code I used..
> 
> #include <sys/mman.h>
> #include <stdio.h>
> #include <string.h>
> #include <native/task.h>
> #include <native/queue.h>
> 
> #define TASK_PRIO  99 /* Highest RT priority */
> #define TASK_MODE  0  /* No flags */
> #define TASK_STKSZ 0  /* Stack size (use default one) */
> 
> RT_QUEUE q_desc;
> 
> RT_TASK task_desc;
> 

We need to know whether an error actually occurred. Nothing guarantees us that
all stdio buffers would be flushed upon SEGV. Does the executable still behave
the same way with that patch?

> void fail()
> {
>         printf("error\n");

+	exit(99);
> }
> 
> 
> void consumer (void *cookie)
> 
> {
>     ssize_t len;
>     void *msg;
>     int err;
> 
>     /* Bind to a queue which has been created elsewhere, either in
>        kernel or user-space. The call will block us until such queue
>        is created with the expected name. The queue should have been
>        created with the Q_SHARED mode set, which is implicit when
>        creation takes place in user-space. */
> 
>     err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
> 
>     if (err)
>         fail();
> 
>     /* Collect each message sent to the queue by the queuer() routine,
>        until the queue is eventually removed from the system by a call
>        to rt_queue_delete(). */
> 
>     while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
>         {
>         printf("received message> len=%d bytes, ptr=%p, s=%s\n",
>                len,msg,(const char *)msg);
>         rt_queue_free(&q_desc,msg);
>         }
> 
>     /* We need to unbind explicitly from the queue in order to
>        properly release the underlying memory mapping. Exiting the
>        process unbinds all mappings automatically. */
> 
>     rt_queue_unbind(&q_desc);
> 
>     if (len != -EIDRM)
>         /* We received some unexpected error notification. */
>         fail();
> 
>     /* ... */
> }
> 
> 
> int main (int argc, char *argv[])
> 
> {
>     static char *messages[] = { "hello", "world", NULL };
>     int n, len;
>     void *msg;
>     int err;
> 
>     mlockall(MCL_CURRENT|MCL_FUTURE);
> 
>     err = rt_task_create(&task_desc,
>                          "MyTaskName",
>                          TASK_STKSZ,
>                          TASK_PRIO,
>                          TASK_MODE);
>     if (!err)
>         rt_task_start(&task_desc,&consumer,NULL);
> 
>     /* ... */
> 
>     for (n = 0; messages[n] != NULL; n++)
>         {
>         len = strlen(messages[n]) + 1;
>         /* Get a message block of the right size. */
>         msg = rt_queue_alloc(&q_desc,len);
> 
>         if (!msg)
>             /* No memory available. */
>             fail();
> 
>         strcpy((char *)msg,messages[n]);
>         rt_queue_send(&q_desc,msg,len,Q_NORMAL);
>         }
> 
>     rt_task_delete(&task_desc);
> }
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help


-- 
Philippe.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Segfault Problems with Message Queues
  2008-04-30 18:13                       ` [Xenomai-help] Segfault Problems with Message Queues Karch, Joshua
  2008-04-30 18:31                         ` Philippe Gerum
@ 2008-04-30 18:36                         ` Philippe Gerum
  2008-04-30 19:19                         ` Gilles Chanteperdrix
  2 siblings, 0 replies; 30+ messages in thread
From: Philippe Gerum @ 2008-04-30 18:36 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
> Hi All,
> 
> I tried implementing inter-task message queues and following the
> msg_queue.c example
> (http://www.xenomai.org/documentation/trunk/html/api/msg__queue_8c-example.html)
> and when I try to run the implementation after fixing some of the code
> (declaring fail() to printf an error, declaring int err, and changing
> &task_body to &consumer), I get the following error
> msg_queue[3897]: segfault at 00000000 eip b7cf8933 esp bf8dce04 error
> 6.  This comes out of the rt_queue_alloc function.
> 
> Has the implementation of message passing between userspace tasks
> changed?  Is there a more recent example?  My end goal is to send non
> blocking messages from one producer task at 50Hz to two reading tasks
> tasks with similar (though not exactly same) loop rates-- i.e. None of
> the tasks are synchronized, though they all run at about 50Hz.  Should I
> use message queues to do this?
>

Btw, that code skeleton was meant to be paired with a peer module in
kernel/userland that would create the queue. Nothing in this code does this; you
need to call rt_queue_create() at init to create the queue the consumer task
will bind to.

> Thank you,
> 
> Joshua Karch
> 
> Attached is the code I used..
> 
> #include <sys/mman.h>
> #include <stdio.h>
> #include <string.h>
> #include <native/task.h>
> #include <native/queue.h>
> 
> #define TASK_PRIO  99 /* Highest RT priority */
> #define TASK_MODE  0  /* No flags */
> #define TASK_STKSZ 0  /* Stack size (use default one) */
> 
> RT_QUEUE q_desc;
> 
> RT_TASK task_desc;
> 
> void fail()
> {
>         printf("error\n");
> }
> 
> 
> void consumer (void *cookie)
> 
> {
>     ssize_t len;
>     void *msg;
>     int err;
> 
>     /* Bind to a queue which has been created elsewhere, either in
>        kernel or user-space. The call will block us until such queue
>        is created with the expected name. The queue should have been
>        created with the Q_SHARED mode set, which is implicit when
>        creation takes place in user-space. */
> 
>     err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
> 
>     if (err)
>         fail();
> 
>     /* Collect each message sent to the queue by the queuer() routine,
>        until the queue is eventually removed from the system by a call
>        to rt_queue_delete(). */
> 
>     while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
>         {
>         printf("received message> len=%d bytes, ptr=%p, s=%s\n",
>                len,msg,(const char *)msg);
>         rt_queue_free(&q_desc,msg);
>         }
> 
>     /* We need to unbind explicitly from the queue in order to
>        properly release the underlying memory mapping. Exiting the
>        process unbinds all mappings automatically. */
> 
>     rt_queue_unbind(&q_desc);
> 
>     if (len != -EIDRM)
>         /* We received some unexpected error notification. */
>         fail();
> 
>     /* ... */
> }
> 
> 
> int main (int argc, char *argv[])
> 
> {
>     static char *messages[] = { "hello", "world", NULL };
>     int n, len;
>     void *msg;
>     int err;
> 
>     mlockall(MCL_CURRENT|MCL_FUTURE);
> 
>     err = rt_task_create(&task_desc,
>                          "MyTaskName",
>                          TASK_STKSZ,
>                          TASK_PRIO,
>                          TASK_MODE);
>     if (!err)
>         rt_task_start(&task_desc,&consumer,NULL);
> 
>     /* ... */
> 
>     for (n = 0; messages[n] != NULL; n++)
>         {
>         len = strlen(messages[n]) + 1;
>         /* Get a message block of the right size. */
>         msg = rt_queue_alloc(&q_desc,len);
> 
>         if (!msg)
>             /* No memory available. */
>             fail();
> 
>         strcpy((char *)msg,messages[n]);
>         rt_queue_send(&q_desc,msg,len,Q_NORMAL);
>         }
> 
>     rt_task_delete(&task_desc);
> }
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help


-- 
Philippe.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Segfault Problems with Message Queues
  2008-04-30 18:31                         ` Philippe Gerum
@ 2008-04-30 18:41                           ` Karch, Joshua
  2008-04-30 18:48                             ` Philippe Gerum
  0 siblings, 1 reply; 30+ messages in thread
From: Karch, Joshua @ 2008-04-30 18:41 UTC (permalink / raw)
  To: rpm; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 4756 bytes --]


Phillipe,

I'm running 2.4.3 and compiling it on the same machine (a geode based machine).  Appending exit(99); to the next line after printf() allows the program to exit with just the "error" from printf().  No seg faults there, but it seems the rt_queue_alloc is the problem right now.

Thank you,

Joshua Karch

-----Original Message-----
From: Philippe Gerum on behalf of Philippe Gerum
Sent: Wed 4/30/2008 2:31 PM
To: Karch, Joshua
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] Segfault Problems with Message Queues
 
Karch, Joshua wrote:
> Hi All,
> 
> I tried implementing inter-task message queues and following the
> msg_queue.c example
> (http://www.xenomai.org/documentation/trunk/html/api/msg__queue_8c-example.html)
> and when I try to run the implementation after fixing some of the code
> (declaring fail() to printf an error, declaring int err, and changing
> &task_body to &consumer), I get the following error
> msg_queue[3897]: segfault at 00000000 eip b7cf8933 esp bf8dce04 error
> 6.  This comes out of the rt_queue_alloc function.
> 
> Has the implementation of message passing between userspace tasks
> changed?  Is there a more recent example?  My end goal is to send non
> blocking messages from one producer task at 50Hz to two reading tasks
> tasks with similar (though not exactly same) loop rates-- i.e. None of
> the tasks are synchronized, though they all run at about 50Hz.  Should I
> use message queues to do this?
> 
> Thank you,
> 
> Joshua Karch
> 
> Attached is the code I used..
> 
> #include <sys/mman.h>
> #include <stdio.h>
> #include <string.h>
> #include <native/task.h>
> #include <native/queue.h>
> 
> #define TASK_PRIO  99 /* Highest RT priority */
> #define TASK_MODE  0  /* No flags */
> #define TASK_STKSZ 0  /* Stack size (use default one) */
> 
> RT_QUEUE q_desc;
> 
> RT_TASK task_desc;
> 

We need to know whether an error actually occurred. Nothing guarantees us that
all stdio buffers would be flushed upon SEGV. Does the executable still behave
the same way with that patch?

> void fail()
> {
>         printf("error\n");

+	exit(99);
> }
> 
> 
> void consumer (void *cookie)
> 
> {
>     ssize_t len;
>     void *msg;
>     int err;
> 
>     /* Bind to a queue which has been created elsewhere, either in
>        kernel or user-space. The call will block us until such queue
>        is created with the expected name. The queue should have been
>        created with the Q_SHARED mode set, which is implicit when
>        creation takes place in user-space. */
> 
>     err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
> 
>     if (err)
>         fail();
> 
>     /* Collect each message sent to the queue by the queuer() routine,
>        until the queue is eventually removed from the system by a call
>        to rt_queue_delete(). */
> 
>     while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
>         {
>         printf("received message> len=%d bytes, ptr=%p, s=%s\n",
>                len,msg,(const char *)msg);
>         rt_queue_free(&q_desc,msg);
>         }
> 
>     /* We need to unbind explicitly from the queue in order to
>        properly release the underlying memory mapping. Exiting the
>        process unbinds all mappings automatically. */
> 
>     rt_queue_unbind(&q_desc);
> 
>     if (len != -EIDRM)
>         /* We received some unexpected error notification. */
>         fail();
> 
>     /* ... */
> }
> 
> 
> int main (int argc, char *argv[])
> 
> {
>     static char *messages[] = { "hello", "world", NULL };
>     int n, len;
>     void *msg;
>     int err;
> 
>     mlockall(MCL_CURRENT|MCL_FUTURE);
> 
>     err = rt_task_create(&task_desc,
>                          "MyTaskName",
>                          TASK_STKSZ,
>                          TASK_PRIO,
>                          TASK_MODE);
>     if (!err)
>         rt_task_start(&task_desc,&consumer,NULL);
> 
>     /* ... */
> 
>     for (n = 0; messages[n] != NULL; n++)
>         {
>         len = strlen(messages[n]) + 1;
>         /* Get a message block of the right size. */
>         msg = rt_queue_alloc(&q_desc,len);
> 
>         if (!msg)
>             /* No memory available. */
>             fail();
> 
>         strcpy((char *)msg,messages[n]);
>         rt_queue_send(&q_desc,msg,len,Q_NORMAL);
>         }
> 
>     rt_task_delete(&task_desc);
> }
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help


-- 
Philippe.


[-- Attachment #2: Type: text/html, Size: 8640 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Segfault Problems with Message Queues
  2008-04-30 18:41                           ` Karch, Joshua
@ 2008-04-30 18:48                             ` Philippe Gerum
  2008-04-30 19:22                               ` Karch, Joshua
  0 siblings, 1 reply; 30+ messages in thread
From: Philippe Gerum @ 2008-04-30 18:48 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
> Phillipe,
> 
> I'm running 2.4.3 and compiling it on the same machine (a geode based machine).  Appending exit(99); to the next line after printf() allows the program to exit with just the "error" from printf().  No seg faults there, but it seems the rt_queue_alloc is the problem right now.
>

You may want to pass the error code to fail() and print it out. The problem is
that you ask rt_queue_alloc() to get a block from a non-existent queue, because
the queue descriptor is invalid for the main() task. You have to call
rt_queue_create() first.

> Thank you,
> 
> Joshua Karch
> 
> -----Original Message-----
> From: Philippe Gerum on behalf of Philippe Gerum
> Sent: Wed 4/30/2008 2:31 PM
> To: Karch, Joshua
> Cc: xenomai@xenomai.org
> Subject: Re: [Xenomai-help] Segfault Problems with Message Queues
>  
> Karch, Joshua wrote:
>> Hi All,
>>
>> I tried implementing inter-task message queues and following the
>> msg_queue.c example
>> (http://www.xenomai.org/documentation/trunk/html/api/msg__queue_8c-example.html)
>> and when I try to run the implementation after fixing some of the code
>> (declaring fail() to printf an error, declaring int err, and changing
>> &task_body to &consumer), I get the following error
>> msg_queue[3897]: segfault at 00000000 eip b7cf8933 esp bf8dce04 error
>> 6.  This comes out of the rt_queue_alloc function.
>>
>> Has the implementation of message passing between userspace tasks
>> changed?  Is there a more recent example?  My end goal is to send non
>> blocking messages from one producer task at 50Hz to two reading tasks
>> tasks with similar (though not exactly same) loop rates-- i.e. None of
>> the tasks are synchronized, though they all run at about 50Hz.  Should I
>> use message queues to do this?
>>
>> Thank you,
>>
>> Joshua Karch
>>
>> Attached is the code I used..
>>
>> #include <sys/mman.h>
>> #include <stdio.h>
>> #include <string.h>
>> #include <native/task.h>
>> #include <native/queue.h>
>>
>> #define TASK_PRIO  99 /* Highest RT priority */
>> #define TASK_MODE  0  /* No flags */
>> #define TASK_STKSZ 0  /* Stack size (use default one) */
>>
>> RT_QUEUE q_desc;
>>
>> RT_TASK task_desc;
>>
> 
> We need to know whether an error actually occurred. Nothing guarantees us that
> all stdio buffers would be flushed upon SEGV. Does the executable still behave
> the same way with that patch?
> 
>> void fail()
>> {
>>         printf("error\n");
> 
> +	exit(99);
>> }
>>
>>
>> void consumer (void *cookie)
>>
>> {
>>     ssize_t len;
>>     void *msg;
>>     int err;
>>
>>     /* Bind to a queue which has been created elsewhere, either in
>>        kernel or user-space. The call will block us until such queue
>>        is created with the expected name. The queue should have been
>>        created with the Q_SHARED mode set, which is implicit when
>>        creation takes place in user-space. */
>>
>>     err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
>>
>>     if (err)
>>         fail();
>>
>>     /* Collect each message sent to the queue by the queuer() routine,
>>        until the queue is eventually removed from the system by a call
>>        to rt_queue_delete(). */
>>
>>     while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
>>         {
>>         printf("received message> len=%d bytes, ptr=%p, s=%s\n",
>>                len,msg,(const char *)msg);
>>         rt_queue_free(&q_desc,msg);
>>         }
>>
>>     /* We need to unbind explicitly from the queue in order to
>>        properly release the underlying memory mapping. Exiting the
>>        process unbinds all mappings automatically. */
>>
>>     rt_queue_unbind(&q_desc);
>>
>>     if (len != -EIDRM)
>>         /* We received some unexpected error notification. */
>>         fail();
>>
>>     /* ... */
>> }
>>
>>
>> int main (int argc, char *argv[])
>>
>> {
>>     static char *messages[] = { "hello", "world", NULL };
>>     int n, len;
>>     void *msg;
>>     int err;
>>
>>     mlockall(MCL_CURRENT|MCL_FUTURE);
>>
>>     err = rt_task_create(&task_desc,
>>                          "MyTaskName",
>>                          TASK_STKSZ,
>>                          TASK_PRIO,
>>                          TASK_MODE);
>>     if (!err)
>>         rt_task_start(&task_desc,&consumer,NULL);
>>
>>     /* ... */
>>
>>     for (n = 0; messages[n] != NULL; n++)
>>         {
>>         len = strlen(messages[n]) + 1;
>>         /* Get a message block of the right size. */
>>         msg = rt_queue_alloc(&q_desc,len);
>>
>>         if (!msg)
>>             /* No memory available. */
>>             fail();
>>
>>         strcpy((char *)msg,messages[n]);
>>         rt_queue_send(&q_desc,msg,len,Q_NORMAL);
>>         }
>>
>>     rt_task_delete(&task_desc);
>> }
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Xenomai-help mailing list
>> Xenomai-help@domain.hid
>> https://mail.gna.org/listinfo/xenomai-help
> 
> 


-- 
Philippe.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Segfault Problems with Message Queues
  2008-04-30 18:13                       ` [Xenomai-help] Segfault Problems with Message Queues Karch, Joshua
  2008-04-30 18:31                         ` Philippe Gerum
  2008-04-30 18:36                         ` Philippe Gerum
@ 2008-04-30 19:19                         ` Gilles Chanteperdrix
  2 siblings, 0 replies; 30+ messages in thread
From: Gilles Chanteperdrix @ 2008-04-30 19:19 UTC (permalink / raw)
  To: Karch, Joshua; +Cc: xenomai

Karch, Joshua wrote:
 > Hi All,

Hi Joshua,

this is unrelated to your issue, but please avoid replying a previous
mail when starting a new discussion: your new mail will appear as an
answer of the mail you replied to in all clients handling threading
properly, including xenomai mailing list archives.

See for instance:
https://mail.gna.org/public/xenomai-help/2008-04/threads.html

Regards.

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Xenomai-help] Segfault Problems with Message Queues
  2008-04-30 18:48                             ` Philippe Gerum
@ 2008-04-30 19:22                               ` Karch, Joshua
  0 siblings, 0 replies; 30+ messages in thread
From: Karch, Joshua @ 2008-04-30 19:22 UTC (permalink / raw)
  To: rpm; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 9429 bytes --]

Phillipe,

I added a bunch of printf statements in the program and added the rt_queue_create section:
err = rt_queue_create(&q_desc, "q_desc", 100, Q_UNLIMITED, Q_FIFO);
I also changed rt_task_delete to rt_task_join  to wait for the task.

Running the following program gives the following:

in consumer task
rt task started
allocated queue of size 6
message sent
allocated queue of size 6
message sent
Xenomai: native: cleaning up queue "q_desc" (ret=0)

It appears that the task never got past the following line of code:


    err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
    printf("rt_queue_bind returns %d",err);

But then I realized that the Queue Name "SomeQueueName" was different then the rt_queue_create "q_desc", fixed that, and now it seems to work.  So, I'm posting this as a simple working example of a message queue.

Thank you for your help,   my next task is to take this same example and make it work within the framework of a running loop. 

Take care,

Joshua Karch

#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <native/task.h>
#include <native/queue.h>

#define TASK_PRIO  99 /* Highest RT priority */
#define TASK_MODE  0  /* No flags */
#define TASK_STKSZ 0  /* Stack size (use default one) */

RT_QUEUE q_desc;

RT_TASK task_desc;



void consumer (void *cookie)

{
    ssize_t len;
    void *msg;
    int err;
    printf("in consumer task\n");

    /* Bind to a queue which has been created elsewhere, either in
       kernel or user-space. The call will block us until such queue
       is created with the expected name. The queue should have been
       created with the Q_SHARED mode set, which is implicit when
       creation takes place in user-space. */

    err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
    printf("rt_queue_bind returns %d",err);

    if (err)
	{
		printf("error: rt_queue_bind. Error code %d, %s \n",err,strerror(err));
		
		exit(99);
	}



    /* Collect each message sent to the queue by the queuer() routine,
       until the queue is eventually removed from the system by a call
       to rt_queue_delete(). */

    while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
        {
        printf("received message> len=%d bytes, ptr=%p, s=%s\n",
               len,msg,(const char *)msg);
        rt_queue_free(&q_desc,msg);
        }

    /* We need to unbind explicitly from the queue in order to
       properly release the underlying memory mapping. Exiting the
       process unbinds all mappings automatically. */

    rt_queue_unbind(&q_desc);

    if (len != -EIDRM)
	{
		printf("error: rt_queue_bind. len= %d\n",len);
		exit(99);
	}
      
    /* ... */
}


int main (int argc, char *argv[])

{
    static char *messages[] = { "hello", "world", NULL };
    int n, len;
    void *msg;
    int err;
    err = rt_queue_create(&q_desc, "SomeQueueName", 100, Q_UNLIMITED, Q_FIFO);
	if(err<0)
		printf("error code of %s\n",strerror(err));

    mlockall(MCL_CURRENT|MCL_FUTURE);

    err = rt_task_create(&task_desc,
                         "MyTaskName",
                         TASK_STKSZ,
                         TASK_PRIO,
                         TASK_MODE);
    if (!err)
        rt_task_start(&task_desc,&consumer,NULL);

    /* ... */
	printf("rt task started\n");

    for (n = 0; messages[n] != NULL; n++)
        {
        len = strlen(messages[n]) + 1;
        /* Get a message block of the right size. */
        msg = rt_queue_alloc(&q_desc,len);

        if (msg==NULL)
            /* No memory available. */
            printf("rt_queue_alloc failed to allocate, NULL pointer received\n");
	else printf("allocated queue of size %d\n",len);

        strcpy((char *)msg,messages[n]);
        rt_queue_send(&q_desc,msg,len,Q_NORMAL);
	printf("message sent\n");
        }
    rt_task_join(&task_desc);

    //rt_task_delete(&task_desc);
}




-----Original Message-----
From: Philippe Gerum on behalf of Philippe Gerum
Sent: Wed 4/30/2008 2:48 PM
To: Karch, Joshua
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] Segfault Problems with Message Queues
 
Karch, Joshua wrote:
> Phillipe,
> 
> I'm running 2.4.3 and compiling it on the same machine (a geode based machine).  Appending exit(99); to the next line after printf() allows the program to exit with just the "error" from printf().  No seg faults there, but it seems the rt_queue_alloc is the problem right now.
>

You may want to pass the error code to fail() and print it out. The problem is
that you ask rt_queue_alloc() to get a block from a non-existent queue, because
the queue descriptor is invalid for the main() task. You have to call
rt_queue_create() first.

> Thank you,
> 
> Joshua Karch
> 
> -----Original Message-----
> From: Philippe Gerum on behalf of Philippe Gerum
> Sent: Wed 4/30/2008 2:31 PM
> To: Karch, Joshua
> Cc: xenomai@xenomai.org
> Subject: Re: [Xenomai-help] Segfault Problems with Message Queues
>  
> Karch, Joshua wrote:
>> Hi All,
>>
>> I tried implementing inter-task message queues and following the
>> msg_queue.c example
>> (http://www.xenomai.org/documentation/trunk/html/api/msg__queue_8c-example.html)
>> and when I try to run the implementation after fixing some of the code
>> (declaring fail() to printf an error, declaring int err, and changing
>> &task_body to &consumer), I get the following error
>> msg_queue[3897]: segfault at 00000000 eip b7cf8933 esp bf8dce04 error
>> 6.  This comes out of the rt_queue_alloc function.
>>
>> Has the implementation of message passing between userspace tasks
>> changed?  Is there a more recent example?  My end goal is to send non
>> blocking messages from one producer task at 50Hz to two reading tasks
>> tasks with similar (though not exactly same) loop rates-- i.e. None of
>> the tasks are synchronized, though they all run at about 50Hz.  Should I
>> use message queues to do this?
>>
>> Thank you,
>>
>> Joshua Karch
>>
>> Attached is the code I used..
>>
>> #include <sys/mman.h>
>> #include <stdio.h>
>> #include <string.h>
>> #include <native/task.h>
>> #include <native/queue.h>
>>
>> #define TASK_PRIO  99 /* Highest RT priority */
>> #define TASK_MODE  0  /* No flags */
>> #define TASK_STKSZ 0  /* Stack size (use default one) */
>>
>> RT_QUEUE q_desc;
>>
>> RT_TASK task_desc;
>>
> 
> We need to know whether an error actually occurred. Nothing guarantees us that
> all stdio buffers would be flushed upon SEGV. Does the executable still behave
> the same way with that patch?
> 
>> void fail()
>> {
>>         printf("error\n");
> 
> +	exit(99);
>> }
>>
>>
>> void consumer (void *cookie)
>>
>> {
>>     ssize_t len;
>>     void *msg;
>>     int err;
>>
>>     /* Bind to a queue which has been created elsewhere, either in
>>        kernel or user-space. The call will block us until such queue
>>        is created with the expected name. The queue should have been
>>        created with the Q_SHARED mode set, which is implicit when
>>        creation takes place in user-space. */
>>
>>     err = rt_queue_bind(&q_desc,"SomeQueueName",TM_INFINITE);
>>
>>     if (err)
>>         fail();
>>
>>     /* Collect each message sent to the queue by the queuer() routine,
>>        until the queue is eventually removed from the system by a call
>>        to rt_queue_delete(). */
>>
>>     while ((len = rt_queue_receive(&q_desc,&msg,TM_INFINITE)) > 0)
>>         {
>>         printf("received message> len=%d bytes, ptr=%p, s=%s\n",
>>                len,msg,(const char *)msg);
>>         rt_queue_free(&q_desc,msg);
>>         }
>>
>>     /* We need to unbind explicitly from the queue in order to
>>        properly release the underlying memory mapping. Exiting the
>>        process unbinds all mappings automatically. */
>>
>>     rt_queue_unbind(&q_desc);
>>
>>     if (len != -EIDRM)
>>         /* We received some unexpected error notification. */
>>         fail();
>>
>>     /* ... */
>> }
>>
>>
>> int main (int argc, char *argv[])
>>
>> {
>>     static char *messages[] = { "hello", "world", NULL };
>>     int n, len;
>>     void *msg;
>>     int err;
>>
>>     mlockall(MCL_CURRENT|MCL_FUTURE);
>>
>>     err = rt_task_create(&task_desc,
>>                          "MyTaskName",
>>                          TASK_STKSZ,
>>                          TASK_PRIO,
>>                          TASK_MODE);
>>     if (!err)
>>         rt_task_start(&task_desc,&consumer,NULL);
>>
>>     /* ... */
>>
>>     for (n = 0; messages[n] != NULL; n++)
>>         {
>>         len = strlen(messages[n]) + 1;
>>         /* Get a message block of the right size. */
>>         msg = rt_queue_alloc(&q_desc,len);
>>
>>         if (!msg)
>>             /* No memory available. */
>>             fail();
>>
>>         strcpy((char *)msg,messages[n]);
>>         rt_queue_send(&q_desc,msg,len,Q_NORMAL);
>>         }
>>
>>     rt_task_delete(&task_desc);
>> }
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Xenomai-help mailing list
>> Xenomai-help@domain.hid
>> https://mail.gna.org/listinfo/xenomai-help
> 
> 


-- 
Philippe.


[-- Attachment #2: Type: text/html, Size: 17430 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2008-04-30 19:22 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-22 22:46 [Xenomai-help] Xenomai serial port c++ code and / or xeno-- (xenomm-0.0.1) install problem Karch, Joshua
2008-04-23  0:12 ` Gilles Chanteperdrix
     [not found]   ` <51B669A8A7D2914E9AB2B3F40AC6553E646F15@domain.hid>
2008-04-23 13:58     ` [Xenomai-help] Xenomai serial port c++ code and / or xeno--(xenomm-0.0.1) " Gilles Chanteperdrix
2008-04-23 14:25       ` Karch, Joshua
2008-04-23 14:30         ` Gilles Chanteperdrix
2008-04-23 15:43           ` Karch, Joshua
2008-04-23 18:10             ` Gilles Chanteperdrix
     [not found]               ` <51B669A8A7D2914E9AB2B3F40AC6553E646F1D@afsexc01.aurora.aero>
2008-04-23 21:20                 ` [Xenomai-help] FW: " Karch, Joshua
2008-04-23 21:28                 ` [Xenomai-help] " Gilles Chanteperdrix
2008-04-23 21:36                   ` Karch, Joshua
2008-04-23 22:14                   ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
2008-04-24  6:43                     ` Gilles Chanteperdrix
2008-04-24  7:04                       ` Jan Kiszka
2008-04-24 14:16                         ` Karch, Joshua
2008-04-24 14:30                           ` Gilles Chanteperdrix
2008-04-24 16:58                             ` Karch, Joshua
2008-04-24 17:16                               ` Gilles Chanteperdrix
2008-04-24 22:37                                 ` [Xenomai-help] serial port overrun problem RT TASK geode latencies too high Karch, Joshua
2008-04-24 22:59                                   ` Gilles Chanteperdrix
2008-04-25 16:04                                     ` [Xenomai-help] Geode Latency Problem (Was: serial port overrun problem) Karch, Joshua
2008-04-25 16:12                                       ` Gilles Chanteperdrix
2008-04-24 13:59                       ` [Xenomai-help] serial port overrun problem RT TASK Karch, Joshua
2008-04-24 14:01                         ` Gilles Chanteperdrix
     [not found] ` <51B669A8A7D2914E9AB2B3F40AC6553E646F52@domain.hid>
     [not found]   ` <18454.9396.476627.446653@domain.hid>
     [not found]     ` <51B669A8A7D2914E9AB2B3F40AC6553E646F54@domain.hid>
     [not found]       ` <48162C69.6040101@domain.hid>
     [not found]         ` <18454.12323.344999.258031@domain.hid>
     [not found]           ` <51B669A8A7D2914E9AB2B3F40AC6553E646F55@domain.hid>
     [not found]             ` <48163EE7.5000604@domain.hid>
     [not found]               ` <18454.17297.451664.334250@domain.hid>
     [not found]                 ` <48164652.5090102@domain.hid>
     [not found]                   ` <2ff1a98a0804290252j1c9dc444kffb345ebaeb123d@domain.hid>
     [not found]                     ` <48187366.2060006@domain.hid>
2008-04-30 18:13                       ` [Xenomai-help] Segfault Problems with Message Queues Karch, Joshua
2008-04-30 18:31                         ` Philippe Gerum
2008-04-30 18:41                           ` Karch, Joshua
2008-04-30 18:48                             ` Philippe Gerum
2008-04-30 19:22                               ` Karch, Joshua
2008-04-30 18:36                         ` Philippe Gerum
2008-04-30 19:19                         ` Gilles Chanteperdrix

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.