execution stops at rtems_rate_monotonic_create() ?

kmedri kmedri kmedri at hotmail.com
Mon Apr 5 03:41:02 UTC 2004


I am curious as to why execution stops at rtems_rate_monotonic_create(), is 
there an initialization of  the rms that I am missing?

The last output of the code below is:

"kph_task has been called\n"

bike.c completes execution properly while tasks.c doesn't
(the "//this is reached" in the other 4 tasks is not actually reached)

Could someone please help me, thanks.

/*  system.h
*
*  This file has been adapted from the file discussed below
*  It has been adapted for an e-bike application
*/

/*  system.h
*
*  This include file contains information that is included in every
*  function in the test set.
*
*  COPYRIGHT (c) 1989-1999.
*  On-Line Applications Research Corporation (OAR).
*
*  The license and distribution terms for this file may be
*  found in the file LICENSE in this distribution or at
*  http://www.rtems.com/license/LICENSE.
*
*  system.h,v 1.13 2000/06/12 15:00:12 joel Exp
*/

/* Standard includes */
#include <stdlib.h>
#include <stdio.h>

/*Includes for timer*/
#include <time.h>
#include <errno.h>

/*seems this is required*/
#include <rtems.h>

/* functions */

rtems_task Init(
  rtems_task_argument argument
);

rtems_task kph_task(
  rtems_task_argument argument
);
rtems_task rpm_task(
  rtems_task_argument argument
);
rtems_task drv_task(
  rtems_task_argument argument
);
rtems_task pedal_sim(
  rtems_task_argument unused
);
rtems_task wheel_sim(
  rtems_task_argument unused
);


/* global variables */

/*  Although originally declared seperately...
*  Keep the names and IDs in global variables so another task can use them.
*/

extern rtems_id   Task_id[ ];         /* array of task ids */
extern rtems_name Task_name[ ];       /* array of task names */
extern double rpm, speed;
extern int drive_level;
extern char wheel, pedal;

#define KPH 1
#define RPM 2
#define DRV 3
#define WHL 4
#define PED 5

/*4bit interface to motor*/
#define MAX_DRIVE_LEVEL 15

/* configuration information */

#include <bsp.h> /* for device driver prototypes */

/*Some duplication as need to allow code from both test and sample
applications from which code sections were used*/
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER

#define CONFIGURE_MAXIMUM_TASKS             8

#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_EXTRA_TASK_STACKS         (3 * RTEMS_MINIMUM_STACK_SIZE)

#include <confdefs.h>

/*
*  Handy macros and static inline functions
*/

/*
*  Macro to hide the ugliness of printing the time.
*/

#define print_time(_s1, _tb, _s2) \
  do { \
    printf( "%s%02d:%02d:%02d   %02d/%02d/%04d%s", \
       _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
       (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
    fflush(stdout); \
  } while ( 0 )

/*
*  Macro to print an task name that is composed of ASCII characters.
*
*/

#define put_name( _name, _crlf ) \
  do { \
    rtems_unsigned32 c0, c1, c2, c3; \
    \
    c0 = ((_name) >> 24) & 0xff; \
    c1 = ((_name) >> 16) & 0xff; \
    c2 = ((_name) >> 8) & 0xff; \
    c3 = (_name) & 0xff; \
    putchar( (char)c0 ); \
    if ( c1 ) putchar( (char)c1 ); \
    if ( c2 ) putchar( (char)c2 ); \
    if ( c3 ) putchar( (char)c3 ); \
    if ( (_crlf) ) \
      putchar( '\n' ); \
  } while (0)

/*
*  static inline routine to make obtaining ticks per second easier.
*/

static inline rtems_unsigned32 get_ticks_per_second( void )
{
  rtems_interval ticks_per_second;
  (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, 
&ticks_per_second );  return ticks_per_second;
}


/*
*  This allows us to view the "Test_task" instantiations as a set
*  of numbered tasks by eliminating the number of application
*  tasks created.
*
*  In reality, this is too complex for the purposes of this
*  example.  It would have been easier to pass a task argument. :)
*  But it shows how rtems_id's can sometimes be used.
*/

#define task_number( tid ) \
  ( rtems_get_index( tid ) - \
     
rtems_configuration_get_rtems_api_configuration()->number_of_initialization_tasks 
)

/* end of include file */

/*  bike.c
*
*  Program to control electric assist on a bicycle
*
*  Time slice size, memory mapping and other like definitions are in
*  confdefs.h, if definitions are to be set outside confdefs.h they
*  should be set prior to it as it set the required definitions to
*  default values if yet undefined
*
*  This file has been adapted from the file discussed below
*  It has been adapted for an e-bike application
*/

/*  Init
*
*  This routine is the initialization task for this test program.
*  It is called from init_exec and has the responsibility for creating
*  and starting the tasks that make up the test.  If the time of day
*  clock is required for the test, it should also be set to a known
*  value by this function.
*
*  Input parameters:  NONE
*
*  Output parameters:  NONE
*
*  COPYRIGHT (c) 1989-1999.
*  On-Line Applications Research Corporation (OAR).
*
*  The license and distribution terms for this file may be
*  found in the file LICENSE in this distribution or at
*  http://www.rtems.com/license/LICENSE.
*
*  init.c,v 1.11.6.1 2003/09/04 18:46:30 joel Exp
*/

/*start configuration information specific for timer*/

/*
*  confdefs.h n 4.5.0 does not account for each POSIX timer requiring
*  a Classic API timer because of the implementation.
*/
#define CONFIGURE_MAXIMUM_POSIX_TIMERS 1
#define CONFIGURE_MAXIMUM_TIMERS 1

/*end info specific for timer*/

#define CONFIGURE_INIT

/* includes, function prototypes added into system.h thus include it here:
* NB: confdefs.h is include at the end of system.h
*/
#include "system.h"

/*Verification for timer*/
#ifndef _POSIX_TIMERS
#error "rtems is supposed to have timer_create"
#endif

/*start configuration information specific for ticker*/

rtems_id   Task_id[ CONFIGURE_MAXIMUM_TASKS ];         /* array of task ids 
*/
rtems_name Task_name[ CONFIGURE_MAXIMUM_TASKS ];       /* array of task 
names */
double rpm, speed;
int drive_level;
char wheel, pedal;

/*end information specific for ticker*/

rtems_task Init( rtems_task_argument ignored)
{
  /*Declarations of variable needed by successful timing method (ticker)*/
  rtems_status_code status;
  rtems_time_of_day time;
  /*end ticker declarations*/
  struct sigevent  evp;

  printf( "E-bike Controller\n" ); /* to demonstrate RTOS is alive*/

  /*Assignment/definition required for timer creation*/
  evp.sigev_notify = SIGEV_NONE;

  /*Alternate, more successful, timing technique:*/

  puts( "\n\n*** E-BIKE v0.9 ***" );

  time.year   = 2004;
  time.month  = 4;
  time.day    = 1;
  time.hour   = 2;
  time.minute = 0;
  time.second = 0;
  time.ticks  = 0;

  drive_level=0; /*motor off*/

  status = rtems_clock_set( &time );

  /*Speed indicates the velocity of the bike (<5Hz)*/
  Task_name[KPH] = rtems_build_name('k','p','h',' ');
  /*RPM indicates the motor speed (<10Hz) or pedaling cadence (<3Hz)*/
  Task_name[RPM] = rtems_build_name('r','p','m',' ');
  /* Initial implementation will be the coast configuration below to allow
   * uninhibited pedalling reponse:
   * Coast configuration (rpm=cadence)
   * Drive motor to match speed, very testable as theoretically the bottom
   * bracket will then never freewheel nor will the clutch click and
   * disengage the motor due to unmatched chain speed
   * Cruise control configuration (rpm=motor speed)
   * Drive motor to match speed, very testable as theoretically the rear
   * hub will then never freewheel nor will the clutch click and disengage
   * the motor due to overdriving
   */
  Task_name[DRV] = rtems_build_name('d','r','v',' ');
  Task_name[WHL] = rtems_build_name('w','h','l',' ');
  Task_name[PED] = rtems_build_name('p','e','d',' ');

  status = rtems_task_create(
    Task_name[ KPH ], 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ KPH ]
  );
  status = rtems_task_create(
    Task_name[ RPM ], 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ RPM ]
  );
  status = rtems_task_create(
    Task_name[ DRV ], 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ DRV ]
  );
  status = rtems_task_create(
    Task_name[ WHL ], 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ WHL ]
  );
  status = rtems_task_create(
    Task_name[ PED ], 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ PED ]
  );

  status = rtems_task_start( Task_id[ KPH ], kph_task, KPH );
  status = rtems_task_start( Task_id[ RPM ], rpm_task, RPM );
  status = rtems_task_start( Task_id[ DRV ], drv_task, DRV );
  status = rtems_task_start( Task_id[ WHL ], wheel_sim, WHL );
  status = rtems_task_start( Task_id[ PED ], pedal_sim, PED );

  status = rtems_task_delete( RTEMS_SELF );

/*Exit taken care of by above task delete command, kept here as a
reminder*/
  exit( 0 );
}

/* end of file */
/*  tasks.c
*
*  E-bike tasks
*
*  This file has been adapted from the file discussed below
*  It has been adapted for an e-bike application
*/

/*  Test_task
*
*  This routine serves as a test task.  It verifies the basic task
*  switching capabilities of the executive.
*
*  Input parameters:  NONE
*
*  Output parameters:  NONE
*
*  COPYRIGHT (c) 1989-1999.
*  On-Line Applications Research Corporation (OAR).
*
*  The license and distribution terms for this file may be
*  found in the file LICENSE in this distribution or at
*  http://www.rtems.com/license/LICENSE.
*
*  tasks.c,v 1.9.4.1 2003/09/04 18:46:30 joel Exp
*/

#include "system.h"

rtems_task kph_task(
  rtems_task_argument unused
)
{
  int		oneHZperiod,
		fiveHZperiod,
		newperiod,
		period;
  double 	wheelsize,
		frequency;
  rtems_id      periodic;
  rtems_status_code status;
  rtems_name        name;

  oneHZperiod=get_ticks_per_second();
  fiveHZperiod=get_ticks_per_second()/5;
  newperiod=1; /*to ensure no div by 0 errors*/
  period=1;

  wheelsize=2.175; /*effective wheel circumference in meters*/

  name = rtems_build_name( 'P', 'k', 'p', 'h' );

  //this is reached
  puts( "kph_task has been called\n" );

  status = rtems_rate_monotonic_create( name, &periodic );

  //this is not reached
  puts( "kph_task has stopped executing\n" );

  if ( status != RTEMS_SUCCESSFUL ) {
    //printf( "rtems_monotonic_create failed with status of %d.\n", rc );
    printf( "rtems_monotonic_create failed\n");
    exit( 1 );
  }

  while ( 1 ) { /*Get speed*/
    if (rtems_rate_monotonic_period(periodic,fiveHZperiod) == RTEMS_TIMEOUT 
)
      break;

    /*indicate that timeslice has been allocated:*/
    printf("S\n");
    /*figure out speed*/
    if (wheel) {
      period=newperiod;
      newperiod=fiveHZperiod;
    }
    else {
      newperiod+=fiveHZperiod;
    }
    frequency=1/period;
    speed=wheelsize/1000*frequency*60*60;
  }

  /* missed period so delete periodic and SELF */
  printf( "kph rtems_rate_monotonic_period failed ie. TIMEOUT\n");

  status = rtems_rate_monotonic_delete( periodic );
  if ( status != RTEMS_SUCCESSFUL ) {
    printf( "rtems_rate_monotonic_delete failed with status of %d.\n", 
status );
    exit( 1 );
  }

  status = rtems_task_delete( RTEMS_SELF );    /* should not return */
  printf( "rtems_task_delete returned with status of %d.\n", status );
  exit( 1 );
}

rtems_task rpm_task(
  rtems_task_argument unused
)
{
  int		oneHZperiod,
		threeHZperiod,
		newperiod,
		period;
  double	frequency;
  rtems_id      periodic;
  rtems_status_code status;
  rtems_name        name;

  oneHZperiod=get_ticks_per_second();
  threeHZperiod=get_ticks_per_second()/3;
  newperiod=1; /*to ensure no div by 0 errors*/
  period=1;

  name = rtems_build_name( 'P', 'r', 'p', 'm' );

  //this is reached
  puts( "rpm_task has been called\n" );

  status = rtems_rate_monotonic_create( name, &periodic );

  //this is not reached
  puts( "rpm_task has stopped executing\n" );

  if ( status != RTEMS_SUCCESSFUL ) {
    //printf( "rtems_monotonic_create failed with status of %d.\n", rc );
    printf( "rtems_monotonic_create failed\n");
    exit( 1 );
  }

  while ( 1 ) { /*Get RPM*/
    if (rtems_rate_monotonic_period(periodic,threeHZperiod) == RTEMS_TIMEOUT 
)
      break;

    /*indicate that timeslice has been allocated:*/
    printf("R\n");
    /*figure out rpm*/
    if (pedal) {
      period=newperiod;
      newperiod=threeHZperiod;
    }
    else {
      newperiod+=threeHZperiod;
    }
    frequency=1/period;
    rpm=frequency*60;
  }

  /* missed period so delete period and SELF */
  printf( "rpm rtems_rate_monotonic_period failed ie. TIMEOUT\n");

  status = rtems_rate_monotonic_delete( periodic );
  if ( status != RTEMS_SUCCESSFUL ) {
    printf( "rtems_rate_monotonic_delete failed with status of %d.\n", 
status );
    exit( 1 );
  }

  status = rtems_task_delete( RTEMS_SELF );    /* should not return */
  printf( "rtems_task_delete returned with status of %d.\n", status );
  exit( 1 );
}

rtems_task drv_task(
  rtems_task_argument unused
)
{
  int		endtime,
		oneHZperiod,
		fiveHZperiod,
		chainring,
		sprocket_can_shift,
		drivecog,
		sprocket;
  double 	wheelsize;
  rtems_id      periodic;
  rtems_time_of_day time;
  rtems_status_code status;
  rtems_name        name;

  endtime=30;
  oneHZperiod=get_ticks_per_second();
  fiveHZperiod=get_ticks_per_second()/5;

  wheelsize=2.175; /*effective wheel circumference in meters*/
  /*Gear inch considerations - along with the automatic transmission
   *a task would keep track of the current gearing selected currently
   *we consider a static selection of: */
  chainring=40; /*larger one is 52T*/
  sprocket_can_shift=14; /*24T, 20T, 17T*/
  /*For the motor as it is electric with good low end torque a static
   *gearing is reasonable to expect even in a final prodect: */
  drivecog=16;
  sprocket=28;

  name = rtems_build_name( 'P', 'd', 'r', 'v' );

  //this is reached
  puts( "drv_task has been called\n" );

  status = rtems_rate_monotonic_create( name, &periodic );

  //this is not reached
  puts( "drv_task has stopped executing\n" );

  if ( status != RTEMS_SUCCESSFUL ) {
    //printf( "rtems_monotonic_create failed with status of %d.\n", rc );
    printf( "rtems_monotonic_create failed\n");
    exit( 1 );
  }

  while ( 1 ) { /*Drive motor, display state*/
    if (rtems_rate_monotonic_period(periodic,fiveHZperiod) == RTEMS_TIMEOUT 
)
      break;

    status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time );
    if ( time.second >= endtime ) {
      puts( "\n*** END OF E-BIKE RUN v5***" );
      exit( 0 );
    }
    /*Currently fuzzy logic driven as a benchmark
	Can then implement the algorithms used by others to compare
	various designs including a formal optimal controller*/
    /*The author realises "/60" is on both sides of the compare but
      the idea is to compare in reasonable mathematical units -
      frequency*/
    if ((rpm/60*chainring) <
        (speed/60/60/wheelsize*1000*sprocket_can_shift)) {
      /*most important is stopping*/
    if (drive_level>0)
      drive_level--;
    }
    else if ((rpm/60*chainring) >
             (speed/60/60/wheelsize*1000*sprocket_can_shift)) {
      /*then consider accelerating*/
      drive_level++;
    }
    else { /*speed appropriate*/
	/*retain drive level*/
    }

     /*display state - consider having fixed numerical fields eg. %02d*/

    printf("\nSpeed: %e kph, %e rpm, drive_level: %d\r", speed, rpm,
		drive_level);

    /*This task should run whenever new information is available
      in our case the minimum of the values above*/
    /*HOWEVER, current algorithm is iterative, thus run as often as
      possible with no blocking, but it then monopolizes without proper 
scheduling
      status = rtems_task_wake_after(fiveHZperiod); sleep enough for a 
context switch
      status = rtems_task_wake_after(get_ticks_per_second()); using rms 
now*/
  }

  /* missed period so delete period and SELF */
  printf( "drv rtems_rate_monotonic_period failed ie. TIMEOUT\n");

  status = rtems_rate_monotonic_delete( periodic );
  if ( status != RTEMS_SUCCESSFUL ) {
    printf( "rtems_rate_monotonic_delete failed with status of %d.\n", 
status );
    exit( 1 );
  }

  status = rtems_task_delete( RTEMS_SELF );    /* should not return */
  printf( "rtems_task_delete returned with status of %d.\n", status );
  exit( 1 );
}
/*  port_sim.c
*
*  E-bike port simulator tasks
*
*  This file has been adapted from the file discussed below
*  It has been adapted for an e-bike application
*/

/*  Test_task
*
*  This routine serves as a test task.  It verifies the basic task
*  switching capabilities of the executive.
*
*  Input parameters:  NONE
*
*  Output parameters:  NONE
*
*  COPYRIGHT (c) 1989-1999.
*  On-Line Applications Research Corporation (OAR).
*
*  The license and distribution terms for this file may be
*  found in the file LICENSE in this distribution or at
*  http://www.rtems.com/license/LICENSE.
*
*  tasks.c,v 1.9.4.1 2003/09/04 18:46:30 joel Exp
*/

#include "system.h"

/*A future task WRITES drive_level TO OUTPUT PORT timing communications
  						standards driven*/

