Exemplo n.º 1
0
void timeout_test_callout_reschedule(int mpsave, bool use_reset)
{
	enum arg argument = HANDLER_NOT_VISITED;
	struct callout callout;
	int retval = 0;
	printf("== Start a callout and reschedule it after some time with %s. mpsave=%d\n", use_reset ? "reset" : "schedule", mpsave);

	callout_init(&callout, mpsave);

	retval = callout_reset(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS), timeout_handler, &argument);
	assert(retval == 0);

	usleep(TEST_NOT_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);

	if(!use_reset)
	{
		retval = callout_schedule(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS));
	}
	else
	{
		retval = callout_reset(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS), timeout_handler, &argument);
	}
	assert(retval != 0);

	usleep(TEST_NOT_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);

	usleep(TEST_FIRED_MS * 1000);
	assert(argument == HANDLER_VISITED);

	callout_deactivate(&callout);
}
Exemplo n.º 2
0
rtems_task Init(
    rtems_task_argument ignored
)
{
    rtems_status_code    status;
    rtems_id             task_id;

    puts( "\n\n*** TEST 57 ***" );

    puts( "Init - rtems_task_create - delay task - OK" );
    status = rtems_task_create(
                 rtems_build_name( 'T', 'A', '1', ' ' ),
                 1,
                 RTEMS_MINIMUM_STACK_SIZE,
                 RTEMS_DEFAULT_OPTIONS,
                 RTEMS_DEFAULT_ATTRIBUTES,
                 &task_id
             );
    directive_failed( status, "rtems_task_create" );

    puts( "Init - rtems_task_start - delay task - OK" );
    status = rtems_task_start( task_id, Delay_task, 0 );
    directive_failed( status, "rtems_task_start" );

    puts( "Init - rtems_task_wake_after - let delay task block - OK" );
    status = rtems_task_wake_after( RTEMS_MILLISECONDS_TO_TICKS(1000) );
    directive_failed( status, "rtems_task_wake_after" );

    puts( "Init - rtems_task_restart - delay task - OK" );
    status = rtems_task_restart( task_id, 0 );
    directive_failed( status, "rtems_task_restart" );

    puts( "*** END OF TEST 57 ***" );
    rtems_test_exit(0);
}
Exemplo n.º 3
0
void timeout_test_callout_rwlock(bool delay_with_lock)
{
	enum arg argument = HANDLER_NOT_VISITED;
	struct callout callout;
	struct rwlock rw;
	int retval = 0;
	printf("== Start a callout with a rwlock%s\n", delay_with_lock ? " and delay execution by locking it." : ".");

	rw_init(&rw, "callouttest");
	callout_init_rw(&callout, &rw, 0);

	retval = callout_reset(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS), timeout_handler, &argument);
	assert(retval == 0);

	usleep(TEST_NOT_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);
	
	if(delay_with_lock)
	{
		retval = rw_try_wlock(&rw);
		assert(retval != 0);

		usleep(TEST_DELAY_MS * 1000);
		assert(argument == HANDLER_NOT_VISITED);

		rw_wunlock(&rw);
	}

	usleep(TEST_FIRED_MS * 1000);
	assert(argument == HANDLER_VISITED);
	
	callout_deactivate(&callout);
}
Exemplo n.º 4
0
void timeout_test_callout_mutex(bool delay_with_lock)
{
	enum arg argument = HANDLER_NOT_VISITED;
	struct callout callout;
	struct mtx mtx;
	int retval = 0;
	printf("== Start a callout with a mutex%s\n", delay_with_lock ? " and delay execution by locking it." : ".");

	mtx_init(&mtx, "callouttest", NULL, MTX_DEF);
	callout_init_mtx(&callout, &mtx, 0);

	retval = callout_reset(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS), timeout_handler, &argument);
	assert(retval == 0);

	usleep(TEST_NOT_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);

	if(delay_with_lock)
	{
		retval = mtx_trylock(&mtx);
		assert(retval != 0);

		usleep(TEST_DELAY_MS * 1000);
		assert(argument == HANDLER_NOT_VISITED);

		mtx_unlock(&mtx);
	}
	
	usleep(TEST_FIRED_MS * 1000);
	assert(argument == HANDLER_VISITED);
	
	callout_deactivate(&callout);

	mtx_destroy(&mtx);
}
Exemplo n.º 5
0
void timeout_test_cancel_callout(int mpsave, bool use_drain)
{
	enum arg argument = HANDLER_NOT_VISITED;
	struct callout callout;
	int retval = 0;
	printf("== Start a callout and cancel it with %s. mpsave=%d\n", use_drain ? "drain" : "stop", mpsave);

	callout_init(&callout, mpsave);

	retval = callout_reset(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS), timeout_handler, &argument);
	assert(retval == 0);

	usleep(TEST_NOT_FIRED_MS * 1000);

	if(!use_drain)
	{
		retval = callout_stop(&callout);
	}
	else
	{
		retval = callout_drain(&callout);
	}
	assert(retval != 0);
	
	usleep(TEST_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);

	callout_deactivate(&callout);
}
Exemplo n.º 6
0
rtems_task Task_1_through_3(
  rtems_task_argument index
)
{
  rtems_time_of_day time;
  rtems_status_code status;
  rtems_interval    ticks;
  rtems_name        name;

  status = rtems_object_get_classic_name( rtems_task_self(), &name );
  directive_failed( status, "rtems_object_get_classic_name" );

  ticks = RTEMS_MILLISECONDS_TO_TICKS( index * 5 * 1000 );

  while( FOREVER ) {
    status = rtems_clock_get_tod( &time );
    directive_failed( status, "rtems_clock_get_tod" );

    if ( time.second >= 35 ) {
      TEST_END();
      rtems_test_exit( 0 );
    }

    put_name( name, FALSE );
    print_time( " - rtems_clock_get_tod - ", &time, "\n" );

    status = rtems_task_wake_after( ticks );
    directive_failed( status, "rtems_task_wake_after" );
  }
}
Exemplo n.º 7
0
/*
 * sh4uart_set_baudrate --
 *     Program the UART timer to specified baudrate
 *
 * PARAMETERS:
 *     uart - pointer to UART descriptor structure
 *     baud - termios baud rate (B50, B9600, etc...)
 *
 * ALGORITHM:
 *     see SH7750 Hardware Manual.
 *
 * RETURNS:
 *     none
 */
