Project Home
Project Home
Trackers
Trackers
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - Periodic tasks creation: (9 Items)
   
Periodic tasks creation  
Hi!

I am a new user of QNX. Actually, I am working on my diploma project which consists to compare three rtos (qnx, rtos32 
and xenomai).

I searched informations about tasks, and especially about periodic tasks.

Is there a trivial way to perform them? For example an instruction which make sleep the task till the next activation by
 the scheduler? 

At this moment I use semaphores. Each thread waits on a specific semaphore and another thread uses "sem_post(&rtTaskN)" 
for all the threads after a specified period in a timer.

I also have another question about cpu clock, if I specify "CLOCK_REALTIME" in the instruction "timer_create", which 
system clock will I use? The RTC clock of the system@32kHz or a cpu internal clock with a greater precision?

Thanks for your help.
Re: Periodic tasks creation  
Hello Cédric,
If you are looking for a way to “make sleep the task till the next activation by the scheduler”, please check 
description of SchedYield(), SchedYield_r():
http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/s/schedyield.html

CLOCK_REALTIME refers to a high-speed (MHz range) CPU internal clock.
Regards,
Yuriy
Re: Periodic tasks creation  
Thanks for your answer Yuriy ! It helped me much :)

Re: Periodic tasks creation  
Hi List,

I get another problem with my application. I would like to generate a signal with a timer, and synchronize one thread 
with this timer.

Actually, it's like if my timer_handler can't catch the signal. 

Did I miss some instructions or did something wrong?
Thanks.

/*********************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <semaphore.h>
#include <pthread.h>
#include <time.h>

sem_t rtClockSem;
sem_t startStopSem;
pthread_t tSubRate1Desc;
struct itimerspec paramTimer;
struct sigevent event;
timer_t timerDesc;
int i = 0; /*just for test and debug*/

void * tSubRate_1(void * cookie)
{
  while (1) {
 	sem_wait(&rtClockSem);
	printf("Hello...\n");
	i += 1;
	if (i > 5)
		sem_post(&startStopSem);

  }
}
void timer_handler(int sig){
	int status;
	if (sig == SIGRTMIN){
		status = sem_post(&rtClockSem);	
		if (status != 0)
			printf ("Semaphore error : %d\n", status);
		
		/*signal association*/
		signal(SIGRTMIN, timer_handler);
  		if (status != 0)
  			printf("error while signal association \n");
	}
}

int main(int argc, char *argv[]) {
	int status;
	status = sem_init(&startStopSem, NULL, 0);
 	if (status != 0)
    	printf("Error creating semaphore : %d\n", status);
    
	status = sem_init(&rtClockSem, NULL, 0);
  	if (status != 0)
    	printf("Error creating semaphore : %d\n", status);
	
	status = pthread_create(&tSubRate1Desc, NULL, tSubRate_1, NULL);
  	if (status != 0)
    	printf ("Error creating task : %d\n", status);
    
  	status = timer_create(CLOCK_REALTIME, &event, &timerDesc);
  	if (status != 0)
  		printf("Error creating timer : %d\n", status);
  
        paramTimer.it_interval.tv_sec = 1;
  	timer_settime(timerDesc, 0, ¶mTimer, NULL);	
  	
        signal(SIGRTMIN, timer_handler);
	
	sem_wait(&startStopSem);
	printf("End...\n");
	return EXIT_SUCCESS;
}
AW: Periodic tasks creation  
Hi Cédric,

you missed a few minor things - first of all, you need to initialize the struct sigevent prior to passing it to 
timer_create(). Use SIGEV_SIGNAL_INIT to do so (see below).

Further, the struct itimerspec provided to timer_settime must be completely initialized, and its  it_value  member must 
be != 0.0, otherwise the time won't run.

See below for a revised (working) version of your app. I removed the clock semaphore; you can just use  sigwait()  in 
your thread to synchronize on the signal. Saves a lot of overhead, too.  Oh, and BTW - you don't need to reattach a 
signal handler within itself (like you do in some other OSes), so calling  signal()  in your  timer_handler()  function 
isn't required.

Hope this helps.

Cheers,
- Thomas

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <semaphore.h>
#include <pthread.h>
#include <time.h>


sem_t		startStopSem;


void *tSubRate_1( void * cookie ) {
	sigset_t  sigs;
	int  sig;
	int	i = 0; /*just for test and debug*/

	while (1) {
		sigemptyset( &sigs );
		sigaddset( &sigs, SIGRTMIN );
		sigwait( &sigs, &sig );
		printf("Hello...\n");
		i += 1;
		if ( i > 5 )
			sem_post( &startStopSem );
	}
}