rtems_task wheel_sim(
  rtems_task_argument unused
)
{
  int		oneHZperiod,
		fiveHZperiod,
		i;
  rtems_id      periodic;
  rtems_status_code status;
  rtems_name        name;

  oneHZperiod=get_ticks_per_second();
  fiveHZperiod=get_ticks_per_second()/5;

  name = rtems_build_name( 'P', 'w', 'h', 'l' );

  //this is reached
  puts( "whl_task has been called\n" );

  status = rtems_rate_monotonic_create( name, &periodic );

  //this is not reached
  puts( "whl_task has stopped executing\n" );

  if ( status != RTEMS_SUCCESSFUL ) {
    //printf( "rtems_monotonic_create failed with status of %d.\n", rc );
    printf( "rtems_monotonic_create failed\n");
    exit( 1 );
  }

  while ( 1 ) { /*create simulated data from wheel sensor*/
    if (rtems_rate_monotonic_period(periodic,fiveHZperiod) == RTEMS_TIMEOUT 
)
      break;

    /*indicate that timeslice has been allocated:*/
    printf("W\n");
    /* since speed will be computed using =wheelsize/1000*frequency*60*60 */
    /*multiplier defines slowest speed possible 4gives 60-> 12 secs*/
    for (i=0;i<((MAX_DRIVE_LEVEL-drive_level)*4);i++) {
      wheel=0;
      if (rtems_rate_monotonic_period(periodic,fiveHZperiod) == 
RTEMS_TIMEOUT )
        break;
    }
    wheel=1;
  }

  /* missed period so delete period and SELF */
  printf( "whl rtems_rate_monotonic_period failed ie. TIMEOUT\n");

  status = rtems_rate_monotonic_delete( periodic );
  if ( status != RTEMS_SUCCESSFUL ) {
    printf( "rtems_rate_monotonic_delete failed with status of %d.\n", 
status );
    exit( 1 );
  }

  status = rtems_task_delete( RTEMS_SELF );    /* should not return */
  printf( "rtems_task_delete returned with status of %d.\n", status );
  exit( 1 );
}

/*defined here to not use stack space rows of ten*/
static char ramp[]={
0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 0, 0, 1,

0, 0, 1, 0, 0, 1, 0, 0, 1,
0, 0, 1, 0, 0, 1, 0, 0, 1,
0, 0, 1, 0, 0, 1, 0, 0, 1,
0, 0, 1, 0, 0, 1, 0, 0, 1,

0, 0, 0, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 0};

rtems_task pedal_sim(
  rtems_task_argument unused
)
{
  int		oneHZperiod,
		threeHZperiod,
		i;
  rtems_id      periodic;
  rtems_status_code status;
  rtems_name        name;

  oneHZperiod=get_ticks_per_second();
  threeHZperiod=get_ticks_per_second()/3;

  name = rtems_build_name( 'P', 'p', 'e', 'd' );

  //this is reached
  puts( "ped_task has been called\n" );

  status = rtems_rate_monotonic_create( name, &periodic );

  //this is not reached
  puts( "ped_task has stopped executing\n" );

  if ( status != RTEMS_SUCCESSFUL ) {
    //printf( "rtems_monotonic_create failed with status of %d.\n", rc );
    printf( "rtems_monotonic_create failed\n");
    exit( 1 );
  }

  while ( 1 ) { /*create simulated data from pedal sensor*/
    Start:
    for (i=0; i < 90;i++) {
      if (rtems_rate_monotonic_period(periodic,threeHZperiod) == 
RTEMS_TIMEOUT )
        break;
      /*indicate that timeslice has been allocated:*/
      printf("P\n");
      /* since rpm will be computed using frequency*60   */
      /*accelerating from zero to plateau and down again*/
      pedal=ramp[i];
    }
    goto Start;
  }

  /* missed period so delete period and SELF */
  printf( "ped rtems_rate_monotonic_period failed ie. TIMEOUT\n");

  status = rtems_rate_monotonic_delete( periodic );
  if ( status != RTEMS_SUCCESSFUL ) {
    printf( "rtems_rate_monotonic_delete failed with status of %d.\n", 
status );
    exit( 1 );
  }

  status = rtems_task_delete( RTEMS_SELF );    /* should not return */
  printf( "rtems_task_delete returned with status of %d.\n", status );
  exit( 1 );
}

_________________________________________________________________
Tired of spam? Get advanced junk mail protection with MSN Premium   
http://join.msn.com/?pgmarket=en-ca&page=byoa/prem&xAPID=1994&DI=1034&SU=http://hotmail.com/enca&HL=Market_MSNIS_Taglines




More information about the users mailing list