QNX Real time application

Hi guys!
I really hope you can help me.
I need to write a qnx real-time application for my university project.
This application should read from an input device (keyboard, mouse, …) and check whether or not real-time constraints are respected.

Can u suggest me something or can u please tell me where i can find something like these over the internet?

Please help me!

Nicola,

If you search this very forum you will see this question has been asked before, by I assume, prior semester classmates :slight_smile:

The answers in those threads will tell you what you need to do to validate the real time constraints.

Tim

Hi Tim! Thanks for your answer.

I searched the forum but found nothing. What section is this thread in? I should graduate on March 2010 (fingers crossed!) and I don’t know where to start from. How can i retrieve data from keyboard or mouse? should i read from tty? if it’s boring for you to explain, can you suggest some online resources for me to use? I’m italian, so i apologize for my bad english.

Thanks in advance!

Nicola,

There is nothing wrong with your English. If you didn’t mention you were Italian I would never have guessed English wasn’t your first language.

First, there still isn’t enough information about your project to help point you in the right direction (tty is where keyboard data comes from but you get that in a program via a non-blocking read() command on stdin assuming you are running in a terminal and not a photon GUI application).

When you say you have to read input, does it have to be a keyboard or mouse? What about serial data for example?

Also, what exactly are you supposed to show in this project to your professor? Even in Windows if you write a simple C application that reads data from the keyboard it’s going to look like its real-time. So there must be something you are supposed to measure/demonstrate under QNX that Windows doesn’t do and this typically involves running a couple of processes etc.

It would be best if you could post the complete description of your assignment in English of course :slight_smile:

Tim

I start telling you that i ain’t been told that much from my prof.
He first told me to grab frames from a web cam at 15 fps and check for real-time constraints.
That was quite difficult for me to achieve and i also had problems in finding drivers.
I tried the cqcam drivers but i wasn’t able to install them.
So I came back to the professor and told him all of this, and he suggested to change the device from whom retrieve data, such as mouse or keyboard (and, of course, check for real-time constraints).
And that’s it. This is what i’ve been told.
I have to write this application by using the momentics IDE and run it onto the qnx target (i’m running qnx on vmware, that’s easier for me).
I managed to communicate with the guest target OS (qnx) from the IDE in the host os (Win 7) but i don’t know how this application should be written.
Tell if I was clear and thanx for the time your spending.

Nicola

Nicola,

First, you can never measure real time constraints in WMWare. So you must install QNX on a real hardware if you actually intend to measure real time performance.

Second, I still don’t see how you can do this assignment with that information. What the professor is asking for makes no sense. He must be marking your work based on ‘something’. For example, how is he going to know if you actually measured/verified real time constraints?

At a minimum the professor needs to define what ‘real time constraints’ are. After that he needs to define exactly what you are being marked on.

Tim

I will be back at the university on wednesday, and i’ll ask for the professor to be more specific, but what I told you is what i’ve been told to.
Yes, I’ve read that hard-real time constraints are not satisfied on vmware, but when i installed qnx on a real hardware on my old laptot, I had some problems when trying to remove it. I had win xp at the time. To fix this issue I remember I did a copy and paste of the ntldr system file, but i’m not sure.
I also used super grub disk to fix the mbr and restore the windows bootloader (just like fdisk /mbr does) but didn’t work, that’s why i decided to use a VM o my new laptot.
Besides, i don’t have momentics in my qnx installation. Should i have host and target system on the same machine, or two different machines?
I only have one pc.

Thanx

Nicola,

Everything is going to depend on exactly what the professor is looking for when grading your assignment.

If you have to demonstrate hard real time requirements then you can’t run in a VM. In that case with only one PC (the university doesn’t have any you can use/borrow) you’ll have to install QNX on your laptop in a dual boot mode as you did before and have Eclipse run in QNX instead of Windows so you can develop and run directly in QNX.

Tim

Hi Tim.

My prof told me to retrieve data from any input device (web cam, mouse, keyboard, …, whatever it is) and it is up to me to choose the rate this data should be retrieved at, he said, for example, 50 Hz.
Then disturb the application and see the behaviour of the scheduler.

Tell if it’s clear now, and thanx

Nicola,

Yes it’s a lot more clear now.

There are 3 parts to the work you are going to have to do:

Part 1

  1. Decide which input device to read from. As you found out there aren’t any drivers for web cam’s. So your choices are mouse, keyboard or serial. Assuming you have a serial port on your laptop I think serial is the easiest to work with. Otherwise you’ll have to go with mouse or keyboard.
  2. Write an application to read from the input device at a timed interval (say 50 Hz). For this you’ll need to do non-blocking reads of the input and use a timer for the interval at which to read. Using timers and doing non-blocking reads of input are described in the help documents.

Part 2

  1. Find a suitable way (ask your professor what he’ll accept as suitable) to measure your applications performance. This means you need to determine if your application is meeting it’s schedule (say 50 Hz). Potential ways include using the Eclipse IDE which has tools designed to measure performance. Other ways include writing data out to serial ports (assuming you have serial ports and aren’t reading from one) and attaching a scope to the serial port. Or maybe just taking a timestamp and writing this + the date read from a keyboard/mouse to a file will suffice. Whatever works with the professor.
  2. Measure your programs performance with nothing else running in the system but your program. This is your baseline performance.

Part 3

  1. Disturb your application. The easiest way is to write another very simple program that simply does a while (1){}. This will do an infinite loop sucking up 100% of the CPU time.
  2. Run your program and the while (1) program at the same time. Make sure to run the while (1) program at a lower priority than your program.
  3. Measure your programs performance. Compare with the baseline measurement. If QNX is respecting real-time behavior you shouldn’t notice any difference in performance.

Tim

First, thanx for your super-quick answer.

Second, going back on how read from input device.
-how do i read from mouse or keyboard? can’t i just read from /dev/zero?
-how can i read at (exactly) 50 Hz?

by “help documents”, do u mean the “getting started” doc chapter 3?
there’s so much of documentation that i don’t know where to start from…
is the “time1.c” example useful for my purpose?
are there are sample programs that i can use?

I have to come up with something within this xmas holidays, otherwise i will just present a theorical paper sheet report and a slide presentation.
I really want make this project, and if i had some sample programs that i can start from, that would be great for me.

Always, thanx

Nicola,

Leave this part till later.

You read at exactly 50 Hz by setting a timer to expire at 50 Hz (50x a second or every 20ms)

The time1.c program is indeed useful. However, the parts you are interested in are the main.c and setupAndPulseTimer() parts. The rest isn’t useful for you including all those structure definitions before the main.c because you aren’t going to receive messages, just timer pulses. So in main.c replace the MessageT with the struct _pulse.

Get that code working (use a printf to show you are getting the pulses). That establishes your 50 Hz rate part of the project.

Tim

This is what i wrote:

#include <stdlib.h>       /* EXIT_SUCCESS, EXIT_FAILURE */
#include <stdio.h>        /* printf(), fprintf() */
#include <sys/neutrino.h> /* struct _pulse, ChannelCreate(), ChannelDestroy(), ConnectAttach(), MsgReceivePulse */
#include <sys/siginfo.h>  /* struct sigevent, SIGEV_PULSE_INIT */
#include <string.h>       /* strerror() */
#include <errno.h>        /* extern int errno */
#include <time.h>         /* clock(), struct itimerspec, timer_create(), timer_delete(), timer_settime() */

#define CODE_TIMER    1
#define FREQ          50  /* Hz */
#define FREQUENCY     ((long) (1000000000/FREQ))
#define DIM           255 /* Dimensione del buffer */

extern int errno;
int chid;             /* Channel ID */
int start_time;
char * progname = "My_Project.c";
char * file = "/dev/zero";
timer_t SetupPulseAndTimer (long);
int GotAPulse (void);
int Delete_Timer (timer_t);

int main(void)
{
	start_time = time(NULL);
	int count, rcvid;       //PID del mittente
	struct _pulse pulse;    //Il nostro pulse
	timer_t t_id;
	
	if((chid = ChannelCreate(0)) == - 1)
	{
		fprintf(stderr, "%s: couldn't create channel. Error: %s\n", progname, strerror(errno));
		exit(EXIT_FAILURE);
	}
	
	//Prepariamo pulse e timer
	t_id = SetupPulseAndTimer(FREQUENCY);
	
	for(count = 1; ;count++)
	{
		rcvid = MsgReceivePulse (chid, (void *) &pulse, sizeof(pulse), NULL);
		printf("%d - ", count);
		GotAPulse();
	}
	
	/* Never reached */
	
	//Distruggiamo il canale
	if(ChannelDestroy(chid) == -1)
	{
		fprintf(stderr, "%s: couldn't destroy channel. Error: %s\n", progname, strerror(errno));
		exit(EXIT_FAILURE);
	}
	
	//Distruggiamo il timer
	if(timer_delete(t_id) == -1)
	{
		fprintf(stderr, "%s: couldn't destroy timer. Error: %s\n", progname, strerror(errno));
		exit(EXIT_FAILURE);
	}
	return EXIT_SUCCESS;
}

timer_t SetupPulseAndTimer (long freq)
{
	timer_t              timer_id;   //ID del timer
	struct sigevent      event;      //evento da lanciare
	struct itimerspec    timer;      //Struttura dati del timer
	int                  coid;       //Connection ID
	
	//Creiamo una connessione
	coid = ConnectAttach (0, 0, chid, 0, 0);
	
	if(coid == -1)
	{
		fprintf(stderr, "%s: couldn't ConnectAttach to self. Error: %s\n", progname, strerror(errno));
		exit(EXIT_FAILURE);
	}
	
	SIGEV_PULSE_INIT (&event, coid, SIGEV_PULSE_PRIO_INHERIT, CODE_TIMER, 0);
	
	if(timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
	{
		fprintf(stderr, "%s: couldn't create timer. Error: %s (%d)\n", progname, strerror(errno), errno);
		exit(EXIT_FAILURE);
	}
	
	//Impostiamo il timer alla frequenza prestabilita
	timer.it_value.tv_sec     = 1;
	timer.it_value.tv_nsec    = 0;
	timer.it_interval.tv_sec  = 0;
	timer.it_interval.tv_nsec = freq;
	
	timer_settime (timer_id, 0, &timer, NULL);
	
	return timer_id;
}

int GotAPulse (void)
{
	char buffer[DIM];
	FILE * file_p = fopen(file, "r");
	
	if(file_p == NULL)
	{
		fprintf(stderr, "Unable to open \"%s\". Error: %s\n", file, strerror(errno));
		return EXIT_FAILURE;
	}
	
	if (fread( buffer, sizeof(buffer), 1, file_p) == 0)
	{
		fprintf(stderr, "Unable to read from \"%s\". Error: %s\n", file, strerror(errno));
		return EXIT_FAILURE;
	}
	
	printf("Buffer: %s\n", buffer);
	
	fclose(file_p);
	
	return EXIT_SUCCESS;
}

Tell me what it looks like to you.

Now, how can i check the performance with and without disturbing the application?
System Profiler? If so, what view?

Thanx

I forgot one thing.
In my example above i’m reading from /dev/zero, that is, nothing.
How can i actually read from keyboard or mouse?

Again, thanx

I got here (check attachment) (still reading from /dev/zero).
Am I in the right way?

I’m reading the ide user guide. It says to make a new OS image and transfer it to my board.
Is this what i have to do? How can i transfer the OS image to my board?
What board does it refers to?

i guess i’m annoying you, but it feels like i’m finally coming up with something.
My last posts tell you the last thing I miss.

Thank you

Nicola,

So far so good. I compiled your program and ran it. The timer stuff is working.

OK, now for reading from the keyboard. See this topic:

openqnx.com/index.php?name=P … d+keyboard

The final short code example Mario posts on page 1 is the one you want. I cut and pasted his raw(), unraw() into your code and was able to read from the keyboard quite nicely once I dropped all your fopen() stuff in the GotAPulse() routine and replaced it with his one line read() command.

Mario’s code does blocking read. You want unblocking so that your program will continue if there is nothing to read (no key was pressed). So check out the fcntl command in the help docs. There is a code example there to set the STDIN_FILENO attributes. You want to ‘or’ O_NONBLOCK with the flags variable.

At this point you’ll also need to check the return of read() to see if it equals -1 and errno=EAGAIN not do any printing because that means there was no characters waiting.

So get the keyboard input reading working next.

The ‘board’ the documents refer to is normally the 2nd computer/test board where QNX is running natively. If you are still running QNX in a VM you transfer the new OS image from Windows to your QNX VM.

You’ll eventually need to transfer a new image when using the system profiler (you are correct that is what you need). But get the keyboard stuff working first before doing the profiler stuff.

Wait till you see my fee for all this help. ;)

Tim

Thanx Tim.
I’ll try now to mix everything together and see what I got.
One last thing.
Assuming the program is correct, should I “press the keys” repeatedly while it’s running?

Thanx

Nicola,

It doesn’t matter whether you press the keys or not. When the timer expires your program will get woken up and poll for keyboard input.

The system profiler you are using to measure performance only cares when your program runs, not what input data it reads.

I suspect your professor initially suggested a Web Cam because the idea would be to visually watch to see if the video became jerky when your application is disturbed. I suspect this is also why the suggestion was then to read keyboard/mouse input data to again see if there is a visual delay.

But the system profiler takes all the guess work out of deciding if there is any delay or not. But go ahead and press the keys anyway as at least you’ll get some visual confirmation that something is happening. :slight_smile:

Just be aware that a Virtual Machine may not (likely won’t) perform exactly the same as running QNX natively on it’s own machine. So your program may not perfectly wake up at a 50 Mhz interval simply because of the VM machine limitations and not limitations of QNX.

Tim

Testing real time on a VM is an oxymoron.

I attached the sources I wrote. Are they ok?

There’s a few things I have to ask:

1- are raw() and unraw() really necessary? why?
2-i have no output even though i press something
3-read() doesn’t lock even with O_NONBLOCK not set
4-instead of writing another “stand-alone” program, i used fork(), but it seems like it locks, doesn’t return. why?

Thanx Tim for your help.
I wish you and the whole forum a Merry Xmas and a happy new year.