int main(int argc, char *argv[]) {
	pthread_t  tSubRate1Desc;
	struct itimerspec  paramTimer;
	struct sigevent  event;
	timer_t  timerDesc;
	int  status;

	status = sem_init(&startStopSem, NULL, 0);
	if (status != 0)
		printf("Error creating semaphore : %d\n", status);

	status = pthread_create( &tSubRate1Desc, NULL, tSubRate_1, NULL );
	if (status != 0)
		printf ("Error creating task : %d\n", status);

	SIGEV_SIGNAL_INIT( &event, SIGRTMIN );

  	status = timer_create( CLOCK_REALTIME, &event, &timerDesc );
  	if (status != 0)
  		printf("Error creating timer : %d\n", status);
  
	paramTimer.it_value.tv_sec = 1;
	paramTimer.it_value.tv_nsec = 0;
	paramTimer.it_interval.tv_sec = 1;
	paramTimer.it_interval.tv_nsec = 0;

  	timer_settime( timerDesc, 0, ¶mTimer, NULL );
	sem_wait( &startStopSem );
	printf("End...\n");

	return EXIT_SUCCESS;
}

> -----Ursprüngliche Nachricht-----
> Von: Cédric Schaffter [mailto:community-noreply@qnx.com]
> Gesendet: 19 September 2008 11:02
> An: general-community
> Betreff: Re: Periodic tasks creation
> 
> 
> Hi List,
> 
> I get another problem with my application. I would like to 
> generate a signal with a timer, and synchronize one thread 
> with this timer.
> 
> Actually, it's like if my timer_handler can't catch the signal. 
> 
> Did I miss some instructions or did something wrong?
> Thanks.
> 
> /*************************************************************
> ********************/
> #include <stdlib.h>
> #include <stdio.h>
> #include <signal.h>
> #include <semaphore.h>
> #include <pthread.h>
> #include <time.h>
> 
> sem_t rtClockSem;
> sem_t startStopSem;
> pthread_t tSubRate1Desc;
> struct itimerspec paramTimer;
> struct sigevent event;
> timer_t timerDesc;
> int i = 0; /*just for test and debug*/
> 
> void * tSubRate_1(void * cookie)
> {
>   while (1) {
>  	sem_wait(&rtClockSem);
> 	printf("Hello...\n");
> 	i += 1;
> 	if (i > 5)
> 		sem_post(&startStopSem);
> 
>   }
> }
> void timer_handler(int sig){
> 	int status;
> 	if (sig == SIGRTMIN){
> 		status = sem_post(&rtClockSem);	
> 		if (status != 0)
> 			printf ("Semaphore error : %d\n", status);
> 		
> 		/*signal association*/
> 		signal(SIGRTMIN, timer_handler);
>   		if (status != 0)
>   			printf("error while signal association \n");
> 	}
> }
> 
> int main(int argc, char *argv[]) {
> 	int status;
> 	status = sem_init(&startStopSem, NULL, 0);
>  	if (status != 0)
>    ...
View Full Message
Re: AW: Periodic tasks creation  
Great! It works well!

Thanks for your help Thomas.
Re: AW: Periodic tasks creation  
Hi list,

I would like to know if there's a way to increase the resolution of this timer?

Actually, I need to perform tasks each tenth micro-seconds, but with this implementation, I don't have an accuracy 
better than around 1millisecond.

I read the article about the function Clockperiod and tried to implement like this :

//**********************************************************

  struct _clockperiod newRes;
  struct _clockperiod oldRes;
  newRes.nsec = 1000; 
  newRes.fract = 0;
  status = ClockPeriod(CLOCK_REALTIME, &newRes, &oldRes, 0);
  if (status < 0) {
    printf("Error setting CLOCK_REALTIME new period %ld\n", newRes.nsec);
    exit(-1);
  }

//**********************************************************

Doing like this, I hoped to get a resolution of 1micro-second.

Is it the best way to increase the resolution or should I implement interrupts with the 8254 internal component?

Can someone help me ?
Thanks.
Re: AW: Periodic tasks creation  
Cédric Schaffter wrote:
>  Hi list,
>
>  I would like to know if there's a way to increase the resolution of
>  this timer?
>
>  Actually, I need to perform tasks each tenth micro-seconds, but with
>  this implementation, I don't have an accuracy better than around
>  1millisecond.
>
>  I read the article about the function Clockperiod and tried to
>  implement like this :

[ Code sample snipped ]

>  Doing like this, I hoped to get a resolution of 1micro-second.
>
>  Is it the best way to increase the resolution or should I implement
>  interrupts with the 8254 internal component?
>
>  Can someone help me ? Thanks.

That would be how you would do it if you wanted to use the OS timing
facilities for general dispatch and scheduling of your tasks.  However at
that rate you will start chewing more CPU for general scheduling checks
and if the system you are running on doesn't have the free cycles or the
horsepower then it might not be the best route.

If you can re-program other hardware timers to trigger an interrupt that
you specifically handle, that may be a better (more efficient) way to 
trigger
your periodic code and leave the general system scheduling at the 1ms
clock resolution.

Hope this helps,
 Thomas
Re: AW: Periodic tasks creation  
Thanks Thomas for your answer !

So first I will try to use the 8254 programmable interval timer. And if I don't have efficient results, I will add an 
extern timer card to my system.

Best regards,
Cédric