Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

/*
 * Project: S.Ha.R.K.
 *
 * Coordinators:
 *   Giorgio Buttazzo    <giorgio@sssup.it>
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *
 * Authors     :
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *   (see the web pages for full authors list)
 *
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
 *
 * http://www.sssup.it
 * http://retis.sssup.it
 * http://shark.sssup.it
 */


/*
 * Copyright (C) 2000 Giorgio Buttazzo, Paolo Gai, Massimiliano Giorgi
 *
 * 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
 *
 *
 * CVS :        $Id: sched.c,v 1.1 2002-11-11 08:22:46 pj Exp $

 This demo is derived from the cbsmouse.c Hartik's example.

 It only prints the task scheduling in graphic mode...

 There is a parameter to choose the type of scheduling module
 to initialize.

 to init correctly the module and task bandwidth parameters, set the defines
 NUM and DEN in initg.c and testg.c and remember the "s" (soft) parameter!!!

 to plot the deadlines assigned by CBS or TBS, compile cbs.c or tbs.c with
 the TESTG define
 (gray dots over the mouse line are the deadlines, green dots are CBS
  shifts)

  Note that a lot of times the demo exits with an exception; to avoid
  these exception you have to properly tune the task parameters.

  On a well configured machine, you will notice the little differences
  between different servers when moving the mouse ;-)

*/


#include <kernel/kern.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <drivers/mouse.h>
#include <semaphore.h>

/*--------------------------------------------------------------*/
/*                    TEST ON EDF SCHEDULING                    */
/*--------------------------------------------------------------*/

#define LMOUSE          20
#define LM              40              /* line of main         */
#define OFFSET          20              /* initial phase        */
#define CHAR_DIM        8               /* Height of chars in pixels */

#define DX (640/5-1)

int     col[3] = {2, 4, 14};            /* colors of timelines  */
int     lev[3] = {80, 120, 160};        /* level of timelines   */
int     ptime[3] = {10, 20, 25};        /* number of cycles     */
int     period[3] = {40, 50,100};       /* tasks' periods       */
int     tick = 1;                       /* system tick          */
int     tscale = 1;                     /* time scale           */
TIME    starttime = 0;                  /* Simulation start time (scaled) */

char *title;  /* used in initg.c */

/* period[] is scaled with a factor of PERIODSCALE usec */
#define PERIODSCALE 5000

// update also isched.c!!!
#define NUM 2000
#define DEN 64000

sem_t   mutex;                          /* Semaphore for graphix*/

//#define IY(y) (480 - y)
#define IY(y)    y

/*
 * mouse cursor
 *
 */


#define W WHITE
#define R RED
#define G GREEN
#define M MAGENTA

/* shape */

BYTE mycursor[16*16]= {
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   0,W,W,W,W,0,0,0,0,0,0,W,W,W,W,0,
   0,W,M,0,0,0,0,0,0,0,0,0,0,M,W,0,
   0,W,0,M,0,0,0,0,0,0,0,0,M,0,W,0,
   0,W,0,0,M,0,0,0,0,0,0,M,0,0,W,0,
   0,0,0,0,0,M,0,0,0,0,M,0,0,0,0,0,
   0,0,0,0,0,0,G,G,G,G,0,0,0,0,0,0,
   0,0,0,0,0,0,G,0,0,G,0,0,0,0,0,0,
   0,0,0,0,0,0,G,0,0,G,0,0,0,0,0,0,
   0,0,0,0,0,0,G,0,0,G,0,0,0,0,0,0,
   0,0,0,0,0,0,G,G,G,G,0,0,0,0,0,0,
   0,0,0,0,0,0,M,M,M,M,0,0,0,0,0,0,
   0,0,0,0,0,0,M,M,M,M,0,0,0,0,0,0,
   0,0,0,0,0,M,M,M,M,M,M,0,0,0,0,0,
   0,0,0,0,M,M,M,M,M,M,M,M,0,0,0,0,
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};

#define F 0xff
#define B 0x00

/* mask */
BYTE mybkg[16*16]= {
   B,B,B,B,B,B,F,F,F,F,B,B,B,B,B,B,
   B,0,0,0,0,B,F,F,F,F,B,0,0,0,0,B,
   B,0,0,B,B,F,F,F,F,F,B,B,B,0,0,B,
   B,0,B,0,B,F,F,F,F,F,F,B,0,B,0,B,
   B,0,B,B,0,B,F,F,F,F,B,0,B,B,0,B,
   B,B,B,F,B,0,B,B,B,B,0,B,F,B,B,B,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,B,B,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,B,B,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,B,B,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,B,0,0,0,0,0,0,B,F,F,F,F,
   F,F,F,B,0,0,0,0,0,0,0,0,B,F,F,F,
   F,F,F,B,B,B,B,B,B,B,B,B,B,F,F,F,
};

#undef B
#define B 0xff

/* bad mask */
BYTE mybadbkg[16*16]= {
   B,B,B,B,B,B,F,F,F,F,B,B,B,B,B,B,
   B,0,0,0,0,B,F,F,F,F,B,0,0,0,0,B,
   B,0,0,B,B,F,F,F,F,F,B,B,B,0,0,B,
   B,0,B,0,B,F,F,F,F,F,F,B,0,B,0,B,
   B,0,B,B,0,B,F,F,F,F,B,0,B,B,0,B,
   B,B,B,F,B,0,B,B,B,B,0,B,F,B,B,B,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,B,B,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,B,B,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,B,B,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,F,B,0,0,0,0,B,F,F,F,F,F,
   F,F,F,F,B,0,0,0,0,0,0,B,F,F,F,F,
   F,F,F,B,0,0,0,0,0,0,0,0,B,F,F,F,
   F,F,F,B,B,B,B,B,B,B,B,B,B,F,F,F,
};

/* very bad mask */
BYTE myverybadbkg[16*16]= {
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
   F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,
};
   

/*--------------------------------------------------------------*/
/*      Prints a grid to show task periods during execution     */
/*--------------------------------------------------------------*/

void    print_grid()
{
  int     i;
  int     a1, a2, a3;
  int     temp;

  a1 = 0;
  a2 = 0;
  a3 = 0;
  temp = 0;

  grx_text(title, 0, 240-10 ,10, 0);

  grx_line(OFFSET, lev[0], 639, lev[0], 5);
  grx_line(OFFSET, lev[1], 639, lev[1], 5);
  grx_line(OFFSET, lev[2], 639, lev[2], 5);
  grx_text("T1", 0, lev[0]-8, 9, 0);
  grx_text("T2", 0, lev[1]-8, 9, 0);
  grx_text("T3", 0, lev[2]-8, 9, 0);
  grx_text("MA", 0,     LM, 8, 0);
  grx_text("MO", 0,     LMOUSE, 8, 0);

  for (i = OFFSET; i < 640; i++) {
    if (temp >= a1) {
      grx_line(i, lev[0] - 1, i, lev[0] - 20, 3);
      a1 += period[0];
    }
    if (temp >= a2) {
      grx_line(i, lev[1] - 1, i, lev[1] - 20, 3);
      a2 += period[1];
    }
    if (temp >= a3) {
      grx_line(i, lev[2] - 1, i, lev[2] - 20, 3);
      a3 += period[2];
    }
    temp += tick/tscale;
  }
}

/*--------------------------------------------------------------*/
/*      This function is called at system termination           */
/*--------------------------------------------------------------*/

void    my_end()
{
  grx_close();
}

/*--------------------------------------------------------------*/
/*      GENERIC PERIODIC PROCESS                                */
/*--------------------------------------------------------------*/

