LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 02-10-2010, 10:01 AM   #1
liny1984
LQ Newbie
 
Registered: Jun 2006
Distribution: openSUSE, Ubuntu
Posts: 23

Rep: Reputation: 0
Question RS232c and OpenGL in same program


I am trying to write a program that accepts user input from the keyboard and a joystick and then sends out the data using the rs232 port of my system to other hardware. I need to send out about 10 bytes every 20 milliseconds. The thing is I need to also keep on reading data from the same port and display it on an opengl screen. This visualizes the hardware data coming in.

So the way I did it was by spinning everything around opengl..I setup GLUT - as follows :
/* register call back functions */
glutDisplayFunc(redraw);
glutReshapeFunc(resize);
glutIdleFunc(visualize);
glutKeyboardFunc(getkey);
glutSpecialFunc(getspecialkey);

and in the idle function visualize() ...I currently do the joystick reading and rs232 packet sending and recv stuff.

I also call redraw after I am done so if I have received new data above, then it gets drawn on the screen.
Everything works fine except that calling redraw() from visualize() is logical in a PC simulation where the simulation state needs to be rendered on screen after a simulation step. But in my case it takes up too much time ...much greater than 20 ms.....so I can no longer guarantee i can send out packets through the rs232 port every 20 ms.

What are my options here if I want to send out packets and visualize data at a reasonable frame rate - packets within 20 ms is more imp of course.
 
Old 02-10-2010, 10:24 AM   #2
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,011

Rep: Reputation: 110Reputation: 110
I'd suggest you use SDL for your opengl context. It's far easier to control how the mainloop operates and the event API is superior.

For the main issue, create a worker thread to do the sim and shove the data into the rs232 device. The visualization should take a snapshot of the sim state and display it however it likes (I'm assuming that the keyboard and joystick input has zero impact on the sim results).
 
Old 02-10-2010, 10:36 AM   #3
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
Perhaps you should put the time critical data i/o over the RS232 into a separate thread so that you do not have to wait until the screen was rendered. Maybe you should have a look on the pthreads manual page.


What I would suggest is a solution closer to the unix philosophy:
Write a program that does all the hardware i/o and receives it commands and data and sends its results over some of the IPC mechanisms (unix sockets or shared memory) to your visualizing application.

This ensures that the time critical i/o works reliable and you could even replace the visualizing software on the fly or allow multiple applications to use the data at the same time.

On further benefit will be that the daemon can be run as a different user than the visualizing software and so this also increases security. Furthermore this kind of architecture is easier to debug. As a side effect only minor changes will be required to run the visualizing software on a more powerful system (higher frame rate) while the i/o daemon is running on a slower system. But use your own imagination in this case.
 
1 members found this post helpful.
Old 02-10-2010, 11:18 AM   #4
liny1984
LQ Newbie
 
Registered: Jun 2006
Distribution: openSUSE, Ubuntu
Posts: 23

Original Poster
Rep: Reputation: 0
yes right....I think I will split up the 2 things into 2 threads.

ok 2 things : first the visualizing part -

I think I will drop opengl & glut for the visualizing part as I just need to show some basic 2D gauges and SDL should suffice as well as handle the keyboard event management stuff. I think SDL should be more lightweight than opengl and the thread should run fast enough.

If it doesnt run fast enough then the problem is it may miss keyboard input as SDL does not use callbacks like glut, it uses an event loop.

As for the joystick I am directly using the joystick C api whose code is something like this......

Code:
if ((fd_joystick = open("/dev/js0", O_RDONLY)) < 0) {
		perror("jstest");
		exit(1);
	}	
	ioctl(fd_joystick, JSIOCGAXES, &axes);
	ioctl(fd_joystick, JSIOCGBUTTONS, &buttons);

if (read(fd_joystick, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
	      	perror("\njstest: error reading");
		return 0;
	}
	      
	switch(js.type & ~JS_EVENT_INIT) {
	case JS_EVENT_BUTTON:
		button[js.number] = js.value;
		break;
	case JS_EVENT_AXIS:
		axis[js.number] = js.value;
		break;
	}
I could use SDL for the joystick input as well though I am not sure if it will be faster than the direct method above. So I will put this code in the same event loop just after the switch-case to check keyboard events.

I just hope SDL is fast enough to not actually drop any inputs from the keyboard.

Now for the worker thread :
Here I can simply keep sending packets at 20 ms and then receive whatever is coming back.The receiving call is of course non blocking so it doesnt jam the thread. I can have this thread at a higher priority.

So pthreads is the standard for threading in Linux ? I just need something with minimum overhead for context switches
 
Old 02-10-2010, 11:22 AM   #5
liny1984
LQ Newbie
 
Registered: Jun 2006
Distribution: openSUSE, Ubuntu
Posts: 23

Original Poster
Rep: Reputation: 0
I had though of IPC and sockets but since the application is very basic there didnt seem to be a need for adding an extra layer of communication....since threads stay in the same address space they can access common variables faster.
 
Old 02-10-2010, 11:37 AM   #6
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
pthreads stands for "posix threads" and is the standard under linux. All programs and libraries I know use pthreads, either directly or over some higher level library.

Why are you afraid of loosing keyboard input? There are buffers in the kernel and in the X server and xlib (if using under x11). I do not think that you will press keys so quickly that these buffers will overflow unless using a very old system.
 
Old 02-10-2010, 01:31 PM   #7
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,011

Rep: Reputation: 110Reputation: 110
Quote:
I could use SDL for the joystick input as well though I am not sure if it will be faster than the direct method above. So I will put this code in the same event loop just after the switch-case to check keyboard events.
"Premature optimization is the root of all evil"

Before you do funny stuff like directly access the joystick device and lose cross-platform compatibility, make sure that it's actually the bottleneck with profiling. It's actually also quite dangerous because SDL assumes you aren't doing such things and will do things like take locks.

SDL's input subsystems are quite fast enough. After all, games have extremely strict real-time requirements. SDL also has a threading subsystem as well, so you can use them and still keep cross-platform compatibility.

Quote:
I had though of IPC and sockets but since the application is very basic there didnt seem to be a need for adding an extra layer of communication....since threads stay in the same address space they can access common variables faster.
Shared memory being faster is a myth. More often than not, locking requirements completely destroy any possible benefits. In fact, you should try to avoid sharing as much data as possible between threads because of the costs of locking, in the overhead of the lock itself, that the lock turns your multi-threaded program into a single-threaded program, and the headache involved with making sure you don't end up with race conditions.

Last edited by tuxdev; 02-10-2010 at 01:46 PM.
 
1 members found this post helpful.
Old 02-10-2010, 05:45 PM   #8
liny1984
LQ Newbie
 
Registered: Jun 2006
Distribution: openSUSE, Ubuntu
Posts: 23

Original Poster
Rep: Reputation: 0
Yeah..i think I ll go ahead with SDL. About the threads...I am planning to store the user inputs in a set of global variables by the thread containing the SDL event loop and having it picked up from there to be sent by the rs232 thread. After sending, the same thread checks if anything is there in the local UART buffer and if so, it stores it in a different set of receive variables. The receive variables are only read by the SDL event thread and never written to.

So in either case, 1 thread is writing and the other reading....so I am hoping this wont cause any locking issues as these are the minimum variables which have to be shared.
 
Old 02-10-2010, 06:05 PM   #9
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
But there is still a need for locking, because the SDL event thread can try to read data while the rs232 thread is writing it. The same goes for the input handling. Perhaps you will never observe any errors but locking will be required anyway.
 
Old 02-10-2010, 06:14 PM   #10
liny1984
LQ Newbie
 
Registered: Jun 2006
Distribution: openSUSE, Ubuntu
Posts: 23

Original Poster
Rep: Reputation: 0
hmmm...maybe I can have a semaphore variable in there to lock the data while the rs232 thread writes it....as somehow I need to get the data from the port to the rendering thread. Does Pthread support priorities so I can run the rs232 thread at a higher one. It may cause the rendering thread to often not have access to the shared variables if the rs232 is constantly locking it....but I guess there is no other way around it.
 
Old 02-10-2010, 06:22 PM   #11
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
You can find a tutorial to pthreads here:

https://computing.llnl.gov/tutorials/pthreads

pthread_attr_setschedparam can be used to set the priority of the thread.

You can also use condition variables: The render thread will sleep until there is new data to render and this won't waste cpu time. (see the link above)
 
1 members found this post helpful.
  


Reply

Tags
opengl, rs232


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
OpenGL program freezes RH 9.0 ssd_123 Linux - Hardware 7 06-23-2003 08:54 AM
Opengl program noir-gel Programming 6 06-19-2003 01:03 PM
OpenGL program freezes RH 9.0 ssd_123 Linux - General 1 06-03-2003 01:55 PM
Opengl program freezes RH 9.0 ssd_123 Linux - Software 1 06-03-2003 01:55 PM
OpenGL program freezes RH 9.0 ssd_123 Programming 2 06-03-2003 01:49 PM


All times are GMT -5. The time now is 06:09 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration