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

Subversion Repositories c16

[/] [c16/] [trunk/] [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 24 jsauermann
        SGE     LL, RR                  ; RR = (next->priority >= t->priority)
90 2 jsauermann
        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 10 jsauermann
char peekchr()
568 2 jsauermann
{
569 10 jsauermann
char ret;
570
 
571 2 jsauermann
   P(&rx_sema);
572 10 jsauermann
   ret = serial_in_buffer[serial_in_get];
573 2 jsauermann
   V(&rx_sema);
574
 
575 10 jsauermann
   return ret;
576 2 jsauermann
}
577
//-----------------------------------------------------------------------------
578
char getnibble(char echo)
579
{
580
char c  = peekchr();
581
int ret = -1;
582
 
583
   if      ((c >= '0') && (c <= '9'))   ret = c - '0';
584
   else if ((c >= 'A') && (c <= 'F'))   ret = c - 0x37;
585
   else if ((c >= 'a') && (c <= 'f'))   ret = c - 0x57;
586
 
587
   if (ret != -1)   // valid hex char
588
      {
589
        getchr();
590
        if (echo)   putchr(c);
591
      }
592
   return ret;
593
}
594
//-----------------------------------------------------------------------------
595
int gethex(char echo)
596
{
597
int  ret = 0;
598
char c;
599
 
600
   while ((c = getnibble(echo)) != -1)   ret = (ret << 4) | c;
601
   return ret;
602
}
603
/*******************************************************************************
604
********************************************************************************
605
**                                                                            **
606
**                     main and its helpers                                   **
607
**                                                                            **
608
********************************************************************************
609
*******************************************************************************/
610
 
611
//-----------------------------------------------------------------------------
612
void init_stack()
613
{
614
char * bottom = current_task->stack_bottom;
615
 
616
   while (bottom < (char *)ASM(" LEA 0(SP), RR"))   *bottom++ = 'S';
617
}
618
//-----------------------------------------------------------------------------
619
 
620
extern char * end_text;
621
 
622 16 jsauermann
void init_unused()   // must ONLY be called by idle task
623 2 jsauermann
{
624
char * cp = current_task->stack_bottom;
625
 
626
   while (--cp >= (char *)&end_text)   *cp = ' ';
627
}
628
//-----------------------------------------------------------------------------
629
int stack_used(Task * t)
630
{
631
char * bottom = t->stack_bottom;
632
 
633
   while (*bottom == 'S')   bottom++;
634
   return t->stack_top - bottom;
635
}
636
//-----------------------------------------------------------------------------
637
void show_sema(Semaphore * s)
638
{
639
Task * t;
640
 
641
   printf("%-20s %4d ", s->name, s->counter);
642
   if (s->counter < 0)
643
      {
644
        for (t = s->next_waiting; t; t = t->next_waiting_task)
645
            {
646
              printf("%s -> ", t->name);
647
              if (t == s->last_waiting)   printf("0");
648
            }
649
      }
650
   else
651
      {
652
        printf("none.");
653
      }
654
   printf("\r\n");
655
}
656
//-----------------------------------------------------------------------------
657
 
658
unsigned char loader[] =
659
{
660
//  0xF8, 0x18, 0x00, 0x4F, 0xFC, 0x00, 0xA0, 0x08, 
661
//  0x6E, 0x0E, 0x24, 0x1A, 0x00, 0x03, 0x07, 0x00, 
662
//  0xF8, 0x32, 0x9E, 0x4F, 0x05, 0xF0, 0x9E, 0x00, 
663
//  0xE8, 0x01,
664
 
665
                0x2E, 0x01, 0x11, 0x01, 0x3D, 0x03,
666
    0x32, 0x1E, 0x2E, 0x00, 0x07, 0x2E, 0x01, 0x11,
667
    0x02, 0x03, 0x3D, 0x1E, 0x65, 0x02, 0x2F, 0x00,
668
    0x07, 0x02, 0x59, 0x1E, 0x61, 0x02, 0xA1, 0x5D,
669
    0x02, 0xB1, 0x47, 0x0F, 0x05, 0x3D, 0x1E, 0x2B,
670
    0x01, 0x61, 0x02, 0x47, 0x03, 0x4C, 0x1E, 0x07,
671
    0x05, 0x32, 0x1E, 0x0F, 0x65, 0x00, 0x29, 0x30,
672
    0x04, 0x71, 0x1E, 0xF8, 0xFF, 0x00, 0x02, 0xBB,
673
    0x1E, 0x65, 0x00, 0x27, 0x39, 0x04, 0x7F, 0x1E,
674
    0x65, 0x00, 0xF7, 0x30, 0x02, 0xBB, 0x1E, 0x65,
675
    0x00, 0x29, 0x41, 0x04, 0x8C, 0x1E, 0xF8, 0xFF,
676
    0x00, 0x02, 0xBB, 0x1E, 0x65, 0x00, 0x27, 0x46,
677
    0x04, 0x9A, 0x1E, 0x65, 0x00, 0xF7, 0x37, 0x02,
678
    0xBB, 0x1E, 0x65, 0x00, 0x29, 0x61, 0x04, 0xA7,
679
    0x1E, 0xF8, 0xFF, 0x00, 0x02, 0xBB, 0x1E, 0x65,
680
    0x00, 0x27, 0x66, 0x04, 0xB5, 0x1E, 0x65, 0x00,
681
    0xF7, 0x57, 0x02, 0xBB, 0x1E, 0xF8, 0xFF, 0x00,
682
    0x02, 0xBB, 0x1E, 0x2B, 0x01, 0x07, 0x05, 0x60,
683
    0x1E, 0x0F, 0x2D, 0x65, 0x01, 0x18, 0xFF, 0x00,
684
    0x04, 0xE3, 0x1E, 0x05, 0x60, 0x1E, 0x5F, 0x00,
685
    0x65, 0x00, 0x18, 0xFF, 0x00, 0x04, 0xE3, 0x1E,
686
    0x65, 0x01, 0x52, 0x04, 0x43, 0x65, 0x00, 0x31,
687
    0x02, 0xED, 0x1E, 0xF8, 0xC7, 0x1F, 0x0E, 0x05,
688
    0x49, 0x1E, 0x2B, 0x02, 0x00, 0x2B, 0x02, 0x07,
689
    0x2D, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, 0xF8, 0xDA,
690
    0x1F, 0x0E, 0x05, 0x49, 0x1E, 0x2B, 0x02, 0x05,
691
    0x32, 0x1E, 0x5F, 0x00, 0x19, 0x3A, 0x03, 0xFF,
692
    0x1E, 0xC0, 0x5F, 0x02, 0x05, 0xBE, 0x1E, 0x5F,
693
    0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58, 0x5F,
694
    0x02, 0x65, 0x00, 0x5F, 0x06, 0x05, 0xBE, 0x1E,
695
    0x5F, 0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58,
696
    0x5F, 0x02, 0x65, 0x00, 0x52, 0x08, 0x5D, 0x04,
697
    0x05, 0xBE, 0x1E, 0x5F, 0x00, 0x65, 0x02, 0x43,
698
    0x65, 0x00, 0x58, 0x5F, 0x02, 0x61, 0x04, 0x43,
699
    0x65, 0x00, 0x31, 0x5D, 0x04, 0x05, 0xBE, 0x1E,
700
    0x5F, 0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58,
701
    0x5F, 0x02, 0x65, 0x00, 0x5F, 0x03, 0xC0, 0x5F,
702
    0x01, 0x02, 0x7C, 0x1F, 0x05, 0xBE, 0x1E, 0x5F,
703
    0x00, 0x65, 0x00, 0x0F, 0x65, 0x02, 0x0E, 0x61,
704
    0x07, 0x0B, 0x58, 0x43, 0x09, 0x45, 0x65, 0x02,
705
    0x43, 0x65, 0x00, 0x58, 0x5F, 0x02, 0x65, 0x01,
706
    0xA1, 0x5F, 0x01, 0xB1, 0x65, 0x01, 0x43, 0x65,
707
    0x06, 0x3C, 0x03, 0x5C, 0x1F, 0x05, 0xBE, 0x1E,
708
    0x5F, 0x00, 0x65, 0x02, 0x43, 0x65, 0x00, 0x58,
709
    0x5F, 0x02, 0x65, 0x02, 0x04, 0x9A, 0x1F, 0x02,
710
    0xB8, 0x1F, 0xF9, 0x2E, 0x0F, 0x05, 0x3D, 0x1E,
711
    0x2B, 0x01, 0x65, 0x03, 0x17, 0x01, 0x04, 0xB5,
712
    0x1F, 0xF8, 0xE4, 0x1F, 0x0E, 0x05, 0x49, 0x1E,
713
    0x2B, 0x02, 0x61, 0x04, 0x06, 0x02, 0xFF, 0x1E,
714
    0xF8, 0xEE, 0x1F, 0x0E, 0x05, 0x49, 0x1E, 0x2B,
715
    0x02, 0x02, 0xF6, 0x1E, 0x2B, 0x07, 0x07, 0x0D,
716
    0x0A, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20,
717
    0x6E, 0x6F, 0x74, 0x20, 0x68, 0x65, 0x78, 0x0D,
718
    0x0A, 0x00, 0x0D, 0x0A, 0x4C, 0x4F, 0x41, 0x44,
719
    0x20, 0x3E, 0x20, 0x00, 0x0D, 0x0A, 0x44, 0x4F,
720
    0x4E, 0x45, 0x2E, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,
721
    0x43, 0x48, 0x45, 0x43, 0x4B, 0x53, 0x55, 0x4D,
722
    0x20, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x2E, 0x00,
723
};
724
 
725
void load_image()
726
{
727
unsigned char * from = (unsigned char *)&loader;
728
unsigned char * to   = (unsigned char *)0x2000 - sizeof(loader);
729
int len              = sizeof(loader);
730
 
731
   printf("Loading image...\r\n");
732
   while (tx_sema.counter < sizeof(serial_out_buffer)) ;
733
   ASM(" DI");
734
   ASM(" MOVE #0x00, RR");            // disable ints
735
   ASM(" OUT  R, (OUT_INT_MASK)");    // disable int sources
736
   for (; len; --len)   *to++ = *from++;
737
   to;   ASM(" MOVE  RR, SP");
738
   ASM(" JMP  0x1EF0\t\t; &main");
739
}
740
//-----------------------------------------------------------------------------
741
void show_semas()
742
{
743
   printf("\r\nSemaphore           Count Waiting tasks\r\n");
744
   print_n('-', 79);   printf("\r\n");
745
   show_sema(&serial_out);
746
   show_sema(&rx_sema);
747
   show_sema(&tx_sema);
748
   show_sema(&t2_control);
749
   show_sema(&t3_control);
750
   print_n('=', 79);   printf("\r\n");
751
 
752
   if (serial_in_overflows)
753
      printf("\r\n\r\nSerial Overflows: %u\r\n\r\n", serial_in_overflows);
754
}
755
//-----------------------------------------------------------------------------
756
void show_tasks()
757
{
758
Task * t = &task_idle;
759
 
760 10 jsauermann
   printf("\r\nTask name        Prio   PC Stack  Size  Used "
761
          "Next waiting     Status\r\n");
762 2 jsauermann
   print_n('-', 79);   printf("\r\n");
763
 
764
   do {
765 10 jsauermann
        printf("%-16s %4d  %4X %4X %5d %5d ",
766
               t->name, t->priority, t->stack_pointer[2], t->stack_pointer,
767 2 jsauermann
               t->stack_top - t->stack_bottom, stack_used(t));
768
        if (t->next_waiting_task)   printf("%-16s ", t->next_waiting_task);
769
        else                        printf("none.            ");
770
        if (t->status == 0)               printf("RUN ");
771
        if (t->status & TASK_SUSPENDED)   printf("SUSP ");
772
        if (t->status & TASK_SLEEPING)    printf("SLEEP %d ms ",
773
                                                 t->sleep_count);
774
        if (t->status & TASK_BLOCKED )    printf("BLKD on %s ",
775
                                                 t->waiting_for->name);
776
        printf("\r\n");
777
 
778
        t = t->next_task;
779
      } while (t != &task_idle);
780
 
781
   print_n('=', 79);   printf("\r\n");
782
}
783
//-----------------------------------------------------------------------------
784
 
785
void show_time()
786
{
787
unsigned int sl;
788
unsigned int sm;
789
unsigned int sh;
790
 
791
   do { seconds_changed = 0;
792
        sl = seconds_low;
793
        sm = seconds_mid;
794
        sh = seconds_high;
795
      } while (seconds_changed);
796
 
797
   printf("Uptime is %4.4X%4.4X%4.4X seconds\r\n", sh, sm, sl);
798
}
799
//-----------------------------------------------------------------------------
800
void display_memory(unsigned char * address)
801
{
802
char c;
803
int  row;
804
int  col;
805
 
806
   for (row = 0; row < 16; row++)
807
       {
808
         printf("%4.4X:", address);
809
         for (col = 0; col < 16; col++)   printf(" %2.2X", *address++);
810
         address -= 16;
811
         printf(" - ");
812
         for (col = 0; col < 16; col++)
813
             {
814
               c = *address++;
815
               if (c < ' ')         putchr('.');
816
               else if (c < 0x7F)   putchr(c);
817
               else                 putchr('.');
818
             }
819
         printf("\r\n");
820
       }
821
}
822
//-----------------------------------------------------------------------------
823
//
824
//   main() is the idle task. main() MUST NOT BLOCK, but could do
825
//   some non-blocking background jobs. It is safer, though, to do
826 10 jsauermann
//   nothing in main()'s for() loop.
827 2 jsauermann
//
828
int main()
829
{
830 16 jsauermann
int i;
831
 
832
   init_unused();
833
   init_stack();
834
 
835
   ASM(" MOVE #0x00, RR");            // disable all interrupt sources
836
   ASM(" OUT  R, (OUT_INT_MASK)");
837
 
838
   // we dont know the value of the interrupt disable counter,
839
   // so we force it to zero (i.e. interrupts enabled)
840
   //
841
   for (i = 0; i < 16; ++i)   ASM(" EI");   // decrement int disable counter
842
 
843 2 jsauermann
   ASM(" MOVE #0x05, RR");            // enable Rx and timer interrupts
844
   ASM(" OUT  R, (OUT_INT_MASK)");
845 16 jsauermann
 
846 2 jsauermann
   deschedule();
847
 
848
   for (;;)   ASM(" HALT");
849
}
850
//-----------------------------------------------------------------------------
851
int main_1(int argc, char * argv[])
852
{
853
int             c;
854
char            last_c;
855
unsigned char * address;
856
int             value;
857
 
858 16 jsauermann
   ASM(" EI");
859
 
860 2 jsauermann
   init_stack();
861
 
862
   for (;;)
863
      {
864
        P(&serial_out);
865
        printf("READY\r");
866
        V(&serial_out);
867
 
868
        last_c = c;
869
        c = getchr_timed(60000);
870
        if (c == -1)   // time out
871
           {
872
             P(&serial_out);
873
             printf("%s is bored.\r\n", current_task->name);
874
             V(&serial_out);
875
             continue;
876
           }
877
 
878
        P(&serial_out);
879
        switch(c)
880
           {
881
             case '\r':
882
             case '\n':
883
                  if (last_c == 'd')
884
                     {
885
                       address += 0x100;
886
                       putchr('\r');
887
                       display_memory(address);
888
                       c = 'd';
889
                     }
890
                  break;
891
 
892
             case '2':
893
                  V(&t2_control);
894
                  printf("Task 2 kicked\r\n");
895
                  break;
896
 
897
             case '3':
898
                  V(&t3_control);
899
                  sleep(100);
900
                  P(&t3_control);
901
                  printf("Task 3 enabled for 100 ms\r\n");
902
                  break;
903
 
904
             case 'b':
905
                  0;   ASM(" OUT  R, (OUT_START_CLK_CTR)");
906
                  deschedule();
907
                  ASM(" OUT  R, (OUT_STOP_CLK_CTR)");
908
                  value = (ASM(" IN   (IN_CLK_CTR_HIGH), RU") << 8)
909
                        |  ASM(" IN   (IN_CLK_CTR_LOW), RU");
910
                  printf("deschedule took %d CLKs = %d us\r\n",
911
                         value, (value + 10)/20);
912
                  break;
913
 
914
             case 'c':
915
                  show_time();
916
                  break;
917
 
918
             case 'd':
919
                  last_c = 'd';
920
                  printf("Display ");
921
                  address = (unsigned char *)gethex(1);
922
                  printf("\r\n");
923
                  getchr();
924
                  display_memory(address);
925
                  break;
926
 
927
             case 'e':
928
                  printf("LEDs ");
929
                  gethex(1);    ASM(" OUT R, (OUT_LEDS)");
930
                  printf("\r\n");
931
                  getchr();
932
                  break;
933
 
934
             case 'm':
935
                  printf("Memory ");
936
                  address = (unsigned char *)gethex(1);
937
                  printf(" Value ");
938
                  getchr();
939
                  *address = gethex(1);
940
                  getchr();
941
                  printf("\r\n");
942
                  break;
943
 
944
             case 's':
945
                  printf("DIP switch is 0x%X\r\n",
946
                         ASM(" IN (IN_DIP_SWITCH), RU"));
947
                  break;
948
 
949
             case 't':
950
                  printf("Temperature is %d degrees Celsius\r\n",
951
                         ASM(" IN (IN_TEMPERAT), RU"));
952
                  break;
953
 
954
             case 'H': printf("Halted.\r\n");
955
                       while (tx_sema.counter < sizeof(serial_out_buffer)) ;
956
                       ASM(" DI");
957
                       ASM(" HALT");
958
                  break;
959
 
960
             case 'I':
961
                  load_image();
962
                  break;
963
 
964
             case 'S':
965
                  show_semas();
966
                  break;
967
 
968
             case 'T':
969
                  show_tasks();
970
                  break;
971
 
972
             default:
973
                  printf("Help:  \r\n"
974
                         "2 - kick task 2\r\n"
975
                         "3 - kick task 3\r\n"
976
                         "I - load image\r\n"
977
                         "S - show semaphores\r\n"
978
                         "T - show tasks\r\n"
979
                         "b - measure task switch (deschedule)\r\n"
980
                         "c - show time\r\n"
981
                         "d - display memory\r\n"
982
                         "e - set LEDs\r\n"
983
                         "m - modify memory\r\n"
984
                         "s - read DIP switch\r\n"
985
                         "t - read temperature\r\n"
986
                         "H - HALT (forever)\r\n"
987
                         "\r\n");
988
           }
989
        V(&serial_out);
990
      }
991
}
992
//-----------------------------------------------------------------------------
993
void main_2()
994
{
995
unsigned int all_value;
996
unsigned int halt_value;
997
unsigned int all_total;
998
unsigned int halt_total;
999
int n;
1000
int idle;
1001
 
1002 16 jsauermann
   ASM(" EI");
1003
 
1004 2 jsauermann
   init_stack();
1005
 
1006
   for (;;)
1007
       {
1008
         P(&t2_control);
1009
 
1010
         all_value  = 0;
1011
         halt_value = 0;
1012
         all_total  = 0;
1013
         halt_total = 0;
1014
 
1015
         P(&serial_out);
1016
         printf("Measuring...\r\n");
1017
         V(&serial_out);
1018
 
1019
         V(&t3_control);
1020
         for (n = 0; n < 100; n++)
1021
             {
1022
               sleep(1);
1023
               0;   ASM(" OUT  R, (OUT_START_CLK_CTR)");
1024
               sleep(1);
1025
               ASM(" OUT  R, (OUT_STOP_CLK_CTR)");
1026
               all_value += (ASM(" IN   (IN_CLK_CTR_HIGH), RU") << 8)
1027
                     |  ASM(" IN   (IN_CLK_CTR_LOW), RU");
1028
 
1029
               all_total += all_value >> 8;
1030
               all_value &= 0x00FF;
1031
 
1032
               sleep(1);
1033
               3;   ASM(" OUT  R, (OUT_START_CLK_CTR)");
1034
               sleep(1);
1035
               ASM(" OUT  R, (OUT_STOP_CLK_CTR)");
1036
 
1037
               halt_value += (ASM(" IN   (IN_CLK_CTR_HIGH), RU") << 8)
1038
                     |  ASM(" IN   (IN_CLK_CTR_LOW), RU");
1039
 
1040
               halt_total += halt_value >> 8;
1041
               halt_value &= 0x00FF;
1042
             }
1043
         P(&t3_control);
1044
 
1045
         P(&serial_out);
1046
         printf("total:  %d cycles\r\n", all_total);
1047
         printf("halted: %d cycles\r\n", halt_total);
1048
         idle = (100*(halt_total>> 8)) / (all_total >> 8);
1049
         printf("idle:   %d %%\r\n", idle);
1050
         printf("load:   %d %%\r\n", 100 - idle);
1051
         V(&serial_out);
1052
       }
1053
}
1054
//-----------------------------------------------------------------------------
1055
void main_3()
1056
{
1057
char out;
1058
 
1059 16 jsauermann
   ASM(" EI");
1060
 
1061 2 jsauermann
   init_stack();
1062
 
1063
   for (;;)
1064
       {
1065
         P(&t3_control);
1066
         V(&t3_control);
1067
 
1068
         P(&serial_out);
1069
         for (out = '0'; out <= '9'; ++out)   putchr(out);
1070
         for (out = 'A'; out <= 'Z'; ++out)   putchr(out);
1071
         for (out = 'a'; out <= 'z'; ++out)   putchr(out);
1072
         putchr('\r');
1073
         putchr('\n');
1074
         V(&serial_out);
1075
       }
1076
}
1077
//-----------------------------------------------------------------------------
1078
//
1079
// task stacks
1080
//
1081
unsigned int stack_1[200], tos_1[3] = { 0, 0, (int)&main_1 }, top_1[0];
1082
unsigned int stack_2[200], tos_2[3] = { 0, 0, (int)&main_2 }, top_2[0];
1083
unsigned int stack_3[200], tos_3[3] = { 0, 0, (int)&main_3 }, top_3[0];
1084
 
1085
Task task_3 =    { &task_idle,         // next task
1086
                   tos_3,              // current stack pointer
1087
                   TASK_RUNNING,       // current state
1088
                   30 ,                // priority
1089
                   "Load Task ",       // task name
1090
                   (char *)&stack_3,   // bottom of stack
1091
                   (char *)&top_3 };   // top    of stack
1092
 
1093
Task task_2 =    { &task_3,            // next task
1094
                   tos_2,              // current stack pointer
1095
                   TASK_RUNNING,       // current state
1096
                   40 ,                // priority
1097
                   "Measurement",      // task name
1098
                   (char *)&stack_2,   // bottom of stack
1099
                   (char *)&top_2 };   // top    of stack
1100
 
1101
Task task_1 =    { &task_2,            // next task
1102
                   tos_1,              // current stack pointer
1103
                   TASK_RUNNING,       // current state
1104
                   50,                 // priority
1105
                   "Monitor",          // task name
1106
                   (char *)&stack_1,   // bottom of stack
1107
                   (char *)&top_1 };   // top    of stack
1108
 
1109
Task task_idle = { &task_1,        // next task
1110
                   0,              // current stack pointer (N/A since running)
1111
                   TASK_RUNNING,   // current state
1112
                   0,              // priority
1113
                   "Idle Task",    // task name
1114 10 jsauermann
                   (char *)0x1F80,         // bottom of stack
1115
                   (char *)0x2000 };       // top    of stack
1116 2 jsauermann
 
1117
Task * current_task = &task_idle;
1118
 
1119
//-----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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