-         

Ergebnis 1 bis 1 von 1

Thema: ASURO Multitasking mit setjmp und alloca

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    09.05.2007
    Beiträge
    99

    ASURO Multitasking mit setjmp und alloca

    Anzeige

    Cooperatives Multitasking mit den Grundbausteinen:
    - alloca
    - setjmp/longjmp
    Compiler Version: WinAVR-20100110
    Asuro Lib: 2.80


    Ich finde die Lösung spannend und wollte sie hier mal vorstellen:

    Was macht der Code (Program: 2908 bytes (35.5% Full))?
    0 blink_Task: Die StatusLED blinkt im Sekunden Takt.
    1 avoid_Task: Wenn ASURO gegen ein Hindernis stößt fährt er zurück und dreht sich davon weg.
    2 cruise_Task: ASURO fährt herum (gerade aus). cruise_Task und avoid_Task kommunizieren über die Variable is_collision.

    3 background_Task: Mit der Restzeit werden rekursiv die Fibonacci Zahlen berechnet. Dies unerbittlich, solange der Stack reicht. Dann crasht das Programm (hier mal als Feature).

    Die Kooperation findet durch die Funktion wait(millis) statt. Mit ihrem Aufruf wird die Kontrolle an einen anderen Task weiter gegeben. Der current Task wird dadurch erst frühestens nach millis Millisekunden wieder aktiviert d.h. "sein" wait(..) kehrt zurück. Mit anderen Worten: Aus der Sicht eines Task verrichten alle anderen Tasks ihre Arbeit innerhalb seines wait(millis).

    Im Array tasks wird jeder Task mit seiner Startfunktion und seinem maximal zu erwartenden Stackbedarf eingetragen. (Achtung Feature: Für Task N-1 wird die Stackbedarfangabe ignoriert. Er verfügt damit über den kompletten verbleibenden Stackbereich des ASURO.) Die Priorität eines Tasks hängt von seiner Position in diesem Array ab. Task 0 hat die höchste Priorität.

    In der main Funktion wird jeder Task initialisiert und sein Stackbedarf reserviert. Dann wird Task 0 gestartet und das kooperative Spiel beginnt.
    Code:
    #include "asuro.h"
    #include <alloca.h>
    #include <setjmp.h>
    
    typedef struct {
     void (*task )() ;
     int stacksize;
     unsigned long awakeAt;
     jmp_buf env;
    } Task_t;
    
    const int slow=60, fast=80;
    int currentTask;
    
    extern void wait(int millis);
    
    void blink_Task() {
     int led=0;
     while(1) {
      led=1-led;
      StatusLED(led);
      wait(1000);
     }
    }
    
    #define SWITCH_NOISE 5
    int is_collision=0;
    
    void avoid_Task() {
    int count, old, sensor;
     while(1) {
      is_collision=0;
      for(count=0; ; count++) {
       sensor=PollSwitch();
       if (old!=sensor) count=0;
       old=sensor;
       if (count>=SWITCH_NOISE && sensor!=0) break;
       wait(10);
      }
      is_collision=1;
      //what do when robot hit a wall?
      SetMotorPower(-slow, -slow);
      wait(2000);
      if(sensor<16) SetMotorPower(-slow, 0); else SetMotorPower(0, -slow);
      wait(1000);
     }
    }
    
    void cruise_Task() {
     while(1) {
      if (is_collision==0) SetMotorPower(fast, fast);
      wait(100);
     }
    }
    
    long fib(int n) {
     long r;
     wait(0);
     if (n<2) return 1;
     r=fib(n-1)+fib(n-2);
     wait(0);
     return r;
    };
    
    void background_Task() {
     int i;
     for(i=0; ;i++) {
      PrintInt(i); SerPrint(" "); PrintLong(fib(i)); SerPrint("\r\n");
     }
    }
    
    Task_t tasks[] = {
     {&blink_Task, 100},
     {&avoid_Task, 100},
     {&cruise_Task, 100},
     {&background_Task},
    };
    
    #define TASKS (sizeof(tasks)/sizeof(Task_t))
    
    void wait(int millis) {
     tasks[currentTask].awakeAt=Gettime()+millis;
     if (setjmp(tasks[currentTask].env)==0) {
      for(currentTask=0; tasks[currentTask].awakeAt>Gettime(); ) {
       currentTask=(currentTask+1)%TASKS;
      }
      longjmp(tasks[currentTask].env, 1);
     }
    }
    
    int main(void) {
     int i;
     Init();
     for(i=0; i<TASKS; i++) {
      tasks[i].awakeAt=0;
      if (setjmp(tasks[i].env)) {
       (*tasks[currentTask].task)();
       while(1) wait(30000);
      }
      if (i<TASKS-1) alloca(tasks[i].stacksize);
     };
     currentTask=0;
     longjmp(tasks[currentTask].env, 1);
    }
    Andere Multitasking Varianten die hier (für den ASURO) vorgestellt wurden:
    - Statemachine
    - Subsumption
    - FreeRTOS
    Darüber hinaus habe ich gehört von:
    - Femto OS
    - NanoVM (JAVA)
    JAVA hat das Multithreading schon auf Sprachebene integrierten. (Das bietet C erst ab C++11.) Jetzt unterstützt NanoVM leider ausgerechnet Threads nicht. Eigentlich Schade!

    Geändert von rossir (06.01.2012 um 23:19 Uhr)

Ähnliche Themen

  1. multitasking für asuro?
    Von Matze 3 im Forum Asuro
    Antworten: 22
    Letzter Beitrag: 16.04.2009, 14:25
  2. Multitasking für den Asuro (II)
    Von Giwo im Forum Asuro
    Antworten: 8
    Letzter Beitrag: 27.12.2006, 09:23
  3. Multitasking
    Von Exodus im Forum AVR Hardwarethemen
    Antworten: 44
    Letzter Beitrag: 22.06.2006, 17:18
  4. Multitasking für den Asuro
    Von Giwo im Forum Asuro
    Antworten: 9
    Letzter Beitrag: 05.06.2005, 03:32
  5. Multitasking
    Von FancanTeik im Forum Software, Algorithmen und KI
    Antworten: 11
    Letzter Beitrag: 25.04.2005, 09:16

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •