Subversion Repositories shark

Rev

Rev 1643 | Rev 1650 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Project: S.Ha.R.K.
 *
 * Coordinators:
 *   Giorgio Buttazzo    <giorgio@sssup.it>
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *
 * Authors     :
 *   Giacomo Guidi       <giacomo@gandalf.sssup.it>
 *   Anton Cervin
 *
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
 *
 * http://www.sssup.it
 * http://retis.sssup.it
 * http://shark.sssup.it
 */


/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "kernel/kern.h"
#include "time.h"
#include "modules/elastic.h"
#include <drivers/shark_keyb26.h>


#define MAX_TASKS 7


/* A task that scrolls a number (the task number) across the screen */

TASK elastic_test(void *arg) {

  int y = (int)arg;
  int x = 0;  

  char str[2];
  str[0] = '0' + y + 1;
  str[1] = '\0';

  while(1) {
    puts_xy(x,y,LIGHTGRAY," ");
    x = (x + 1) % 80;
    puts_xy(x,y,LIGHTGRAY,str);
    task_testcancel();
    task_endcycle();
  }
}

/* A simple keyboard string input routine */

void myinput(char *query, char *buf, int len) {
  BYTE c;
  int n = 0;

  cprintf(query);

  do {
    c = keyb_getch(NON_BLOCK);
    if (c == '\r') break;
    if (c == '\b') {
      if (n > 0) {
        cprintf("%c", '\b');
        n--;
      }
    } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')) {
      cprintf("%c", c);
      buf[n++] = c;
    }
  } while (n < len);

  buf[n] = '\0';
  cprintf("\n");
}

/* The main program */

