Subversion Repositories shark

Rev

Rev 1098 | Rev 1382 | 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
 *
1123 pj 37
 * CVS :        $Id: cabs.c,v 1.3 2003-01-07 17:10:15 pj Exp $
1098 pj 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 function is called when Alt-X is pressed.
92
   It simply shutdown the system using sys_end.
93
   Note that the byebye() function is called only if we exit from
94
   the system using sys_end()!!!!
95
*/
96
void my_end(KEY_EVT* e)
97
{
98
        sys_end();
99
}
100
 
101
/******************************************************************/
102
 
103
/* This function is called when the system exit correctly after Alt-X.
104
   It exits from the graphic mode and then it prints a small greeting.
105
   Note that:
106
   - The function calls grx_exit, so it must be registered using
107
     RUNLEVEL_BEFORE_EXIT (RUNLEVEL_AFTER_EXIT does not work because
108
     at that point the kernel is already returned in real mode!!!)
109
   - When an exception is raised, the exception handler is called.
110
     Since the exception handler already exits from the graphic mode,
111
     this funcion has not to be called. For this reason:
112
     . we registered byebye using the flag NO_AT_ABORT
113
     . the exception handler exits using sys_abort; in that way byebye is
114
       NOT called
115
*/
116
 
117
 
118
/*--------------------------------------------------------------*/
119
/* User exit function                                           */
120
/*--------------------------------------------------------------*/
121
 
122
void byebye(void *arg)
123
{
124
  grx_close();
1098 pj 125
  cprintf("Bye Bye!\n");
1085 pj 126
}
127
 
128
/*--------------------------------------------------------------*/
129
/* Main task                                                    */
130
/*--------------------------------------------------------------*/
131
 
132
 
133
/****************************** MAIN ******************************/
134
 
135
int main(int argc, char **argv)
136
{
137
    char c = 0;         /* character from keyboard      */
138
 
139
    /* Set the closing function */
1123 pj 140
    sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);
1085 pj 141
 
142
    /* graphic card Initialization */
143
    if (grx_init() < 1) {
144
       sys_abort(1);
145
    }
146
 
147
    if (grx_open(640, 480, 8) < 0) {
1098 pj 148
        cprintf("GRX Err\n");
1085 pj 149
        sys_abort(1);
150
    }
151
 
152
    grx_clear(BLACK);
153
 
154
    grx_text("Press a key [1-4]", 10, 16, 7, 0);
155
    grx_text("to create a pair",  10, 24, 7, 0);
156
    grx_text("ESC to exit demo",  10, 48, 7, 0);
157
 
158
    while (c != 27) {
159
      c = keyb_getch(BLOCK);
160
      if ((c >= '1') && (c <= '1'+NCAB-1))
161
        create_channel(c-'1');
162
    }
163
 
164
    sys_end();
165
 
166
    return 0;
167
}
168
 
169
 
170
/*--------------------------------------------------------------*/
171
/* write data in a cab                                          */
172
/*--------------------------------------------------------------*/
173
 
174
TASK    producer(void *arg)
175
{
176
int     i = (int)arg;
177
char    c;                      /* message character            */
178
char    *p;                     /* pointer to a cab buffer      */
179
char    s[2];                   /* string to display            */
180
int     k = 0;
181
int     x, y;
182
int     col = 13;
183
int     ybase = YY + i*DELTA;
184
 
185
        x = X1;
186
        y = ybase;
187
        s[1] = 0;
188
 
189
        k = 0;
190
        while (1) {
191
                c = 'A' + k;
192
                p = cab_reserve(cid[i]);
193
                *p = c;
194
                cab_putmes(cid[i], p);
195
 
196
                s[0] = c;
197
                k = (k + 1) % NCAR;
198
                grx_text(s,x,y,col,0);
199
 
200
                x += 8;
201
                if (x >= (X1 + NCAR*8)) {
202
                        x = X1;
203
                        y = y + 8;
204
                        if (y >= ybase+16) {
205
                                y = ybase;
206
                                col = col % 15 + 1;
207
                        }
208
                }
209
 
210
                task_endcycle();
211
        }
212
}
213
 
