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/