Subversion Repositories shark

Rev

Rev 1086 | Rev 1123 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1098 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/*
20
 * Copyright (C) 2000 Giorgio Buttazzo, Paolo Gai
21
 *
22
 * This program is free software; you can redistribute it and/or modify
23
 * it under the terms of the GNU General Public License as published by
24
 * the Free Software Foundation; either version 2 of the License, or
25
 * (at your option) any later version.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
 * GNU General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU General Public License
33
 * along with this program; if not, write to the Free Software
34
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
35
 *
36
 *
37
 * CVS :        $Id: cabs.c,v 1.2 2002-10-28 08:11:29 pj Exp $
38
 */
39
 
1085 pj 40
/*--------------------------------------------------------------*/
41
/*                    TEST ON CABS                              */
42
/*--------------------------------------------------------------*/
43
 
44
#include <kernel/kern.h>
45
#include <modules/cabs.h>
46
#include <drivers/glib.h>
47
#include <drivers/keyb.h>
48
#include <string.h>
49
 
50
#define NCAB    4               /* max number of CABs   */
51
#define NCAR    26              /* generated characters */
52
 
53
#define YP      32              /* level of arrows      */
54
#define R       20              /* task radius          */
55
#define YY      (YP+R+32)       /* level of writing     */
56
#define DELTA   (2*R+72)        /* total channel hight  */
57
#define X1      120             /* start column for P1  */
58
#define X2      360             /* start column for P2  */
59
 
60
#define XP1     (X1+64)         /* X position of task 1 */
61
#define XP2     (X2+64)         /* X position of task 2 */
62
#define XC      (XP1+96)        /* X position of CAB    */
63
#define L       52              /* CAB rectangle length */
64
 
65
void    my_exit(KEY_EVT *k);
66
void    draw_channel(int i);
67
void    create_channel(int i);
68
void    get_data();
69
 
70
TASK    producer(void *arg);
71
TASK    consumer(void *arg);
72
 
73
char    *cname[NCAB] = {"cab1", "cab2", "cab3", "cab4"};
74
char    *pname1[NCAB] = {"wr1", "wr2", "wr3", "wr4"};
75
char    *pname2[NCAB] = {"rd1", "rd2", "rd3", "rd4"};
76
 
77
CAB     cid[NCAB];              /* CAB identifiers      */
78
PID     p1[NCAB], p2[NCAB];     /* task identifiers     */
79
 
80
/* Task Periods */
81
TIME    t1[NCAB] = {200000, 100000, 300000, 800000};
82
TIME    t2[NCAB] = {400000, 400000, 150000, 200000};
83
 
84
/* Task WCETS */
85
TIME    w1[NCAB] = {10000, 10000, 10000, 10000};
86
TIME    w2[NCAB] = {10000, 10000, 10000, 10000};
87
 
88
 
89
/****************************************************************/
90
 
91
/* This is the exception handler. It is called when an exception
92
   is raised.
93
   It exits from the graphical mode, then it prints a message and
94
   shutdown the kernel using sys_abort()
95
*/
96
 
97
void demo_exc_handler(int signo, siginfo_t *info, void *extra)
98
{
99
  struct timespec t;
100
 
101
  grx_close();
102
 
103
  /* Default action for an kern exception is  */
104
  kern_cli();
105
  ll_gettime(TIME_EXACT, &t),
1098 pj 106
  cprintf("\nS.Ha.R.K. Exception raised!!!"
107
          "\nTime (s:ns)     :%ld:%ld"
108
          "\nException number:%d (numbers in include/bits/errno.h)"
109
          "\nPID             :%d\n",
110
          t.tv_sec, t.tv_nsec, info->si_value.sival_int,
111
          info->si_task);
1085 pj 112
  sys_abort(1);
113
}
114
 
115
/******************************************************************/
116
 
117
/* This function is called when Alt-X is pressed.
118
   It simply shutdown the system using sys_end.
119
   Note that the byebye() function is called only if we exit from
120
   the system using sys_end()!!!!
121
*/
122
void my_end(KEY_EVT* e)
123
{
124
        sys_end();
125
}
126
 
127
/******************************************************************/
128
 
129
/* This function is called when the system exit correctly after Alt-X.
130
   It exits from the graphic mode and then it prints a small greeting.
131
   Note that:
132
   - The function calls grx_exit, so it must be registered using
133
     RUNLEVEL_BEFORE_EXIT (RUNLEVEL_AFTER_EXIT does not work because
134
     at that point the kernel is already returned in real mode!!!)
135
   - When an exception is raised, the exception handler is called.
136
     Since the exception handler already exits from the graphic mode,
137
     this funcion has not to be called. For this reason:
138
     . we registered byebye using the flag NO_AT_ABORT
139
     . the exception handler exits using sys_abort; in that way byebye is
140
       NOT called
141
*/
142
 
143
 
144
/*--------------------------------------------------------------*/
145
/* User exit function                                           */
146
/*--------------------------------------------------------------*/
147
 
148
void byebye(void *arg)
149
{
150
  grx_close();
1098 pj 151
  cprintf("Bye Bye!\n");
1085 pj 152
}
153
 
154
/*--------------------------------------------------------------*/
155
/* Main task                                                    */
156
/*--------------------------------------------------------------*/
157
 
158
 
159
/****************************** MAIN ******************************/
160
 
161
int main(int argc, char **argv)
162
{
163
    struct sigaction action;
164
 
165
    char c = 0;         /* character from keyboard      */
166
 
167
    /* Init the standard S.Ha.R.K. exception handler */
168
    action.sa_flags = SA_SIGINFO;            /* Set the signal action */
169
    action.sa_sigaction = demo_exc_handler;
170
    action.sa_handler = 0;
171
    sigfillset(&action.sa_mask); /* we block all the other signals... */
172
 
173
    if (sigaction(SIGHEXC, &action, NULL) == -1) {  /* set the signal */
174
      perror("Error initializing signals...");
175
      sys_end();
176
    }
177
 
178
    /* Set the closing function */
179
    sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT|NO_AT_ABORT);
180
 
181
    /* graphic card Initialization */
182
    if (grx_init() < 1) {
183
       sys_abort(1);
184
    }
185
 
186
    if (grx_open(640, 480, 8) < 0) {
1098 pj 187
        cprintf("GRX Err\n");
1085 pj 188
        sys_abort(1);
189
    }
190
 
191
    grx_clear(BLACK);
192
 
193
    grx_text("Press a key [1-4]", 10, 16, 7, 0);
194
    grx_text("to create a pair",  10, 24, 7, 0);
195
    grx_text("ESC to exit demo",  10, 48, 7, 0);
196
 
197
    while (c != 27) {
198
      c = keyb_getch(BLOCK);
199
      if ((c >= '1') && (c <= '1'+NCAB-1))
200
        create_channel(c-'1');
201
    }
202
 
203
    sys_end();
204
 
205
    return 0;
206
}
207
 
208
 
209
/*--------------------------------------------------------------*/
210
/* write data in a cab                                          */
211
/*--------------------------------------------------------------*/
212
 
213
TASK    producer(void *arg)
214
{
215
int     i = (int)arg;
216
char    c;                      /* message character            */
217
char    *p;                     /* pointer to a cab buffer      */
218
char    s[2];                   /* string to display            */
219
int     k = 0;
220
int     x, y;
221
int     col = 13;
222
int     ybase = YY + i*DELTA;
223
 
224
        x = X1;
225
        y = ybase;
226
        s[1] = 0;
227
 
228
        k = 0;
229
        while (1) {
230
                c = 'A' + k;
231
                p = cab_reserve(cid[i]);
232
                *p = c;
233
                cab_putmes(cid[i], p);
234
 
235
                s[0] = c;
236
                k = (k + 1) % NCAR;
237
                grx_text(s,x,y,col,0);
238
 
239
                x += 8;
240
                if (x >= (X1 + NCAR*8)) {
241
                        x = X1;
242
                        y = y + 8;
243
                        if (y >= ybase+16) {
244
                                y = ybase;
245
                                col = col % 15 + 1;
246
                        }
247
                }
248
 
249
                task_endcycle();
250
        }
251
}
252
 
253
/*--------------------------------------------------------------*/
254
/* read data from a cab                                         */
255
/*--------------------------------------------------------------*/
256
 
257
TASK    consumer(void *arg)
258
{
259
int     i = (int)arg;
260
char    *p;
261
char    s[2];
262
int     x, y;
263
int     col = 13;
264
int     ybase = YY + i*DELTA;
265
 
266
        x = X2;
267
        y = ybase;
268
        s[1] = 0;
269
 
270
        while (1) {
271
                p = cab_getmes(cid[i]);
272
                s[0] = *p - 'A' + 'a';
273
                cab_unget(cid[i], p);
274
 
275
                grx_text(s,x,y,col,0);
276
                x += 8;
277
 
278
                if (x >= (X2 + NCAR*8)) {
279
                        x = X2;
280
                        y = y + 8;
281
                        if (y >= ybase+16) {
282
                                y = ybase;
283
                                col = col % 15 + 1;
284
                        }
285
                }
286
                task_endcycle();
287
        }
288
}
289
 
290
/*--------------------------------------------------------------*/
291
/* create the two tasks and a channel                           */
292
/*--------------------------------------------------------------*/
293
 
294
void    create_channel(int i)
295
{
296
        HARD_TASK_MODEL m;
297
 
298
        draw_channel(i);
299
        cid[i] = cab_create(cname[i], 1, 2);
300
 
301
        hard_task_default_model(m);
302
        hard_task_def_ctrl_jet (m);
303
        hard_task_def_arg      (m, (void *)i);
304
        hard_task_def_wcet     (m, w1[i]);
305
        hard_task_def_mit      (m, t1[i]);
306
        hard_task_def_usemath  (m);
307
        p1[i] = task_create(pname1[i], producer, &m, NULL);
308
        if (p1[i] == NIL) {
309
          grx_close();
310
          perror("Could not create task <producer>");
311
          sys_abort(1);
312
        }
313
        task_activate(p1[i]);
314
 
315
        hard_task_default_model(m);
316
        hard_task_def_ctrl_jet (m);
317
        hard_task_def_arg      (m, (void *)i);
318
        hard_task_def_wcet     (m, w2[i]);
319
        hard_task_def_mit      (m, t2[i]);
320
        hard_task_def_usemath  (m);
321
        p2[i] = task_create(pname2[i], consumer, &m, NULL);
322
        if (p2[i] == NIL) {
323
          grx_close();
324
          perror("Could not create task <consumer>");
325
          sys_abort(1);
326
        }
327
        task_activate(p2[i]);
328
}
329
 
330
/*--------------------------------------------------------------*/
331
/* Disegna i processi e il canale di comunicazione              */
332
/*--------------------------------------------------------------*/
333
 
334
void    draw_channel(int i)
335
{
336
char    buffer[32];                     /* buffer per sprintf   */
337
int     yc = YP + i*DELTA;              /* altezza del canale   */
338
 
339
        grx_circle(XP1,yc,R,2);
340
        grx_text("P1",XP1-8,yc-4,12,0);
341
 
342
        grx_circle(XP2,yc,R,2);
343
        grx_text("P2",XP2-8,yc-4,12,0);
344
 
345
        grx_rect(XC,yc-R,XC+L,yc+R,3);
346
        grx_text("CAB",XC+16,yc-4,12,0);
347
 
348
        grx_line(XP1+R,yc,XC,yc,4);
349
        grx_line(XC+L,yc,XP2-R,yc,4);
350
 
351
        grx_text("T1 =          ms",X1+40,yc+R+16,14,0);
352
        sprintf(buffer,"%ld", t1[i]);
353
        grx_text(buffer,X1+88,yc+R+16,14,0);
354
 
355
        grx_text("T2 =          ms",X2+40,yc+R+16,14,0);
356
        sprintf(buffer,"%ld", t2[i]);
357
        grx_text(buffer,X2+88,yc+R+16,14,0);
358
}
359
 
360
/*--------------------------------------------------------------*/
361