214
/*--------------------------------------------------------------*/
215
/* read data from a cab                                         */
216
/*--------------------------------------------------------------*/
217
 
218
TASK    consumer(void *arg)
219
{
220
int     i = (int)arg;
221
char    *p;
222
char    s[2];
223
int     x, y;
224
int     col = 13;
225
int     ybase = YY + i*DELTA;
226
 
227
        x = X2;
228
        y = ybase;
229
        s[1] = 0;
230
 
231
        while (1) {
232
                p = cab_getmes(cid[i]);
233
                s[0] = *p - 'A' + 'a';
234
                cab_unget(cid[i], p);
235
 
236
                grx_text(s,x,y,col,0);
237
                x += 8;
238
 
239
                if (x >= (X2 + NCAR*8)) {
240
                        x = X2;
241
                        y = y + 8;
242
                        if (y >= ybase+16) {
243
                                y = ybase;
244
                                col = col % 15 + 1;
245
                        }
246
                }
247
                task_endcycle();
248
        }
249
}
250
 
251
/*--------------------------------------------------------------*/
252
/* create the two tasks and a channel                           */
253
/*--------------------------------------------------------------*/
254
 
255
void    create_channel(int i)
256
{
257
        HARD_TASK_MODEL m;
258
 
259
        draw_channel(i);
260
        cid[i] = cab_create(cname[i], 1, 2);
261
 
262
        hard_task_default_model(m);
263
        hard_task_def_ctrl_jet (m);
264
        hard_task_def_arg      (m, (void *)i);
265
        hard_task_def_wcet     (m, w1[i]);
266
        hard_task_def_mit      (m, t1[i]);
267
        hard_task_def_usemath  (m);
268
        p1[i] = task_create(pname1[i], producer, &m, NULL);
269
        if (p1[i] == NIL) {
270
          grx_close();
271
          perror("Could not create task <producer>");
272
          sys_abort(1);
273
        }
274
        task_activate(p1[i]);
275
 
276
        hard_task_default_model(m);
277
        hard_task_def_ctrl_jet (m);
278
        hard_task_def_arg      (m, (void *)i);
279
        hard_task_def_wcet     (m, w2[i]);
280
        hard_task_def_mit      (m, t2[i]);
281
        hard_task_def_usemath  (m);
282
        p2[i] = task_create(pname2[i], consumer, &m, NULL);
283
        if (p2[i] == NIL) {
284
          grx_close();
285
          perror("Could not create task <consumer>");
286
          sys_abort(1);
287
        }
288
        task_activate(p2[i]);
289
}
290
 
291
/*--------------------------------------------------------------*/
292
/* Disegna i processi e il canale di comunicazione              */
293
/*--------------------------------------------------------------*/
294
 
295
void    draw_channel(int i)
296
{
297
char    buffer[32];                     /* buffer per sprintf   */
298
int     yc = YP + i*DELTA;              /* altezza del canale   */
299
 
300
        grx_circle(XP1,yc,R,2);
301
        grx_text("P1",XP1-8,yc-4,12,0);
302
 
303
        grx_circle(XP2,yc,R,2);
304
        grx_text("P2",XP2-8,yc-4,12,0);
305
 
306
        grx_rect(XC,yc-R,XC+L,yc+R,3);
307
        grx_text("CAB",XC+16,yc-4,12,0);
308
 
309
        grx_line(XP1+R,yc,XC,yc,4);
310
        grx_line(XC+L,yc,XP2-R,yc,4);
311
 
312
        grx_text("T1 =          ms",X1+40,yc+R+16,14,0);
313
        sprintf(buffer,"%ld", t1[i]);
314
        grx_text(buffer,X1+88,yc+R+16,14,0);
315
 
316
        grx_text("T2 =          ms",X2+40,yc+R+16,14,0);
317
        sprintf(buffer,"%ld", t2[i]);
318
        grx_text(buffer,X2+88,yc+R+16,14,0);
319
}
320
 
321
/*--------------------------------------------------------------*/
322