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