* [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
[parent not found: <51B669A8A7D2914E9AB2B3F40AC6553E646F15@domain.hid>]
* 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
[parent not found: <51B669A8A7D2914E9AB2B3F40AC6553E646F1D@afsexc01.aurora.aero>]
* [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 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
* 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
[parent not found: <51B669A8A7D2914E9AB2B3F40AC6553E646F52@domain.hid>]
[parent not found: <18454.9396.476627.446653@domain.hid>]
[parent not found: <51B669A8A7D2914E9AB2B3F40AC6553E646F54@domain.hid>]
[parent not found: <48162C69.6040101@domain.hid>]
[parent not found: <18454.12323.344999.258031@domain.hid>]
[parent not found: <51B669A8A7D2914E9AB2B3F40AC6553E646F55@domain.hid>]
[parent not found: <48163EE7.5000604@domain.hid>]
[parent not found: <18454.17297.451664.334250@domain.hid>]
[parent not found: <48164652.5090102@domain.hid>]
[parent not found: <2ff1a98a0804290252j1c9dc444kffb345ebaeb123d@domain.hid>]
[parent not found: <48187366.2060006@domain.hid>]
* [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: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: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
* 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: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
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.