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/