Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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