int main(int argc, char **argv)
{
  ELASTIC_TASK_MODEL e;
  PID el_pid;
  PID pidvec[MAX_TASKS];
  int quit = 0;
  char buf[80];
  int y;
  int Tmin, Tmax, C, E, T, nbr, i;
  double U, Umax;

  for (i=0; i<MAX_TASKS; i++) pidvec[i] = NIL;
  clear();

  /* Create predefined task 1 */
  elastic_task_default_model(e);
  elastic_task_def_period(e, 50000, 200000);
  elastic_task_def_wcet(e, 25000);
  elastic_task_def_param(e, 5, PERIOD_SCALING);
  elastic_task_def_arg(e, (void *)0);
  el_pid = task_create("Elastic",elastic_test,&e,NULL);
  if (el_pid == NIL) {
    cprintf("ELASTIC_public_create failed!\n");
  } else {
    pidvec[0] = el_pid;
    task_activate(el_pid);
  }

  /* Create predefined task 2 */
  elastic_task_default_model(e);
  elastic_task_def_period(e, 100000, 150000);
  elastic_task_def_wcet(e, 40000);
  elastic_task_def_param(e, 10, PERIOD_SCALING);
  elastic_task_def_arg(e, (void *)1);
  el_pid = task_create("Elastic",elastic_test,&e,NULL);
  if (el_pid == NIL) {
    cprintf("ELASTIC_public_create failed!\n");
  } else {
    pidvec[1] = el_pid;
    task_activate(el_pid);
  }

  do {

    /* Print task table */
    for (y = 7; y <=15; y++) {
      puts_xy(0,y,LIGHTGRAY,"                                                                                ");
    }
    place(0,7);

    U = 0.0;
    Umax = 0.0;
    cprintf("Nbr  Tmin  Tmax    C     E     T  \n");
    for (i=0; i<MAX_TASKS; i++) {
      if (pidvec[i] != NIL) {
        Tmin = ELASTIC_get_Tmin(pidvec[i]);
        Tmax = ELASTIC_get_Tmax(pidvec[i]);
        C = ELASTIC_get_C(pidvec[i]);
        E = ELASTIC_get_E(pidvec[i]);
        T = ELASTIC_get_period(pidvec[i]);
        U += (double)C/(double)T;
        Umax += (double)C/(double)Tmin;
        cprintf(" %1d   %4d  %4d  %4d  %4d  %4d\n", i+1, Tmin/1000, Tmax/1000, C/1000, E, T/1000);
      }
    }
    cprintf("Maximum utilization: %5.3f   Actual utilization: %5.3f\n", Umax, U);

    puts_xy(0,16,LIGHTGRAY,"                                                                                ");
    place(0,16);

    myinput("(q)uit, (c)reate, (k)ill, force (p)eriod, change (e)lasticity? ", buf, 10);
    for (y = 17; y <=24; y++) {
      puts_xy(0,y,LIGHTGRAY,"                                                                                ");
    }

    switch (buf[0]) {

      /* Quit */
    case 'q':
      quit = 1;
      break;

      /* Create task */
    case 'c':
      cprintf("Create task");
      for (i=0; i<MAX_TASKS; i++) {
        if (pidvec[i] == NIL) break;
      }
      if (i == MAX_TASKS) {
        cprintf("\nNo more task slots available!\n");
        break;
      } else {
        cprintf(" %d\n", i+1);
      }
      myinput("Tmin (ms): ", buf, 10);
      Tmin = 1000*atoi(buf);
      myinput("Tmax (ms): ", buf, 10);
      Tmax = 1000*atoi(buf);
      myinput("C (ms): ", buf, 10);
      C = 1000*atoi(buf);
      myinput("E: ", buf, 10);
      E = atoi(buf);
      elastic_task_default_model(e);
      elastic_task_def_period(e, Tmin, Tmax);
      elastic_task_def_wcet(e, C);
      elastic_task_def_param(e, E, PERIOD_SCALING);
      elastic_task_def_arg(e, (void *)i);
      el_pid = task_create("Elastic",elastic_test,&e,NULL);
      if (el_pid == NIL) {
        cprintf("ELASTIC_public_create failed!\n");
      } else {
        pidvec[i] = el_pid;
        task_activate(el_pid);
      }
      break;

      /* Force period */
    case 'p':
      myinput("Force period\nTask nbr: ", buf, 10);
      nbr = atoi(buf);
      if (nbr < 1 || nbr > MAX_TASKS) {
        cprintf("Invalid task number!\n");
        break;
      }
      el_pid = pidvec[nbr-1];
      if (el_pid == NIL) {
        cprintf("Task does not exist!\n");
        break;
      }
      myinput("T (ms): ", buf, 10);
      T = 1000*atoi(buf);
      if (ELASTIC_set_period(el_pid, T) == -1) {
        cprintf("ELASTIC_set_period failed!\n");
      }
      break;

      /* Kill task */
    case 'k':
      myinput("Kill task\nTask nbr: ", buf, 10);
      nbr = atoi(buf);
      if (nbr < 1 || nbr > MAX_TASKS) {
        cprintf("Invalid task number!\n");
        break;
      }
      el_pid = pidvec[nbr-1];
      if (el_pid == NIL) {
        cprintf("Task does not exist!\n");
        break;
      }
      task_kill(el_pid);
      pidvec[nbr-1] = NIL;
      usleep(500000);  // wait half a second before redrawing the task table!!!
      /* also erase task number */
      puts_xy(0,nbr-1,LIGHTGRAY,"                                                                                ");
      break;

      /* Set elasticity */
    case 'e':
      myinput("Set elasticity\nTask nbr: ", buf, 10);
      nbr = atoi(buf);
      if (nbr < 1 || nbr > MAX_TASKS) {
        cprintf("Invalid task number!\n");
        break;
      }
      el_pid = pidvec[nbr-1];
      if (el_pid == NIL) {
        cprintf("Task does not exist!\n");
        break;
      }
      myinput("E: ", buf, 10);
      E = atoi(buf);
      if (ELASTIC_set_E(el_pid, E) == -1) {
        cprintf("ELASTIC_set_E failed!\n");
      }
      break;

    default:
      cprintf("Unknown command\n");
      break;
    }

  } while (!quit);

  sys_end();

  return 0;

}