OpenCores
URL https://opencores.org/ocsvn/c16/c16/trunk

Subversion Repositories c16

[/] [c16/] [tags/] [V10/] [rtos.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jsauermann
/*******************************************************************************
2
********************************************************************************
3
**                                                                            **
4
**                     TASK SWITCHING                                         **
5
**                                                                            **
6
********************************************************************************
7
*******************************************************************************/
8
 
9
enum
10
{
11
   TASK_RUNNING   = 0x00,
12
   TASK_BLOCKED   = 0x01,
13
   TASK_SLEEPING  = 0x02,
14
   TASK_SUSPENDED = 0x04
15
};
16
 
17
typedef struct _task Task;
18
typedef struct _semaphore Semaphore;
19
struct _task
20
{
21
   // members required at initialization...
22
   // 
23
   Task        * next_task;
24
   int         * stack_pointer;
25
   char          status;
26
   unsigned char priority;
27
   const char *  name;
28
   char *        stack_bottom;
29
   char *        stack_top;
30
 
31
   // members used later on
32
   //
33
   char          sema_ret;
34
   unsigned char saved_priority;
35
   Semaphore  *  waiting_for;
36
   Task *        next_waiting_task;
37
   int           sleep_count;
38
};
39
 
40
extern Task * current_task;
41
extern Task task_idle;
42
 
43
struct _semaphore
44
{
45
   int          counter;
46
   Task *       next_waiting;
47
   Task *       last_waiting;
48
   const char * name;
49
};
50
Semaphore rx_sema =    { 0, 0, 0, "rx_semaphore"   };
51
Semaphore t2_control = { 0, 0, 0, "task 2 control" };
52
Semaphore t3_control = { 0, 0, 0, "task 3 control" };
53
Semaphore serial_out = { 1, 0, 0, "serial out"     };
54
Semaphore tx_sema =    { 16, 0, 0, "tx_semaphore"  };
55
 
56
void switch_tasks()   // interrupts disabled !
57
{
58
Task * next = 0;
59
Task * t = current_task;
60
 
61
   /* for performance reasons, we hand-code the following:
62
 
63
   do { if (  !(t = t->next_task)->status       // t is running and
64
           && (!next                            // no next found so far,
65
              || t->priority > next->priority   // or t has higher priority
66
              )
67
           )  next = t;
68
      } while (t != current_task);
69
   */
70
 
71
   ASM("
72
st_loop:
73
        MOVE    0(SP), RR               ; RR = t
74
        MOVE    (RR), RR                ; RR = t->next_task
75
        MOVE    RR, 0(SP)               ; t  = t->next_task
76
        ADD     RR, #4                  ; RR = & t->status
77
        MOVE    (RR), RS                ; RR = t->status
78
        JMP     RRNZ, st_next_task      ; jump if (status != 0)
79
                                        ;
80
        MOVE    2(SP), RR               ; RR = next
81
        JMP     RRZ, st_accept          ; jump if (next == 0)
82
                                        ;
83
        ADD     RR, #5                  ; RR = & next->priority
84
        MOVE    (RR), RS                ; RR = next->priority
85
        MOVE    RR, LL                  ; LL = next->priority
86
        MOVE    0(SP), RR               ; RR = t
87
        ADD     RR, #5                  ; RR = & t->priority
88
        MOVE    (RR), RS                ; RR = t->priority
89
        SGT     LL, RR                  ; RR = (next->priority > t->priority)
90
        JMP     RRNZ, st_next_task      ; jump if (next->priority > t->priority)
91
st_accept:                              ;
92
        MOVE    0(SP), RR               ; RR = t
93
        MOVE    RR, 2(SP)               ; next = t
94
st_next_task:                           ;
95
        MOVE    0(SP), RR               ; RR = t
96
        MOVE    (Ccurrent_task), LL     ; LL = current_task
97
        SNE     LL, RR                  ; RR = (t != current_task)
98
        JMP     RRNZ, st_loop           ;
99
        ");
100
 
101
   if (current_task != next)
102
      {
103
        current_task->stack_pointer = (int *)ASM(" LEA  0(SP), RR");
104
        current_task = next;
105
        current_task->stack_pointer;  ASM(" MOVE RR, SP");
106
      }
107
}
108
//-----------------------------------------------------------------------------
109
void P(Semaphore * sema)
110
{
111
   ASM(" DI");
112
 
113
   if (--sema->counter < 0)
114
      {
115
        // this task blocks
116
        //
117
        current_task->waiting_for = sema;
118
        current_task->next_waiting_task = 0;
119
        current_task->status |= TASK_BLOCKED;
120
 
121
        if (sema->next_waiting)   // some tasks blocked already on sema
122
           sema->last_waiting->next_waiting_task = current_task;
123
        else                      // first task blocked on sema
124
           sema->next_waiting = current_task;
125
 
126
        sema->last_waiting = current_task;
127
        switch_tasks();
128
      }
129
 
130
   ASM(" RETI");
131
}
132
//-----------------------------------------------------------------------------
133
//
134
// return non-zero if timeout occured
135
//
136
char P_timed(Semaphore * sema, unsigned int ticks)
137
{
138
char ret = 0;
139
 
140
   ASM(" DI");
141
 
142
   if (--sema->counter < 0)
143
      {
144
        // this task blocks
145
        //
146
        current_task->waiting_for = sema;
147
        current_task->sleep_count = ticks;
148
        current_task->next_waiting_task = 0;
149
        current_task->status |= TASK_BLOCKED | TASK_SLEEPING;
150
        current_task->sema_ret = 0;
151
 
152
        if (sema->next_waiting)   // some tasks blocked already on sema
153
           sema->last_waiting->next_waiting_task = current_task;
154
        else                      // first task blocked on sema
155
           sema->next_waiting = current_task;
156
 
157
 
158
        switch_tasks();
159
        ret = current_task->sema_ret;
160
      }
161
 
162
   ASM(" EI");
163
   return ret;
164
}
165
//-----------------------------------------------------------------------------
166
//
167
// return non-zero if task switch required
168
//
169
char Vint(Semaphore * sema)   // interrupts disabled !
170
{
171
Task * next = sema->next_waiting;
172
 
173
   ++sema->counter;
174
 
175
   if (next)   // waiting queue not empty: remove first waiting
176
      {
177
        next->status &= ~(TASK_BLOCKED | TASK_SLEEPING);
178
 
179
        sema->next_waiting = next->next_waiting_task;
180
        if (!sema->next_waiting)   sema->last_waiting = 0;
181
 
182
        return next->priority > current_task->priority;
183
      }
184
 
185
   return 0;
186
}
187
//-----------------------------------------------------------------------------
188
void V(Semaphore * sema)
189
{
190
   ASM(" DI");
191
   if (Vint(sema))   switch_tasks();
192
   ASM(" RETI");
193
}
194
/*******************************************************************************
195
********************************************************************************
196
**                                                                            **
197
**                     INTERRUPT HANDLERS                                     **
198
**                                                                            **
199
********************************************************************************
200
*******************************************************************************/
201
 
202
unsigned char serial_in_buffer[16];
203
unsigned char serial_in_get       = 0;
204
unsigned char serial_in_put       = 0;
205
unsigned int  serial_in_overflows = 0;
206
 
207
char rx_interrupt()
208
{
209
char c = ASM(" IN   (IN_RX_DATA), RU");
210
 
211
   if (rx_sema.counter < sizeof(serial_in_buffer))
212
      {
213
        serial_in_buffer[serial_in_put] = c;
214
        if (++serial_in_put >= sizeof(serial_in_buffer))   serial_in_put = 0;
215
        return Vint(&rx_sema);
216
      }
217
   else
218
      {
219
        ++serial_in_overflows;
220
        return 0;
221
      }
222
}
223
//-----------------------------------------------------------------------------
224
 
225
unsigned char serial_out_buffer[16];
226
unsigned char serial_out_get = 0;
227
unsigned char serial_out_put = 0;
228
 
229
char tx_interrupt()
230
{
231
   if (tx_sema.counter < sizeof(serial_out_buffer))
232
      {
233
        serial_out_buffer[serial_out_get];
234
        ASM(" OUT  R, (OUT_TX_DATA)");
235
        if (++serial_out_get >= sizeof(serial_out_buffer))   serial_out_get = 0;
236
        return Vint(&tx_sema);
237
      }
238
   else
239
      {
240
        ASM(" MOVE #0x05, RR");            // RxInt and TimerInt
241
        ASM(" OUT  R, (OUT_INT_MASK)");
242
        return 0;
243
      }
244
}
245
//-----------------------------------------------------------------------------
246
 
247
unsigned int  milliseconds    = 0;
248
unsigned int  seconds_low     = 0;
249
unsigned int  seconds_mid     = 0;
250
unsigned int  seconds_high    = 0;
251
unsigned char seconds_changed = 0;
252
 
253
void timer_interrupt()
254
{
255
Task * t = current_task;
256
Semaphore * s;
257
Task * ts;
258
 
259
   ASM(" OUT  R, (OUT_RESET_TIMER)");
260
   if (++milliseconds == 1000)
261
      {
262
         milliseconds = 0;
263
         seconds_changed = 0xFF;
264
         if (++seconds_low == 0)
265
            {
266
              if (++seconds_mid == 0)   ++seconds_high;
267
            }
268
      }
269
 
270
   do {
271
        if (!--(t->sleep_count) && (t->status & TASK_SLEEPING))
272
           {
273
             t->status &= ~TASK_SLEEPING;
274
             if (t->status & TASK_BLOCKED)   // timed P
275
                {
276
                  t->status &= ~TASK_BLOCKED;
277
                  t->sema_ret = -1;
278
                  s = t->waiting_for;
279
                  ++s->counter;
280
                  ts = s->next_waiting;
281
                  if (t == ts)                    // t is first waiting
282
                     {
283
                       if (t == s->last_waiting)
284
                          { // t is also last (thus, the only) waiting
285
                            s->next_waiting = 0;
286
                            s->last_waiting = 0;
287
                          }
288
                       else
289
                          { // t is first of several waiting (thus, not last)
290
                            s->next_waiting = t->next_waiting_task;
291
                          }
292
                     }
293
                  else                            // t is subsequent waiting
294
                     {
295
                       while (t != ts->next_waiting_task)
296
                             ts = ts->next_waiting_task;
297
                       ts->next_waiting_task = t->next_waiting_task;
298
                       if (t == s->last_waiting)   // t is last waiting
299
                          s->last_waiting = ts;    // now ts is last waiting
300
                     }
301
                }
302
           }
303
      } while (current_task != (t = t->next_task));
304
}
305
//-----------------------------------------------------------------------------
306
void interrupt()
307
{
308
char ts_1 = 0;
309
char ts_2 = 0;
310
 
311
   ASM(" MOVE RR, -(SP)");
312
   ASM(" MOVE LL, RR");
313
   ASM(" MOVE RR, -(SP)");
314
 
315
   if (ASM(" IN   (IN_STATUS), RU") & 0x10)   ts_1  = rx_interrupt();
316
   if (ASM(" IN   (IN_STATUS), RU") & 0x20)   ts_2  = tx_interrupt();
317
   if (ASM(" IN   (IN_STATUS), RU") & 0x40)
318
      { timer_interrupt();   ts_1 = -1; }
319
 
320
   if (ts_1 | ts_2)   switch_tasks();
321
 
322
   ASM(" MOVE (SP)+, RR");
323
   ASM(" MOVE RR, LL");
324
   ASM(" MOVE (SP)+, RR");
325
   ASM(" ADD  SP, #2");
326
   ASM(" RETI");
327
}
328
//-----------------------------------------------------------------------------
329
void sleep(int millisecs)
330
{
331
   ASM(" DI");
332
   current_task->sleep_count = millisecs;
333
   current_task->status      = TASK_SLEEPING;
334
   switch_tasks();
335
   ASM(" RETI");
336
}
337
//-----------------------------------------------------------------------------
338
void deschedule()
339
{
340
   ASM(" DI");
341
   switch_tasks();
342
   ASM(" RETI");
343
}
344
/*******************************************************************************
345
********************************************************************************
346
**                                                                            **
347
**                     UTILITY FUNCTIONS                                      **
348
**                                                                            **
349
********************************************************************************
350
*******************************************************************************/
351
 
352
int strlen(const char * buffer)
353
{
354
const char * from = buffer;
355
 
356
    while (*buffer)   buffer++;
357
 
358
   return buffer - from;
359
}
360
/*******************************************************************************
361
********************************************************************************
362
**                                                                            **
363
**                     SERIAL OUTPUT                                          **
364
**                                                                            **
365
********************************************************************************
366
*******************************************************************************/
367
 
368
int putchr(char c)
369
{
370
   P(&tx_sema);   // get free position
371
 
372
   serial_out_buffer[serial_out_put] = c;
373
   if (++serial_out_put >= sizeof(serial_out_buffer))   serial_out_put = 0;
374
   ASM(" MOVE #0x07, RR");            // RxInt and TxInt and TimerInt
375
   ASM(" OUT  R, (OUT_INT_MASK)");
376
   1;
377
}
378
//-----------------------------------------------------------------------------
379
void print_n(char c, int count)
380
{
381
    for (; count > 0; --count)   putchr(c);
382
}
383
//-----------------------------------------------------------------------------
384
void print_string(const char * buffer)
385
{
386
    while (*buffer)   putchr(*buffer++);
387
}
388
//-----------------------------------------------------------------------------
389
void print_hex(char * dest, unsigned int value, const char * hex)
390
{
391
   if (value >= 0x1000)   *dest++ = hex[(value >> 12) & 0x0F];
392
   if (value >=  0x100)   *dest++ = hex[(value >>  8) & 0x0F];
393
   if (value >=   0x10)   *dest++ = hex[(value >>  4) & 0x0F];
394
   *dest++ = hex[value  & 0x0F];
395
   *dest = 0;
396
}
397
//-----------------------------------------------------------------------------
398
void print_unsigned(char * dest, unsigned int value)
399
{
400
   if (value >= 10000)    *dest++ = '0' + (value / 10000);
401
   if (value >=  1000)    *dest++ = '0' + (value /  1000) % 10;
402
   if (value >=   100)    *dest++ = '0' + (value /   100) % 10;
403
   if (value >=    10)    *dest++ = '0' + (value /    10) % 10;
404
   *dest++ = '0' + value % 10;
405
   *dest = 0;
406
}
407
//-----------------------------------------------------------------------------
408
int print_item(const char * buffer, char flags, char sign, char pad,
409
               const char * alt, int field_w, int min_w, char min_p)
410
{
411
   // [fill] [sign] [alt] [pad] [buffer] [fill]
412
   //        ----------- len ----------- 
413
int filllen = 0;
414
int signlen = 0;
415
int altlen  = 0;
416
int padlen  = 0;
417
int buflen  = strlen(buffer);
418
int len;
419
int i;
420
 
421
   if (min_w > buflen)          padlen = min_w - buflen;
422
   if (sign)                    signlen = 1;
423
   if (alt && (flags & 0x01))   altlen = strlen(alt);
424
 
425
   len = signlen + altlen + padlen + buflen;
426
 
427
   if (0x02 & ~flags)   print_n(pad, field_w - len);   // right align
428
 
429
   if (sign)   putchr(sign);
430
   if (alt)
431
      {
432
        if (flags & 0x01)   print_string(alt);
433
      }
434
 
435
   for (i = 0; i < padlen; i++)   putchr(min_p);
436
   print_string(buffer);
437
 
438
   if (0x02 & flags)   print_n(pad, field_w - len);   // left align
439
 
440
   return len;
441
}
442
//-----------------------------------------------------------------------------
443
int printf(const char * format, ...)
444
{
445
const char **  args = 1 + &format;
446
int            len = 0;
447
char           c;
448
char           flags;
449
char           sign;
450
char           pad;
451
const char *   alt;
452
int            field_w;
453
int            min_w;
454
unsigned int * which_w;
455
char           buffer[12];
456
 
457
   while (c = *format++)
458
       {
459
         if (c != '%')   { len +=putchr(c);   continue; }
460
 
461
         flags   = 0;
462
         sign    = 0;
463
         pad     = ' ';
464
         field_w = 0;
465
         min_w   = 0;
466
         which_w = &field_w;
467
         for (;;)
468
             {
469
               switch(c = *format++)
470
                  {
471
                    case 'X': print_hex(buffer, (unsigned int)*args++,
472
                                        "0123456789ABCDEF");
473
                              len += print_item(buffer, flags, sign, pad,
474
                                                "0X", field_w, min_w, '0');
475
                              break;
476
 
477
                    case 'd': if (((int)*args) < 0)
478
                                 {
479
                                   sign = '-';
480
                                   *args = (char *)(- ((int)*args));
481
                                 }
482
                              print_unsigned(buffer, ((int)*args++));
483
                              len += print_item(buffer, flags, sign, pad,
484
                                                "", field_w, min_w, '0');
485
                              break;
486
 
487
                    case 's': len += print_item(*args++, flags & 0x02, 0, ' ',
488
                                                "", field_w, min_w, ' ');
489
                              break;
490
 
491
                    case 'u': print_unsigned(buffer, (unsigned int)*args++);
492
                              len += print_item(buffer, flags, sign, pad,
493
                                                "", field_w, min_w, '0');
494
                              break;
495
 
496
                    case 'x': print_hex(buffer, (unsigned int)*args++,
497
                                        "0123456789abcdef");
498
                              len += print_item(buffer, flags, sign, pad,
499
                                                "0x", field_w, min_w, '0');
500
                              break;
501
 
502
                    case 'c': len += putchr((int)*args++);    break;
503
 
504
                    case '#': flags |= 0x01;                  continue;
505
                    case '-': flags |= 0x02;                  continue;
506
                    case ' ': if (!sign)  sign = ' ';         continue;
507
                    case '+': sign = '+';                     continue;
508
                    case '.': which_w = &min_w;               continue;
509
 
510
                    case '0': if (*which_w)   *which_w *= 10;
511
                              else            pad = '0';
512
                              continue;
513
 
514
                    case '1': *which_w = 10 * *which_w + 1;   continue;
515
                    case '2': *which_w = 10 * *which_w + 2;   continue;
516
                    case '3': *which_w = 10 * *which_w + 3;   continue;
517
                    case '4': *which_w = 10 * *which_w + 4;   continue;
518
                    case '5': *which_w = 10 * *which_w + 5;   continue;
519
                    case '6': *which_w = 10 * *which_w + 6;   continue;
520
                    case '7': *which_w = 10 * *which_w + 7;   continue;
521
                    case '8': *which_w = 10 * *which_w + 8;   continue;
522
                    case '9': *which_w = 10 * *which_w + 9;   continue;
523
                    case '*': *which_w = (int)*args++;        continue;
524
 
525
                    case 0:   format--;   // premature end of format
526
                              break;
527
 
528
                    default:  len += putchr(c);
529
                              break;
530
                  }
531
                break;
532
             }
533
       }
534
   return len;
535
}
536
/*******************************************************************************
537
********************************************************************************
538
**                                                                            **
539
**                     SERIAL INPUT                                           **
540
**                                                                            **
541
********************************************************************************
542
*******************************************************************************/
543
 
544
int getchr()
545
{
546
char c;
547
 
548
   P(&rx_sema);
549
 
550
   c = serial_in_buffer[serial_in_get];
551
   if (++serial_in_get >= sizeof(serial_in_buffer))   serial_in_get = 0;
552
   return c;
553
}
554
//-----------------------------------------------------------------------------
555
int getchr_timed(unsigned int ticks)
556
{
557
char c;
558
 
559
   c = P_timed(&rx_sema, ticks);
560
   if (c)   return -1;   // if rx_sema timed out
561
 
562
   c = serial_in_buffer[serial_in_get];
563
   if (++serial_in_get >= sizeof(serial_in_buffer))   serial_in_get = 0;
564
   return c;
565
}
566
//-----------------------------------------------------------------------------
567
int peekchr()
568
{
569
   P(&rx_sema);
570
   V(&rx_sema);
571
 
572
   return serial_in_buffer[serial_in_get];
573
}
574
//-----------------------------------------------------------------------------
575
char getnibble(char echo)
576
{
577
char c  = peekchr();
578
int ret = -1;
579
 
580
   if      ((c >= '0') && (c <= '9'))   ret = c - '0';
581
   else if ((c >= 'A') && (c <= 'F'))   ret = c - 0x37;
582
   else if ((c >= 'a') && (c <= 'f'))   ret = c - 0x57;
583
 
584
   if (ret != -1)   // valid hex char
585
      {
586
        getchr();
587
        if (echo)   putchr(c);
588
      }
589
   return ret;
590
}
591
//-----------------------------------------------------------------------------
592
int gethex(char echo)
593
{
594
int  ret = 0;
595
char c;
596
 
597
   while ((c = getnibble(echo)) != -1)   ret = (ret << 4) | c;
598
   return ret;
599
}
600
/*******************************************************************************
601
********************************************************************************
602
**                                                                            **
603
**                     main and its helpers                                   **
604
**                                                                            **
605
********************************************************************************
606
*******************************************************************************/
607
 
608
//-----------------------------------------------------------------------------
609
void init_stack()
610
{
611
char * bottom = current_task->stack_bottom;
612
 
613
   while (bottom < (char *)ASM(" LEA 0(SP), RR"))   *bottom++ = 'S';
614
}
615
//-----------------------------------------------------------------------------
616
 
617
extern char * end_text;
618
 
619
void init_unused()   // MUST only be called by idle task
620
{
621
char * cp = current_task->stack_bottom;
622
 
623
   while (--cp >= (char *)&end_text)   *cp = ' ';
624
}
625
//-----------------------------------------------------------------------------
626
int stack_used(Task * t)
627
{
628
char * bottom = t->stack_bottom;
629
 
630
   while (*bottom == 'S')   bottom++;
631
   return t->stack_top - bottom;
632
}
633
//-----------------------------------------------------------------------------
634
void show_sema(Semaphore * s)
635
{
636
Task * t;
637
 
638
   printf("%-20s %4d ", s->name, s->counter);
639
   if (s->counter < 0)
640
      {
641
        for (t = s->next_waiting; t; t = t->next_waiting_task)
642
            {
643
              printf("%s -> ", t->name);
644
              if (t == s->last_waiting)   printf("0");
645
            }
646
      }
647
   else
648
      {
649
        printf("none.");
650
      }
651
   printf("\r\n");
652
}
653
//-----------------------------------------------------------------------------
654
 
655
unsigned char loader[] =
656
{
657
//  0xF8, 0x18, 0x00, 0x4F, 0xFC, 0x00, 0xA0, 0x08, 
658
//  0x6E, 0x0E, 0x24, 0x1A, 0x00, 0x03, 0x07, 0x00, 
659
//  0xF8, 0x32, 0x9E, 0x4F, 0x05, 0xF0, 0x9E, 0x00, 
660
//  0xE8, 0x01,
661
 
662
                0x2E, 0x01, 0x11, 0x01, 0x3D, 0x03,
663
    0x32, 0x1E, 0x2E, 0x00, 0x07, 0x2E, 0x01, 0x11,
664
    0x02, 0x03, 0x3D, 0x1E, 0x65, 0x02, 0x2F, 0x00,
665
    0x07, 0x02, 0x59, 0x1E, 0x61, 0x02, 0xA1, 0x5D,
666
    0x02, 0xB1, 0x47, 0x0F, 0x05, 0x3D, 0x1E, 0x2B,
667
    0x01, 0x61, 0x02, 0x47, 0x03, 0x4C, 0x1E, 0x07,
668
    0x05, 0x32, 0x1E, 0x0F, 0x65, 0x00, 0x29, 0x30,
669
    0x04, 0x71, 0x1E, 0xF8, 0xFF, 0x00, 0x02, 0xBB,
670
    0x1E, 0x65, 0x00, 0x27, 0x39, 0x04, 0x7F, 0x1E,
671
    0x65, 0x00, 0xF7, 0x30, 0x02, 0xBB, 0x1E, 0x65,
672
    0x00, 0x29, 0x41, 0x04, 0x8C, 0x1E, 0xF8, 0xFF,
673
    0x00, 0x02, 0xBB, 0x1E, 0x65, 0x00, 0x27, 0x46,
674
    0x04, 0x9A, 0x1E, 0x65, 0x00, 0xF7, 0x37, 0x02,
675
    0xBB, 0x1E, 0x65, 0x00, 0x29, 0x61, 0x04, 0xA7,
676
    0x1E, 0xF8, 0xFF, 0x00, 0x02, 0xBB, 0x1E, 0x65,
677
    0x00, 0x27, 0x66, 0x04, 0xB5, 0x1E, 0x65, 0x00,
678
    0xF7, 0x57, 0x02, 0xBB, 0x1E, 0xF8, 0xFF, 0x00,
679
    0x02, 0xBB, 0x1E, 0x2B, 0x01, 0x07, 0x05, 0x60,
680
    0x1E, 0x0F, 0x2D, 0x65, 0x01, 0x18, 0xFF, 0x00,
681
    0x04, 0xE3, 0x1E, 0x05, 0x60, 0x1E, 0x5F, 0x00,
682
    0x65, 0x00, 0x18, 0xFF, 0x00, 0x04, 0xE3, 0x1E,
683
    0x65, 0x01, 0x52, 0x04, 0x43, 0x65, 0x00, 0x31,
684
    0x02, 0xED, 0x1E, 0xF8, 0xC7, 0x1F, 0x0E, 0x05,
685
    0x49, 0x1E, 0x2B, 0x02, 0x00, 0x2B, 0x02, 0x07,
686
    0x2D, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, 0xF8, 0xDA,
687
    0x1F, 0x0E, 0x05, 0x49, 0x1E, 0x2B, 0x02, 0x05,
688
    0x32, 0x1E, 0x5F, 0x00, 0x19, 0x3A, 0x03, 0xFF,
689
    0x1E, 0xC0, 0x5F, 0x02, 0x05, 0xBE, 0x1E, 0x5F,
690
    0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58, 0x5F,
691
    0x02, 0x65, 0x00, 0x5F, 0x06, 0x05, 0xBE, 0x1E,
692
    0x5F, 0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58,
693
    0x5F, 0x02, 0x65, 0x00, 0x52, 0x08, 0x5D, 0x04,
694
    0x05, 0xBE, 0x1E, 0x5F, 0x00, 0x65, 0x02, 0x43,
695
    0x65, 0x00, 0x58, 0x5F, 0x02, 0x61, 0x04, 0x43,
696
    0x65, 0x00, 0x31, 0x5D, 0x04, 0x05, 0xBE, 0x1E,
697
    0x5F, 0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58,
698
    0x5F, 0x02, 0x65, 0x00, 0x5F, 0x03, 0xC0, 0x5F,
699
    0x01, 0x02, 0x7C, 0x1F, 0x05, 0xBE, 0x1E, 0x5F,
700
    0x00, 0x65, 0x00, 0x0F, 0x65, 0x02, 0x0E, 0x61,
701
    0x07, 0x0B, 0x58, 0x43, 0x09, 0x45, 0x65, 0x02,
702
    0x43, 0x65, 0x00, 0x58, 0x5F, 0x02, 0x65, 0x01,
703
    0xA1, 0x5F, 0x01, 0xB1, 0x65, 0x01, 0x43, 0x65,
704
    0x06, 0x3C, 0x03, 0x5C, 0x1F, 0x05, 0xBE, 0x1E,
705
    0x5F, 0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58,
706
    0x5F, 0x02, 0x65, 0x02, 0x04, 0x9A, 0x1F, 0x02,
707
    0xB8, 0x1F, 0xF9, 0x2E, 0x0F, 0x05, 0x3D, 0x1E,
708
    0x2B, 0x01, 0x65, 0x03, 0x17, 0x01, 0x04, 0xB5,
709
    0x1F, 0xF8, 0xE4, 0x1F, 0x0E, 0x05, 0x49, 0x1E,
710
    0x2B, 0x02, 0x61, 0x04, 0x06, 0x02, 0xFF, 0x1E,
711
    0xF8, 0xEE, 0x1F, 0x0E, 0x05, 0x49, 0x1E, 0x2B,
712
    0x02, 0x02, 0xF6, 0x1E, 0x2B, 0x07, 0x07, 0x0D,
713
    0x0A, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20,
714
    0x6E, 0x6F, 0x74, 0x20, 0x68, 0x65, 0x78, 0x0D,
715
    0x0A, 0x00, 0x0D, 0x0A, 0x4C, 0x4F, 0x41, 0x44,
716
    0x20, 0x3E, 0x20, 0x00, 0x0D, 0x0A, 0x44, 0x4F,
717
    0x4E, 0x45, 0x2E, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,
718
    0x43, 0x48, 0x45, 0x43, 0x4B, 0x53, 0x55, 0x4D,
719
    0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x2E, 0x00,
720
};
721
 
722
void load_image()
723
{
724
unsigned char * from = (unsigned char *)&loader;
725
unsigned char * to   = (unsigned char *)0x2000 - sizeof(loader);
726
int len              = sizeof(loader);
727
 
728
   printf("Loading image...\r\n");
729
   while (tx_sema.counter < sizeof(serial_out_buffer)) ;
730
   ASM(" DI");
731
   ASM(" MOVE #0x00, RR");            // disable ints
732
   ASM(" OUT  R, (OUT_INT_MASK)");    // disable int sources
733
   for (; len; --len)   *to++ = *from++;
734
   to;   ASM(" MOVE  RR, SP");
735
   ASM(" JMP  0x1EF0\t\t; &main");
736
}
737
//-----------------------------------------------------------------------------
738
void show_semas()
739
{
740
   printf("\r\nSemaphore           Count Waiting tasks\r\n");
741
   print_n('-', 79);   printf("\r\n");
742
   show_sema(&serial_out);
743
   show_sema(&rx_sema);
744
   show_sema(&tx_sema);
745
   show_sema(&t2_control);
746
   show_sema(&t3_control);
747
   print_n('=', 79);   printf("\r\n");
748
 
749
   if (serial_in_overflows)
750
      printf("\r\n\r\nSerial Overflows: %u\r\n\r\n", serial_in_overflows);
751
}
752
//-----------------------------------------------------------------------------
753
void show_tasks()
754
{
755
Task * t = &task_idle;
756
 
757
   printf("\r\nTask name        Prio Stack  Size  Used Next waiting     Status\r\n");
758
   print_n('-', 79);   printf("\r\n");
759
 
760
   do {
761
        printf("%-16s %4d  %4X %5d %5d ",
762
               t->name, t->priority, t->stack_pointer,
763
               t->stack_top - t->stack_bottom, stack_used(t));
764
        if (t->next_waiting_task)   printf("%-16s ", t->next_waiting_task);
765
        else                        printf("none.            ");
766
        if (t->status == 0)               printf("RUN ");
767
        if (t->status & TASK_SUSPENDED)   printf("SUSP ");
768
        if (t->status & TASK_SLEEPING)    printf("SLEEP %d ms ",
769
                                                 t->sleep_count);
770
        if (t->status & TASK_BLOCKED )    printf("BLKD on %s ",
771
                                                 t->waiting_for->name);
772
        printf("\r\n");
773
 
774
        t = t->next_task;
775
      } while (t != &task_idle);
776
 
777
   print_n('=', 79);   printf("\r\n");
778
}
779
//-----------------------------------------------------------------------------
780
 
781
void show_time()
782
{
783
unsigned int sl;
784
unsigned int sm;
785
unsigned int sh;
786
 
787
   do { seconds_changed = 0;
788
        sl = seconds_low;
789
        sm = seconds_mid;
790
        sh = seconds_high;
791
      } while (seconds_changed);
792
 
793
   printf("Uptime is %4.4X%4.4X%4.4X seconds\r\n", sh, sm, sl);
794
}
795
//-----------------------------------------------------------------------------
796
void display_memory(unsigned char * address)
797
{
798
char c;
799
int  row;
800
int  col;
801
 
802
   for (row = 0; row < 16; row++)
803
       {
804
         printf("%4.4X:", address);
805
         for (col = 0; col < 16; col++)   printf(" %2.2X", *address++);
806
         address -= 16;
807
         printf(" - ");
808
         for (col = 0; col < 16; col++)
809
             {
810
               c = *address++;
811
               if (c < ' ')         putchr('.');
812
               else if (c < 0x7F)   putchr(c);
813
               else                 putchr('.');
814
             }
815
         printf("\r\n");
816
       }
817
}
818
//-----------------------------------------------------------------------------
819
//
820
//   main() is the idle task. main() MUST NOT BLOCK, but could do
821
//   some non-blocking background jobs. It is safer, though, to do
822
//   nothing in main().
823
//
824
int main()
825
{
826
   ASM(" MOVE #0x05, RR");            // enable Rx and timer interrupts
827
   ASM(" OUT  R, (OUT_INT_MASK)");
828
   deschedule();
829
   init_unused();
830
   init_stack();
831
 
832
   for (;;)   ASM(" HALT");
833
}
834
//-----------------------------------------------------------------------------
835
int main_1(int argc, char * argv[])
836
{
837
int             c;
838
char            last_c;
839
unsigned char * address;
840
int             value;
841
 
842
   init_stack();
843
 
844
   for (;;)
845
      {
846
        P(&serial_out);
847
        printf("READY\r");
848
        V(&serial_out);
849
 
850
        last_c = c;
851
        c = getchr_timed(60000);
852
        if (c == -1)   // time out
853
           {
854
             P(&serial_out);
855
             printf("%s is bored.\r\n", current_task->name);
856
             V(&serial_out);
857
             continue;
858
           }
859
 
860
        P(&serial_out);
861
        switch(c)
862
           {
863
             case '\r':
864
             case '\n':
865
                  if (last_c == 'd')
866
                     {
867
                       address += 0x100;
868
                       putchr('\r');
869
                       display_memory(address);
870
                       c = 'd';
871
                     }
872
                  break;
873
 
874
             case '2':
875
                  V(&t2_control);
876
                  printf("Task 2 kicked\r\n");
877
                  break;
878
 
879
             case '3':
880
                  V(&t3_control);
881
                  sleep(100);
882
                  P(&t3_control);
883
                  printf("Task 3 enabled for 100 ms\r\n");
884
                  break;
885
 
886
             case 'b':
887
                  0;   ASM(" OUT  R, (OUT_START_CLK_CTR)");
888
                  deschedule();
889
                  ASM(" OUT  R, (OUT_STOP_CLK_CTR)");
890
                  value = (ASM(" IN   (IN_CLK_CTR_HIGH), RU") << 8)
891
                        |  ASM(" IN   (IN_CLK_CTR_LOW), RU");
892
                  printf("deschedule took %d CLKs = %d us\r\n",
893
                         value, (value + 10)/20);
894
                  break;
895
 
896
             case 'c':
897
                  show_time();
898
                  break;
899
 
900
             case 'd':
901
                  last_c = 'd';
902
                  printf("Display ");
903
                  address = (unsigned char *)gethex(1);
904
                  printf("\r\n");
905
                  getchr();
906
                  display_memory(address);
907
                  break;
908
 
909
             case 'e':
910
                  printf("LEDs ");
911
                  gethex(1);    ASM(" OUT R, (OUT_LEDS)");
912
                  printf("\r\n");
913
                  getchr();
914
                  break;
915
 
916
             case 'm':
917
                  printf("Memory ");
918
                  address = (unsigned char *)gethex(1);
919
                  printf(" Value ");
920
                  getchr();
921
                  *address = gethex(1);
922
                  getchr();
923
                  printf("\r\n");
924
                  break;
925
 
926
             case 's':
927
                  printf("DIP switch is 0x%X\r\n",
928
                         ASM(" IN (IN_DIP_SWITCH), RU"));
929
                  break;
930
 
931
             case 't':
932
                  printf("Temperature is %d degrees Celsius\r\n",
933
                         ASM(" IN (IN_TEMPERAT), RU"));
934
                  break;
935
 
936
             case 'H': printf("Halted.\r\n");
937
                       while (tx_sema.counter < sizeof(serial_out_buffer)) ;
938
                       ASM(" DI");
939
                       ASM(" HALT");
940
                  break;
941
 
942
             case 'I':
943
                  load_image();
944
                  break;
945
 
946
             case 'S':
947
                  show_semas();
948
                  break;
949
 
950
             case 'T':
951
                  show_tasks();
952
                  break;
953
 
954
             default:
955
                  printf("Help:  \r\n"
956
                         "2 - kick task 2\r\n"
957
                         "3 - kick task 3\r\n"
958
                         "I - load image\r\n"
959
                         "S - show semaphores\r\n"
960
                         "T - show tasks\r\n"
961
                         "b - measure task switch (deschedule)\r\n"
962
                         "c - show time\r\n"
963
                         "d - display memory\r\n"
964
                         "e - set LEDs\r\n"
965
                         "m - modify memory\r\n"
966
                         "s - read DIP switch\r\n"
967
                         "t - read temperature\r\n"
968
                         "H - HALT (forever)\r\n"
969
                         "\r\n");
970
           }
971
        V(&serial_out);
972
      }
973
}
974
//-----------------------------------------------------------------------------
975
void main_2()
976
{
977
unsigned int all_value;
978
unsigned int halt_value;
979
unsigned int all_total;
980
unsigned int halt_total;
981
int n;
982
int idle;
983
 
984
   init_stack();
985
 
986
   for (;;)
987
       {
988
         P(&t2_control);
989
 
990
         all_value  = 0;
991
         halt_value = 0;
992
         all_total  = 0;
993
         halt_total = 0;
994
 
995
         P(&serial_out);
996
         printf("Measuring...\r\n");
997
         V(&serial_out);
998
 
999
         V(&t3_control);
1000
         for (n = 0; n < 100; n++)
1001
             {
1002
               sleep(1);
1003
               0;   ASM(" OUT  R, (OUT_START_CLK_CTR)");
1004
               sleep(1);
1005
               ASM(" OUT  R, (OUT_STOP_CLK_CTR)");
1006
               all_value += (ASM(" IN   (IN_CLK_CTR_HIGH), RU") << 8)
1007
                     |  ASM(" IN   (IN_CLK_CTR_LOW), RU");
1008
 
1009
               all_total += all_value >> 8;
1010
               all_value &= 0x00FF;
1011
 
1012
               sleep(1);
1013
               3;   ASM(" OUT  R, (OUT_START_CLK_CTR)");
1014
               sleep(1);
1015
               ASM(" OUT  R, (OUT_STOP_CLK_CTR)");
1016
 
1017
               halt_value += (ASM(" IN   (IN_CLK_CTR_HIGH), RU") << 8)
1018
                     |  ASM(" IN   (IN_CLK_CTR_LOW), RU");
1019
 
1020
               halt_total += halt_value >> 8;
1021
               halt_value &= 0x00FF;
1022
             }
1023
         P(&t3_control);
1024
 
1025
         P(&serial_out);
1026
         printf("total:  %d cycles\r\n", all_total);
1027
         printf("halted: %d cycles\r\n", halt_total);
1028
         idle = (100*(halt_total>> 8)) / (all_total >> 8);
1029
         printf("idle:   %d %%\r\n", idle);
1030
         printf("load:   %d %%\r\n", 100 - idle);
1031
         V(&serial_out);
1032
       }
1033
}
1034
//-----------------------------------------------------------------------------
1035
void main_3()
1036
{
1037
char out;
1038
 
1039
   init_stack();
1040
 
1041
   for (;;)
1042
       {
1043
         P(&t3_control);
1044
         V(&t3_control);
1045
 
1046
         P(&serial_out);
1047
         for (out = '0'; out <= '9'; ++out)   putchr(out);
1048
         for (out = 'A'; out <= 'Z'; ++out)   putchr(out);
1049
         for (out = 'a'; out <= 'z'; ++out)   putchr(out);
1050
         putchr('\r');
1051
         putchr('\n');
1052
         V(&serial_out);
1053
       }
1054
}
1055
//-----------------------------------------------------------------------------
1056
//
1057
// task stacks
1058
//
1059
unsigned int stack_1[200], tos_1[3] = { 0, 0, (int)&main_1 }, top_1[0];
1060
unsigned int stack_2[200], tos_2[3] = { 0, 0, (int)&main_2 }, top_2[0];
1061
unsigned int stack_3[200], tos_3[3] = { 0, 0, (int)&main_3 }, top_3[0];
1062
 
1063
Task task_3 =    { &task_idle,         // next task
1064
                   tos_3,              // current stack pointer
1065
                   TASK_RUNNING,       // current state
1066
                   30 ,                // priority
1067
                   "Load Task ",       // task name
1068
                   (char *)&stack_3,   // bottom of stack
1069
                   (char *)&top_3 };   // top    of stack
1070
 
1071
Task task_2 =    { &task_3,            // next task
1072
                   tos_2,              // current stack pointer
1073
                   TASK_RUNNING,       // current state
1074
                   40 ,                // priority
1075
                   "Measurement",      // task name
1076
                   (char *)&stack_2,   // bottom of stack
1077
                   (char *)&top_2 };   // top    of stack
1078
 
1079
Task task_1 =    { &task_2,            // next task
1080
                   tos_1,              // current stack pointer
1081
                   TASK_RUNNING,       // current state
1082
                   50,                 // priority
1083
                   "Monitor",          // task name
1084
                   (char *)&stack_1,   // bottom of stack
1085
                   (char *)&top_1 };   // top    of stack
1086
 
1087
Task task_idle = { &task_1,        // next task
1088
                   0,              // current stack pointer (N/A since running)
1089
                   TASK_RUNNING,   // current state
1090
                   0,              // priority
1091
                   "Idle Task",    // task name
1092
                   (char *)0x9F80,         // bottom of stack
1093
                   (char *)0xA000 };       // top    of stack
1094
 
1095
Task * current_task = &task_idle;
1096
 
1097
//-----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.