TASK    color(int k)
{
  int     i;
  DWORD   x = OFFSET;
  TIME  t;
  while ( x < 640L) {
    for (i = 0; i < ptime[k]; i++) {

      t = sys_gettime(NULL) / PERIODSCALE;
      x = (t - starttime) + OFFSET;
      if (x>=640) break;
      sem_wait(&mutex);
      grx_plot(x, lev[k] - 4, col[k]);
      grx_plot(x, lev[k] - 5, col[k]);
      grx_plot(x, lev[k] - 6, col[k]);
      grx_plot(x, lev[k] - 7, col[k]);
      sem_post(&mutex);
      while (sys_gettime(NULL)/PERIODSCALE == t);
    }
    task_endcycle();
  }
  return 0;
}

void my_mouse_handler(MOUSE_EVT *ev)
{
  int x;

  x = (sys_gettime(NULL)/PERIODSCALE - starttime) + OFFSET;
  if (x>=640) return;
  sem_wait(&mutex);
  grx_plot(x, LMOUSE, 8);
  sem_post(&mutex);  
}

/*--------------------------------------------------------------*/
/*      MAIN PROCESS                                            */
/*--------------------------------------------------------------*/

int  main(int argc, char *argv[])
{
  int     x = OFFSET;

  MOUSE_PARMS mouse = BASE_MOUSE;
  HARD_TASK_MODEL mouse_hard;
  SOFT_TASK_MODEL mouse_soft;
  NRT_TASK_MODEL  mouse_nrt;

  char  c;
  KEY_EVT emerg;

  HARD_TASK_MODEL m_per;
  int modenum;

  set_exchandler_grx();

  if (argc>=3)
    switch(*argv[2]) {
      case 'h':
        /* this is not correct, because it don't remember activations */
        hard_task_default_model(mouse_hard);
        hard_task_def_mit(mouse_hard,DEN);
        hard_task_def_wcet(mouse_hard,NUM);
        hard_task_def_system(mouse_hard);
        hard_task_def_nokill(mouse_hard);
        hard_task_def_aperiodic(mouse_hard);
        mouse_def_task(mouse,(TASK_MODEL *)&mouse_hard);
        break;
      case 's':
        soft_task_default_model(mouse_soft);
        soft_task_def_wcet(mouse_soft,NUM);
        soft_task_def_met(mouse_soft,NUM);
        soft_task_def_period(mouse_soft,DEN);
        soft_task_def_system(mouse_soft);
        soft_task_def_nokill(mouse_soft);
        soft_task_def_aperiodic(mouse_soft);
        mouse_def_task(mouse,(TASK_MODEL *)&mouse_soft);
        break;
      case 'n':
        /* this is not correct, because it don't remember activations */
        nrt_task_default_model(mouse_nrt);
        nrt_task_def_system(mouse_nrt);
        nrt_task_def_nokill(mouse_nrt);
        mouse_def_task(mouse,(TASK_MODEL *)&mouse_nrt);
        break;
      default:
        argc=0;
        break;
    }

  /* Serial mous on COM3 */
  mouse_def_ms(mouse,2);

  if (argc>=4) {
    period[0]=atoi(argv[3]);
    if (period[0]<ptime[0]) period[0]=ptime[0]+5;
  }
  if (argc>=5) {
    period[1]=atoi(argv[4]);
    if (period[1]<ptime[1]) period[1]=ptime[1]+5;
  }
  if (argc>=6) {
    period[2]=atoi(argv[5]);
    if (period[2]<ptime[2]) period[2]=ptime[2]+5;
  }
     
  if (argc<2) {
    cprintf("syntax: x testg <config> <mouse-task> [t1] [t2] [t3]\n");
    cprintf("where <config> can be:\n");
    cprintf("\t0 - EDF + CBS                + RR\n");
    cprintf("\t1 - RM  + PS (  bkg, U=1/16) + RR, no check Ulub < 0.69\n");
    cprintf("\t2 - RM  + PS (nobkg, U=1/16) + RR, no check Ulub < 0.69\n");
    cprintf("\t3 - EDF + PS (  bkg, U=1/16) + RR\n");
    cprintf("\t4 - EDF + PS (nobkg, U=1/16) + RR\n");
    cprintf("\t5 - EDF + TBS(       U=1/16) + RR\n");
    cprintf("\t6 - RM  + DS (  bkg, U=1/16) + RR, no check Ulub < 0.69\n");
    cprintf("\t7 - RM  + DS (nobkg, U=1/16) + RR, no check Ulub < 0.69\n");
    cprintf("\nwhere <mouse-task> can be:\n");
    cprintf("\th - Hard\n");
    cprintf("\ts - Soft (understimated wcet)\n");
    cprintf("\tn - NRT\n");
    sys_end();
    return -1;
  }

  if (grx_init() == -1) {
    cprintf("Error initing GraphLib!!!\n");
    sys_end();
  }
  modenum = grx_getmode(640, 480, 8);
  cprintf("Modenum :%d\n", modenum);

  if (grx_setmode(modenum) == -1) {
    cprintf("No SetMode!!!\n");
    sys_end();
  }

  /* this trick can be useful when debugging ... */
  //grx_close();



  print_grid();
  grx_box(DX*0,240,DX*1-1,479,GREEN);
  grx_box(DX*1,240,DX*2-1,479,WHITE);
  grx_box(DX*2,240,DX*3-1,479,RED);
  grx_box(DX*3,240,DX*4-1,479,MAGENTA);
  grx_box(DX*4,240,DX*5-1,479,BLACK);

   
  sys_atrunlevel(my_end, NULL, RUNLEVEL_BEFORE_EXIT);

  /* mutex */
  sem_init(&mutex,0,1);

  /* keyboard */
  emerg.ascii = 'x';
  emerg.scan = KEY_X;
  emerg.flag = ALTL_BIT;
  keyb_hook(emerg,(void (*)(KEY_EVT *))sys_end);
  keyb_getchar();

  /* mouse */
  mouse_init(&mouse);
  mouse_limit(XMINLIMIT(640,480),
              240,
              XMAXLIMIT(640,480),
              YMAXLIMIT(640,480));
  mouse_position(320,280);
  mouse_threshold(2);
  //grx_setcolor(255,255,255,255);
  mouse_grxshape(mycursor,mybkg);
  mouse_grxcursor(ENABLE);
  mouse_on();
  mouse_hook(my_mouse_handler);

  /* hard task creation */

  hard_task_default_model(m_per);
  hard_task_def_mit(m_per,period[0]*PERIODSCALE);
  hard_task_def_wcet(m_per,ptime[0]*PERIODSCALE);
  hard_task_def_group(m_per, 1);
  //task_def_wcet(m, ptime[0] * sys_tick);
  if (task_create("verde", color, &m_per, NULL) == -1) {
    grx_close();
    perror("Edf.C(main) Could not create <green>:");
    sys_end();
  }
  hard_task_def_arg(m_per, (void *)1);
  hard_task_def_wcet(m_per, ptime[1]*PERIODSCALE);
  hard_task_def_mit(m_per,period[1]*PERIODSCALE);
  if (task_create("red", color, &m_per, NULL) == -1) {
    grx_close();
    perror("Edf.C(main) Could not create <red>:");
    sys_end();
  }
  hard_task_def_arg(m_per, (void *)2);
  hard_task_def_wcet(m_per, ptime[2]*PERIODSCALE);
  hard_task_def_mit(m_per,period[2]*PERIODSCALE);
  if (task_create("yellow", color, &m_per, NULL) == -1) {
    grx_close();
    perror("Edf.C(main) Could not create <yellow>:");
    sys_end();
  }
  starttime = sys_gettime(NULL) / PERIODSCALE;
  group_activate(1);

  /* main loop */
  while (x < 640L) {
    x = (sys_gettime(NULL)/PERIODSCALE - starttime) + OFFSET;
    if (x>=640) break;
    sem_wait(&mutex);
    grx_plot(x, LM, 7);
    sem_post(&mutex);
  }

  c = keyb_getchar();

  sys_end();
  return 0;
}

/*--------------------------------------------------------------*/