Ok. I think it's a common mistake people are making.

>  pthread_create( &thread, NULL, start_routine, 0 );
> 
>  /* Periodisation de la tache */
> 
>  pthread_make_periodic_np( thread, gethrtime() + 5000000, CESAR_SAMPLING_PERIOD );
> 
>  pthread_setfp_np( thread, 1 );

By the time you get to pthread_setfp_np(), the start_routine has already
been started -- as required by POSIX. So start_routine performs FP operations
before they have been enabled.

The correct way to initialize is to move pthread_setfp_np into the begining
of start_routine.

Michael.


Jacques GANGLOFF ([EMAIL PROTECTED]) wrote:
> Hi,
> 
> I experimented strange random system hang using
> FP computations in a periodic task.
> 
> This problem seems to be linked with the X server :
> 
> * When I insert the module in a xterm, the system hangs immediately after pressing 
>[ENTER].
> I tracked down the problem, and it seems to happen in a call of a function with one 
>argument is
> a double.
> 
> * When I insert the SAME module in a virtual console (X is not running) the system 
>does not hang
> and the module works as expected. This can be reapeted many times without problem.
> 
> * The last but not the least : If after successfully inserting the module in a 
>virtual console, I start X
> and I re-insert the module in a xterm, then the system does NOT hang !!!!???? I 
>saids that it is a starnge problem.
> 
> I experimented this problem on various PC's with differnt programs. If somebody can 
>help me, thanks in
> advance. In the meanwhiel, I will try RTAI to see if the same problem occurs.
> 
> In attachment, the faultly module.
> 
> /*****************************************************************************
> * cesar.c : module de commande de robot.
> *
> *               JG, le 14/6/2000
> *****************************************************************************/
> 
> #include <rtl.h>
> #include <time.h>
> #include <pthread.h>
> #include <rtl_fifo.h>
> #include <rtl_sched.h>
> #include <math.h>
> #include <asm/io.h>
> #include "dac.h"
> #include "counter.h"
> #include "cesar.h"
> 
> /*
>  * Constantes
>  */
> 
> /* Sens de comptage */
> 
> static char  cesar_counter_sign[CESAR_NB_JOINTS] = {    0,
>                  0,
>                  0,
>                  0,
>                  0,
>                  1 };
> 
> /* Nombre de tops codeur pour une rotation de l'axe de 1 radian */
> 
> static double cesar_counter_top_per_radian[CESAR_NB_JOINTS] = {  12732.39,
>                  12732.39,
>                  12732.39,
>                  10026.76,
>                  10026.76,
>                  10026.76 };
> 
> /* Numeros des axes a mouvoir lors du recalage */
> 
> static int  cesar_counter_init_sequence[CESAR_NB_JOINTS] = {  1,
>                  4,
>                  5,
>                  3,
>                  2,
>                  0 };
> 
> 
> /* Sens de rotation pour le recalage */
> 
> static int  cesar_counter_init_direction[CESAR_NB_JOINTS] = {  1,
>                  1,
>                  -1,
>                  -1,
>                  1,
>                  1 };
> 
> /* Valeur a initialiser lorsque le robot est en butee */
> 
> static int  cesar_counter_init_value[CESAR_NB_JOINTS] =  {  33474,
>                  10112,
>                  -3333,
>                  -32732,
>                  22108,
>                  38842 };
> 
> /* Trainage maximum lors du recalage */
> 
> static int  cesar_counter_init_max_error[CESAR_NB_JOINTS] = {  200,
>                  200,
>                  200,
>                  800,
>                  800,
>                  800 };
> 
> /* Valeur de repli pour se mettre hors zone d'activation des securites */
> 
> static int  cesar_counter_init_back[CESAR_NB_JOINTS] = {   5000,
>                  5000,
>                  5000,
>                  5000,
>                  5000,
>                  5000 };
> 
> /* Position initial du robot */
> 
> static int  cesar_initial_position[CESAR_NB_JOINTS] = {   21100,
>                  -11133,
>                  16313,
>                  0,
>                  10800,
>                  3400 };
> 
> /* Traimage maximum en asservissement de position */
> 
> static int  cesar_max_error[CESAR_NB_JOINTS] = {     1500,
>                  1500,
>                  1500,
>                  1500,
>                  1500,
>                  1500 };
> 
> /* Butee logicielle de position haute */
> 
> static int  cesar_counter_max[CESAR_NB_JOINTS] = {     26866,
>                  4936,
>                  23300,
>                  29924,
>                  15625,
>                  7000 };
> 
> /* Butee logicielle de position basse */
> 
> static int  cesar_counter_min[CESAR_NB_JOINTS] = {    -26866,
>                  -18269,
>                  0,
>                  -29924,
>                  0,
>                  -7000 };
> 
> /* Tension de saturation des commmandes */
> 
> static double cesar_control_sat[CESAR_NB_JOINTS] = {    0.5,
>                  0.5,
>                  0.5,
>                  0.5,
>                  0.5,
>                  0.5 };
> 
> /* Coefficients proportionnels du correcteur */
> 
> static double cesar_controller_P[CESAR_NB_JOINTS] = {    1.9e-3,
>                  2.8e-3,
>                  2.9e-3,
>                  2e-3,
>                  2e-3,
>                  3.2e-3 };
> 
> /*
>  * Variables globales
>  */
> 
> pthread_t  thread;
> 
> ROBOT_STRUCT Robot;
> 
> 
> /*****************************************************************************
> * rt_init_cesar : initialisation.
> *****************************************************************************/
> int rt_init_cesar( void ) {
> 
>  int  error_nb = 0, i;
> 
>  /* Initialisation des modules cna */
> 
>  rt_init_dac( 0, CESAR_DAC_PORT_1 );
>  rt_init_dac( 1, CESAR_DAC_PORT_2 );
> 
>  /* Initialisation des compteurs */
> 
>  if ( rt_init_counter( 0, CESAR_COUNTER_PORT_1 ) ) {
>   rtl_printf( "cesar: counter 1 init failed.\n" );
>   error_nb = 1;
>   }
>  if ( rt_init_counter( 1, CESAR_COUNTER_PORT_2 ) ) {
>   rtl_printf( "cesar: counter 2 init failed.\n" );
>   error_nb = 1;
>   }
>  if ( rt_init_counter( 2, CESAR_COUNTER_PORT_3 ) ) {
>   rtl_printf( "cesar: counter 3 init failed.\n" );
>   error_nb = 1;
>   }
>  if ( rt_init_counter( 3, CESAR_COUNTER_PORT_4 ) ) {
>   rtl_printf( "cesar: counter 4 init failed.\n" );
>   error_nb = 1;
>   }
>  if ( rt_init_counter( 4, CESAR_COUNTER_PORT_5 ) ) {
>   rtl_printf( "cesar: counter 5 init failed.\n" );
>   error_nb = 1;
>   }
>  if ( rt_init_counter( 5, CESAR_COUNTER_PORT_6 ) ) {
>   rtl_printf( "cesar: counter 6 init failed.\n" );
>   error_nb = 1;
>   }
> 
>  /* Definition du sens de comptage */
> 
>  for ( i = 0; i < CESAR_NB_JOINTS; i++ )
>   rt_sign_counter( i, cesar_counter_sign[i] );
> 
>  /* Deblocage des compteurs */
> 
>  for ( i = 0; i < CESAR_NB_JOINTS; i++ )
>   rt_unlock_counter( i );
> 
>  /* Initialisation de la structure d'etat */
> 
>  for ( i = 0; i < CESAR_NB_JOINTS; i++ ) {
>   Robot.Control[i] =
>   Robot.Offset[i] = 0.0;
>   Robot.Reference[i] =
>   Robot.Measurement[i] = 0;
>   }
> 
>  rt_security_cesar( CESAR_SECURITY_ON ); <<============================= THE SYSTEM 
>HANGS ON THIS CALL
>  rt_power_cesar( CESAR_POWER_OFF );
> 
>  return error_nb;
>  }
> 
> /*****************************************************************************
> * rt_power_cesar : gestion de la puissance.
> *****************************************************************************/
> int rt_power_cesar( char State ) {
> 
>  if ( State ) {
>   rt_write_dac( 1, 3, DAC_MAX_VOLTAGE );
>   Robot.Power_on = 1;
>   }
>  else {
>   rt_write_dac( 1, 3, 0.0 );
>   Robot.Power_on = 0;
>   }
> 
>  return 0;
>  }
> 
> /*****************************************************************************
> * rt_security_cesar : gestion des securites.
> *****************************************************************************/
> int rt_security_cesar( char State ) {
> 
>  if ( State ) {
>   rt_write_dac( 1, 2, 0.0 );
>   Robot.Security_on = 1;
>   }
>  else {
>   rt_write_dac( 1, 2, 0.0 );
>   Robot.Security_on = 0;
>   }
> 
>  return 0;
>  }
> 
> /*****************************************************************************
> * rt_send_control_cesar : envoi des commandes.
> *****************************************************************************/
> int rt_send_control_cesar( void ) {
> 
>  double  control_sat[CESAR_NB_JOINTS];
>  int  i;
> 
>  /* Saturation */
> 
>  for ( i = 0; i < CESAR_NB_JOINTS; i++ ) {
> 
>   control_sat[i] = Robot.Control[i];
> 
>   if ( control_sat[i] > cesar_control_sat[i] )
>    control_sat[i] = cesar_control_sat[i];
>   if ( control_sat[i] < -cesar_control_sat[i] )
>    control_sat[i] = -cesar_control_sat[i];
> 
>   control_sat[i] += Robot.Offset[i];
>   }
> 
>  /* Envoi des tensions sur les CNA */
> 
>  rt_write_dac( 0, 0, control_sat[0] );
>  rt_write_dac( 0, 1, control_sat[1] );
>  rt_write_dac( 0, 2, control_sat[2] );
>  rt_write_dac( 0, 3, control_sat[3] );
>  rt_write_dac( 1, 0, control_sat[4] );
>  rt_write_dac( 1, 1, control_sat[5] );
> 
>  rt_conv_dac( 0 );
>  rt_conv_dac( 1 );
> 
>  return 0;
>  }
> 
> /*****************************************************************************
> * rt_read_position_cesar : lecture des valeurs des compteurs.
> *****************************************************************************/
> int rt_read_position_cesar( void ) {
> 
>  int  i;
> 
>  for ( i = 0; i < CESAR_NB_JOINTS; i++ )
>   rt_read_counter( i, &Robot.Measurement[i] );
> 
>  return 0;
>  }
> 
> /*****************************************************************************
> * Routine Periodique
> *****************************************************************************/
> void * start_routine( void *arg ) {
> 
>  int  i;
> 
>  /* Initialisation */
> 
>  if ( rt_init_cesar( ) ) {
>   rtl_printf( "cesar: init failed.\n" );
>   return 0;
>   }
> 
>  /* Mise sous tension */
> 
>  rt_power_cesar( CESAR_POWER_ON );
> 
>  while ( 1 ) {
> 
>   /* Attente de la prochaine periode */
> 
>   pthread_wait_np();
> 
>   /* Lecture des positions */
> 
>   rt_read_position_cesar( );
> 
>   /* Calcul des commandes */
> 
>   for ( i = 0; i < 6; i++ )
>    Robot.Control[i] = (double)( Robot.Reference[i] - Robot.Measurement[i] )
>         * cesar_controller_P[i];
> 
>   /* Envoi des commandes */
> 
>   rt_send_control_cesar( );
>   }
> 
>  return 0;
>  }
> 
> 
> /* Initialisation du module */
> 
> int init_module( void ) {
> 
>  struct sched_param   p;
> 
>  /* Creation  de la tache temps reelle */
> 
>  pthread_create( &thread, NULL, start_routine, 0 );
> 
>  /* Periodisation de la tache */
> 
>  pthread_make_periodic_np( thread, gethrtime() + 5000000, CESAR_SAMPLING_PERIOD );
> 
>  /* Autorisation fpu */
> 
>  pthread_setfp_np( thread, 1 );
> 
>  /* Configuration du scheduleur */
> 
>  p . sched_priority = 1;
>  pthread_setschedparam( thread, SCHED_FIFO, &p );
> 
>  /* Affichage d'un message */
> 
>  printk( KERN_INFO "cesar: loaded.\n" );
> 
>  return 0;
> }
> 
> 
> /* Destruction du module */
> 
> void cleanup_module( void ) {
> 
>  pthread_delete_np ( thread );
> 
>  /* Affichage d'un message */
> 
>  printk( KERN_INFO "cesar: unloaded.\n" );
> }
> 
> 
> --
>  _________________________________
> (
> )   Jacques GANGLOFF
> (   Associate Professor
> )   LSIIT / GRAViR
> (   Bd S?bastien Brant
> )   67400 Illkirch
> (   Tel : +33 (0)3 88 65 50 84
> )   Fax : +33 (0)3 88 65 54 89
> (   http://gravir.u-strasbg.fr
> )_________________________________
> 
> 
> 
> -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> ---
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/rtlinux/
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/

Reply via email to