static void
sh4uart_set_baudrate(sh4uart *uart, speed_t baud)
{
  uint32_t   rate;
  int16_t   div;
  int n;
  uint32_t   Pph = sh4uart_get_Pph();

  switch (baud) {
    case B50:     rate = 50; break;
    case B75:     rate = 75; break;
    case B110:    rate = 110; break;
    case B134:    rate = 134; break;
    case B150:    rate = 150; break;
    case B200:    rate = 200; break;
    case B300:    rate = 300; break;
    case B600:    rate = 600; break;
    case B1200:   rate = 1200; break;
    case B2400:   rate = 2400; break;
    case B4800:   rate = 4800; break;
    case B9600:   rate = 9600; break;
    case B19200:  rate = 19200; break;
    case B38400:  rate = 38400; break;
    case B57600:  rate = 57600; break;
#ifdef B115200
    case B115200: rate = 115200; break;
#endif
#ifdef B230400
    case B230400: rate = 230400; break;
#endif
    default:      rate = 9600; break;
  }

  for (n = 0; n < 4; n++) {
    div = Pph / (32 * (1 << (2 * n)) * rate) - 1;
    if (div < 0x100)
      break;
  }

  /* Set default baudrate if specified baudrate is impossible */
  if (n >= 4)
    sh4uart_set_baudrate(uart, B9600);

  if ( uart->chn == 1 ) {
    volatile uint8_t *smr1 = (volatile uint8_t *)SH7750_SCSMR1;
    *smr1 &= ~SH7750_SCSMR_CKS;
    *smr1 |= n << SH7750_SCSMR_CKS_S;
  } else {
    volatile uint16_t *smr2 = (volatile uint16_t *)SH7750_SCSMR2;
    *smr2 &= ~SH7750_SCSMR_CKS;
    *smr2 |= n << SH7750_SCSMR_CKS_S;
  }

  SCBRR(uart->chn) = div;
  /* Wait at least 1 bit interwal */
  rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000 / rate));
}
Exemplo n.º 8
0
rtems_task Init(
  rtems_task_argument ignored
)
{
  rtems_status_code     sc;
  rtems_id              period1;
  rtems_id              period2;

  puts( "\n\n*** TEST 60 ***" );

  puts( "Init - rtems_rate_monotonic_create - first period" );
  sc = rtems_rate_monotonic_create(
    rtems_build_name( 'P', 'E', 'R', '1' ),
    &period1
  );
  directive_failed( sc, "rtems_rate_monotonic_create 1" );

  puts( "Init - rtems_rate_monotonic_create - second period" );
  sc = rtems_rate_monotonic_create(
    rtems_build_name( 'P', 'E', 'R', '2' ),
    &period2
  );
  directive_failed( sc, "rtems_rate_monotonic_create 1" );

  puts( "Init - rtems_rate_monotonic_period - short period" );
  sc = rtems_rate_monotonic_period(period1, RTEMS_MILLISECONDS_TO_TICKS(200) );
  directive_failed( sc, "rtems_rate_monotonic_period" );

  puts( "Init - rtems_rate_monotonic_period - long period initiated" );
  sc = rtems_rate_monotonic_period(period2, RTEMS_MILLISECONDS_TO_TICKS(1000) );
  directive_failed( sc, "rtems_rate_monotonic_period" );

  puts( "Init - rtems_rate_monotonic_period - long period block" );
  sc = rtems_rate_monotonic_period(period2, RTEMS_MILLISECONDS_TO_TICKS(1000) );
  directive_failed( sc, "rtems_rate_monotonic_period" );

  puts( "Init - rtems_rate_monotonic_period - verify long period expired" );
  sc = rtems_rate_monotonic_period(period1, RTEMS_PERIOD_STATUS );
  fatal_directive_status(sc, RTEMS_TIMEOUT, "rtems_task_period status");

  puts( "*** END OF TEST 60 ***" );
  rtems_test_exit(0);
}
Exemplo n.º 9
0
rtems_task Delay_task(
    rtems_task_argument ignored
)
{
    rtems_status_code    status;

    puts( "Delay - rtems_task_wake_after - OK" );
    status = rtems_task_wake_after( RTEMS_MILLISECONDS_TO_TICKS(2000) );

    puts( "ERROR - delay task woke up!!" );
    rtems_test_exit(0);
}
Exemplo n.º 10
0
void timeout_test_timeout()
{
	enum arg argument = HANDLER_NOT_VISITED;
	struct callout_handle handle;
	
	printf("== Start a timeout and test if handler has been called.\n");

	callout_handle_init(&handle);

	handle = timeout(timeout_handler, &argument, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS));

	usleep(TEST_NOT_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);
	
	usleep(TEST_FIRED_MS * 1000);
	assert(argument == HANDLER_VISITED);
}
Exemplo n.º 11
0
void timeout_test_callout(int mpsave)
{
	enum arg argument = HANDLER_NOT_VISITED;
	struct callout callout;
	int retval = 0;
	printf("== Start a callout and test if handler has been called. mpsave=%d\n", mpsave);

	callout_init(&callout, mpsave);

	retval = callout_reset(&callout, RTEMS_MILLISECONDS_TO_TICKS(TIMEOUT_MILLISECONDS), timeout_handler, &argument);
	assert(retval == 0);

	usleep(TEST_NOT_FIRED_MS * 1000);
	assert(argument == HANDLER_NOT_VISITED);
	
	usleep(TEST_FIRED_MS * 1000);
	assert(argument == HANDLER_VISITED);

	callout_deactivate(&callout);
}
Exemplo n.º 12
0
/*
 * sh4uart_set_attributes --
 *     This function parse the termios attributes structure and perform
 *     the appropriate settings in hardware.
 *
 * PARAMETERS:
 *     uart - pointer to the UART descriptor structure
 *     t - pointer to termios parameters
 *
 * RETURNS:
 *     RTEMS_SUCCESSFUL
 */
rtems_status_code
sh4uart_set_attributes(sh4uart *uart, const struct termios *t)
{
  int level;
  speed_t baud;
  uint16_t   smr;

  smr = (uint16_t)(*(uint8_t*)SH7750_SCSMR(uart->chn));

  baud = cfgetospeed(t);

  /* Set flow control XXX*/
  if ((t->c_cflag & CRTSCTS) != 0) {
  }

  /* Set character size -- only 7 or 8 bit */
  switch (t->c_cflag & CSIZE) {
    case CS5:
    case CS6:
    case CS7: smr |= SH7750_SCSMR_CHR_7; break;
    case CS8: smr &= ~SH7750_SCSMR_CHR_7; break;
  }

    /* Set number of stop bits */
  if ((t->c_cflag & CSTOPB) != 0)
    smr |= SH7750_SCSMR_STOP_2;
  else
    smr &= ~SH7750_SCSMR_STOP_2;

  /* Set parity mode */
  if ((t->c_cflag & PARENB) != 0) {
    smr |= SH7750_SCSMR_PE;
    if ((t->c_cflag & PARODD) != 0)
       smr |= SH7750_SCSMR_PM_ODD;
    else
       smr &= ~SH7750_SCSMR_PM_ODD;
  } else
    smr &= ~SH7750_SCSMR_PE;

  rtems_interrupt_disable(level);
  /* wait untill all data is transmitted */
  /* XXX JOEL says this is broken -- interrupts are OFF so NO ticks  */
  rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(100));

  if ( uart->chn == 1 ) {
    volatile uint8_t *scrP = (volatile uint8_t *)SH7750_SCSCR1;
    volatile uint8_t *smrP = (volatile uint8_t *)SH7750_SCSMR1;

    *scrP &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); /* disable operations */
    sh4uart_set_baudrate(uart, baud);
    *smrP = (uint8_t)smr;
    *scrP |= SH7750_SCSCR_TE | SH7750_SCSCR_RE;    /* enable operations */
  } else {
    volatile uint16_t *scrP = (volatile uint16_t *)SH7750_SCSCR2;
    volatile uint16_t *smrP = (volatile uint16_t *)SH7750_SCSMR2;

    *scrP &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); /* disable operations */
    sh4uart_set_baudrate(uart, baud);
    *smrP = (uint8_t)smr;
    *scrP |= SH7750_SCSCR_TE | SH7750_SCSCR_RE;    /* enable operations */
  }

  rtems_interrupt_enable(level);

  return RTEMS_SUCCESSFUL;
}
Exemplo n.º 13
0
int main_pcmmio_dac(int argc, char **argv)
{
  int       dac;
  float     low_voltage;
  float     high_voltage;
  float     step_voltage;
  float     current_voltage;
  float     current_step;
  int       step_time;
  int       maximum_time;
  uint32_t  step_ticks;
  bool      fail = false;
  int       elapsed;

  /*
   *  Verify that we have the right number of arguments.
   */
  if ( (argc != 3) && (argc != 7) ) {
    printf( "Incorrect number of arguments\n" );
    PRINT_USAGE();
    return -1;
  }

  /*
   *  Convert the string arguments into number values
   */
  if ( rtems_string_to_int( argv[1], &dac, NULL, 0 ) ) {
    printf( "DAC (%s) is not a number\n", argv[1] );
    fail = true;
  }

  if ( rtems_string_to_float( argv[2], &low_voltage, NULL ) ) {
    printf( "Voltage (%s) is not a number\n", argv[2] );
    fail = true;
  }

  /*
   *  Validate the output dac and voltage.
   */
  if ( dac < 0 || dac > 7 ) {
    puts( "DAC number must be 0-7" );
    fail = true;
  }

  VALIDATE_VOLTAGE( low_voltage );

  /*
   *  Now do a single write to the DAC
   */
  if ( argc == 3 ) {
    if ( fail ) {
      PRINT_USAGE();
      return -1;
    }
    printf( "Write %6.4f to to dac %d\n", low_voltage, dac );
    set_dac_voltage(dac, low_voltage);
    return 0;
  }

  /*
   *  Finish parsing the arguments to do a pattern
   */
  fail = false;

  if ( rtems_string_to_float( argv[3], &high_voltage, NULL ) ) {
    printf( "Voltage (%s) is not a number\n", argv[3] );
    fail = true;
  }

  VALIDATE_VOLTAGE( high_voltage );

  if ( rtems_string_to_float( argv[4], &step_voltage, NULL ) ) {
    printf( "Step voltage (%s) is not a number\n", argv[4] );
    fail = true;
  }

  VALIDATE_VOLTAGE( step_voltage );

  if ( step_voltage < 0.0 ) {
    printf( "Step voltage must be greater than 0\n" );
    fail = true;
  }

  if ( rtems_string_to_int( argv[5], &step_time, NULL, 0 ) ) {
    printf( "Step time (%s) is not a number\n", argv[5] );
    fail = true;
  }

  if ( rtems_string_to_int( argv[6], &maximum_time, NULL, 0 ) ) {
    printf( "Maximum time (%s) is not a number\n", argv[6] );
    fail = true;
  }

  if ( step_time >= maximum_time ) {
    printf(
      "Step time (%d) must be less than maximum time (%d)\n",
      step_time,
      maximum_time
    );
    fail = true;
  }

  if ( step_time < 0 ) {
    printf( "Step time must be greater than 0\n" );
    fail = true;
  }

  if ( maximum_time < 0 ) {
    printf( "Maximum time must be greater than 0\n" );
    fail = true;
  }

  /*
   *  Now write the pattern to the DAC
   */

  if ( fail ) {
    PRINT_USAGE();
    return -1;
  }

  printf(
    "Write %6.4f-%6.4f step=%6.4f stepTime=%d msecs dac=%d max=%d msecs\n",
    low_voltage,
    high_voltage,
    step_voltage,
    step_time,
    dac,
    maximum_time
  );

  elapsed         = 0;
  step_ticks      = RTEMS_MILLISECONDS_TO_TICKS(step_time);
  current_voltage = low_voltage;
  current_step    = step_voltage;

  if ( low_voltage > high_voltage ) 
    current_step    *= -1.0;

  while (1) {
  
    #if defined(TESTING)
      printf( "%d: Write %6.4f to to dac %d\n", elapsed, current_voltage, dac );
    #endif
    set_dac_voltage(dac, current_voltage);

    current_voltage += current_step;
    if ( current_voltage < low_voltage ) {
      current_step    = step_voltage;
      current_voltage = low_voltage;
    } else if ( current_voltage > high_voltage ) {
      current_step    = -1.0 * step_voltage;
      current_voltage = high_voltage;
    }

    elapsed += step_time;
    if ( elapsed > maximum_time )
      break;

    rtems_task_wake_after( step_ticks );
  }
   
  return 0;
}
Exemplo n.º 14
0
rtems_task Init(
  rtems_task_argument ignored
)
{
  rtems_status_code     status;
  rtems_id              task_id;
  void                 *address_1;
  rtems_task_priority   priority;

  puts( "\n\n*** TEST 59 ***" );

  priority = RTEMS_MAXIMUM_PRIORITY / 4;
  priority = (priority * 3) + (priority / 2);
  printf( "Init - blocking task priority will be %" PRIdrtems_task_priority "\n", priority );

  puts( "Init - rtems_task_create - delay task - OK" );
  status = rtems_task_create(
     rtems_build_name( 'T', 'A', '1', ' ' ),
     priority,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_OPTIONS,
     RTEMS_DEFAULT_ATTRIBUTES,
     &task_id
  );
  directive_failed( status, "rtems_task_create" );

  puts( "Init - rtems_task_start - delay task - OK" );
  status = rtems_task_start( task_id, Blocking_task, 0 );
  directive_failed( status, "rtems_task_start" );

  puts( "Init - rtems_region_create - OK" );
  status = rtems_region_create(
    rtems_build_name('R', 'N', '0', '1'),
    Region_Memory,
    sizeof( Region_Memory ),
    64,
    RTEMS_PRIORITY,
    &Region
  );
  directive_failed( status, "rtems_region_create of RN1" );

  puts( "Init - rtems_region_get_segment - get segment to consume memory" );
  rtems_region_get_segment(
    Region,
    ALLOC_SIZE,
    RTEMS_PRIORITY,
    RTEMS_NO_TIMEOUT,
    &address_1
  );
  directive_failed( status, "rtems_region_get_segment" );

  puts( "Init - rtems_task_wake_after - let other task block - OK" );
  status = rtems_task_wake_after( RTEMS_MILLISECONDS_TO_TICKS(1000) );
  directive_failed( status, "rtems_task_wake_after" );

  puts( "Init - rtems_region_get_segment - return segment" );
  status = rtems_region_return_segment( Region, address_1 );
  directive_failed( status, "rtems_region_return_segment" );

  puts( "Init - rtems_task_wake_after - let other task run again - OK" );
  status = rtems_task_wake_after( RTEMS_MILLISECONDS_TO_TICKS(1000) );
  directive_failed( status, "rtems_task_wake_after" );

  puts( "*** END OF TEST 59 ***" );
  rtems_test_exit(0);
}
Exemplo n.º 15
0
static void
rtems_cpuusage_top_thread (rtems_task_argument arg)
{
  rtems_cpu_usage_data*  data = (rtems_cpu_usage_data*) arg;
  char                   name[13];
  int                    i;
  Heap_Information_block wksp;
  uint32_t               ival, fval;
  int                    task_count;
  rtems_event_set        out;
  rtems_status_code      sc;
  bool                   first_time = true;

  data->thread_active = true;

  _TOD_Get_uptime(&data->last_uptime);

  CPU_usage_Set_to_zero(&data->zero);

  while (data->thread_run)
  {
    Timestamp_Control uptime_at_last_reset = CPU_usage_Uptime_at_last_reset;
    size_t            tasks_size;
    size_t            usage_size;
    Timestamp_Control load;

    data->task_count = 0;
    rtems_iterate_over_all_threads_2(task_counter, data);

    tasks_size = sizeof(Thread_Control*) * (data->task_count + 1);
    usage_size = sizeof(Timestamp_Control) * (data->task_count + 1);

    if (data->task_count > data->task_size)
    {
      data->tasks = realloc(data->tasks, tasks_size);
      data->usage = realloc(data->usage, usage_size);
      data->current_usage = realloc(data->current_usage, usage_size);
      if ((data->tasks == NULL) || (data->usage == NULL) || (data->current_usage == NULL))
      {
        rtems_printf(data->printer, "top worker: error: no memory\n");
        data->thread_run = false;
        break;
      }
    }

    memset(data->tasks, 0, tasks_size);
    memset(data->usage, 0, usage_size);
    memset(data->current_usage, 0, usage_size);

    _Timestamp_Set_to_zero(&data->total);
    _Timestamp_Set_to_zero(&data->current);
    data->stack_size = 0;

    _TOD_Get_uptime(&data->uptime);
    _Timestamp_Subtract(&uptime_at_last_reset, &data->uptime, &data->uptime);
    _Timestamp_Subtract(&data->last_uptime, &data->uptime, &data->period);
    data->last_uptime = data->uptime;

    rtems_iterate_over_all_threads_2(task_usage, data);

    if (data->task_count > data->task_size)
    {
      data->last_tasks = realloc(data->last_tasks, tasks_size);
      data->last_usage = realloc(data->last_usage, usage_size);
      if ((data->last_tasks == NULL) || (data->last_usage == NULL))
      {
        rtems_printf(data->printer, "top worker: error: no memory\n");
        data->thread_run = false;
        break;
      }
      data->task_size = data->task_count;
    }

    memcpy(data->last_tasks, data->tasks, tasks_size);
    memcpy(data->last_usage, data->usage, usage_size);
    data->last_task_count = data->task_count;

    /*
     * We need to loop again to get suitable current usage values as we need a
     * last sample to work.
     */
    if (first_time)
    {
      rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(500));
      first_time = false;
      continue;
    }

    _Protected_heap_Get_information(&_Workspace_Area, &wksp);

    if (data->single_page)
      rtems_printf(data->printer,
                   "\x1b[H\x1b[J"
                   " ENTER:Exit  SPACE:Refresh"
                   "  S:Scroll  A:All  <>:Order  +/-:Lines\n");
    rtems_printf(data->printer, "\n");

    /*
     * Uptime and period of this sample.
     */
    rtems_printf(data->printer, "Uptime: ");
    print_time(data, &data->uptime, 20);
    rtems_printf(data->printer, " Period: ");
    print_time(data, &data->period, 20);

    /*
     * Task count, load and idle levels.
     */
    rtems_printf(data->printer, "\nTasks: %4i  ", data->task_count);

    _Timestamp_Subtract(&data->idle, &data->total, &load);
    _Timestamp_Divide(&load, &data->uptime, &ival, &fval);
    rtems_printf(data->printer,
                 "Load Average: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval);
    _Timestamp_Subtract(&data->current_idle, &data->current, &load);
    _Timestamp_Divide(&load, &data->period, &ival, &fval);
    rtems_printf(data->printer,
                 "  Load: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval);
    _Timestamp_Divide(&data->current_idle, &data->period, &ival, &fval);
    rtems_printf(data->printer,
                 "  Idle: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval);

    /*
     * Memory usage.
     */
    if (rtems_configuration_get_unified_work_area())
    {
      rtems_printf(data->printer, "\nMem: ");
      print_memsize(data, wksp.Free.total, "free");
      print_memsize(data, wksp.Used.total, "used");
    }
    else
    {
      region_information_block libc_heap;
      malloc_info(&libc_heap);
      rtems_printf(data->printer, "\nMem: Wksp: ");
      print_memsize(data, wksp.Free.total, "free");
      print_memsize(data, wksp.Used.total, "used  Heap: ");
      print_memsize(data, libc_heap.Free.total, "free");
      print_memsize(data, libc_heap.Used.total, "used");
    }

    print_memsize(data, data->stack_size, "stack\n");

    rtems_printf(data->printer,
       "\n"
        " ID         | NAME                | RPRI | CPRI   | TIME                | TOTAL   | CURRENT\n"
        "-%s---------+---------------------+-%s-----%s-----+---------------------+-%s------+--%s----\n",
       data->sort_order == RTEMS_TOP_SORT_ID ? "^^" : "--",
       data->sort_order == RTEMS_TOP_SORT_REAL_PRI ? "^^" : "--",
       data->sort_order == RTEMS_TOP_SORT_CURRENT_PRI ? "^^" : "--",
                          data->sort_order == RTEMS_TOP_SORT_TOTAL ? "^^" : "--",
       data->sort_order == RTEMS_TOP_SORT_CURRENT ? "^^" : "--"
    );

    task_count = 0;

    for (i = 0; i < data->task_count; i++)
    {
      Thread_Control*   thread = data->tasks[i];
      Timestamp_Control usage;
      Timestamp_Control current_usage;

      if (thread == NULL)
        break;

      if (data->single_page && (data->show != 0) && (i >= data->show))
        break;

      /*
       * We need to count the number displayed to clear the remainder of the
       * the display.
       */
      ++task_count;

      /*
       * If the API os POSIX print the entry point.
       */
      rtems_object_get_name(thread->Object.id, sizeof(name), name);
      if (name[0] == '\0')
        snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.Entry.Kinds.Numeric.entry);

      rtems_printf(data->printer,
                   " 0x%08" PRIx32 " | %-19s |  %3" PRId64 " |  %3" PRId64 "   | ",
                   thread->Object.id,
                   name,
                   thread->Real_priority.priority,
                   _Thread_Get_priority(thread));

      usage = data->usage[i];
      current_usage = data->current_usage[i];

      /*
       * Print the information
       */
      print_time(data, &usage, 19);
      _Timestamp_Divide(&usage, &data->total, &ival, &fval);
      rtems_printf(data->printer,
                   " |%4" PRIu32 ".%03" PRIu32, ival, fval);
      _Timestamp_Divide(&current_usage, &data->period, &ival, &fval);
      rtems_printf(data->printer,
                   " |%4" PRIu32 ".%03" PRIu32 "\n", ival, fval);
    }

    if (data->single_page && (data->show != 0) && (task_count < data->show))
    {
      i = data->show - task_count;
      while (i > 0)
      {
        rtems_printf(data->printer, "\x1b[K\n");
        i--;
      }
    }

    sc = rtems_event_receive(RTEMS_EVENT_1,
                             RTEMS_EVENT_ANY,
                             RTEMS_MILLISECONDS_TO_TICKS (data->poll_rate_usecs),
                             &out);
    if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT))
    {
      rtems_printf(data->printer,
                   "error: event receive: %s\n", rtems_status_text(sc));
      break;
    }
  }

  free(data->tasks);
  free(data->last_tasks);
  free(data->last_usage);
  free(data->current_usage);

  data->thread_active = false;

  rtems_task_delete (RTEMS_SELF);
}