- SF800 Solar Speicher Tutorial         
Ergebnis 1 bis 9 von 9

Thema: Multitasking für den Asuro (II)

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    31.05.2005
    Beiträge
    6
    So, ich hab mich in der letzten Woche mal wieder in die ganze Asuro-Materie eingearbeitet, und kleine Verbesserungen an der Multitasking-Bibliothek vorgenommen. Mit der AsuroLib 2.6.1 habe ich mich allerdings noch nicht richtig beschäftigt. Ich habe eben mal bei m_a_r_v_i_n angefragt, ob er Interesse an Multitasking in seiner AsuroLib hat.

    Aber hier ist erstmal ein weiteres Testprogramm, das mit der original Asuro-Bibliothek arbeitet. Es lässt den Asuro in Schlangenlinien fahren. Bei einer Kollision weicht er ein Stück zurück. Das ganze habe ich mit 4 Prozessen implementiert. Mehr steht in den Kommentaren am Anfang:
    Code:
    /***************************************************************************
    
    *                                                                         *
    
    *   This program is free software; you can redistribute it and/or modify  *
    
    *   it under the terms of the GNU General Public License as published by  *
    
    *   the Free Software Foundation; either version 2 of the License, or     *
    
    *   any later version.                                                    *
    
    ***************************************************************************/
    
    /**************************************************************************
    * Dieses Programm demonstriert, wie Multitasking zur Robottersteuerung    *
    * eingesetzt werden kann. Es kommen hier 4 Tasks zum einsatz:             *
    *                                                                         *
    * debugTask: Gibt Statusmeldungen ueber die IR-Schnittstelle aus.         *
    *                                                                         *
    * cruiseTask: Faehrt abwechselnd leichte Links- und Rechtskurven.         *
    *                                                                         *
    * avoidTask: Entzieht cruiseTask nach einer Kollision die Kontrolle, und  *
    *    faehrt ein Stueck nach hinten.                                       *
    *                                                                         *
    * MAIN_TASK (hauptprogramm): Koordiniert den Zugriff von cruiseTask und   *
    *    avoidTask auf die Motoren.                                           *
    *                                                                         *
    **************************************************************************/
    
    #include "asuro.h"
    #include "task.h"
    #include <string.h>
    
    // Einen String ausgeben
    void SerWriteString(char *outStr) {
    	SerWrite(outStr, strlen(outStr));
    }
    
    // Eine Zahl ausgeben
    void SerWriteInt(int outInt) {
    	char outStr[8];
    	itoa(outInt, outStr, 10);
    	SerWrite(outStr, strlen(outStr));
    }
    
    int cruiseLeft, cruiseRight;	// Motorgeschwindigkeit, gesetzt von cruiseTask
    
    int avoidLeft, avoidRight;		// Motorgeschwindigkeit, gesetzt von avoidTask
    
    int avoidControl;       		// Will avoidTask die Kontrolle ueber die 
    								// Motoren uebernehmen?
    
    int currentLeft, currentRight;	// Momentane Motorgeschwindigkeit
    
    char switches;					// Die gedrueckten Taster
    
    //Setzt die Motorgeschwindigkeit. Zulaessige Werte: -255..255 enspricht rueckwerts..vorwaerts
    void MyMotorSpeed(int left, int right) {
    	char left_dir = left >=0 ? FWD : RWD;
    	char right_dir = right >=0 ? FWD : RWD;
    	left = left < 0 ? -left : left;
    	right = right < 0 ? -right : right;
    	
    	MotorDir(left_dir, right_dir);
    	MotorSpeed(left, right);
    }
    
    //Faehrt abwechselnd leichte Links- und Rechtskurven.
    void cruiseTask(void) {
    	while (1) {
    		cruiseLeft=180;
    		cruiseRight=200;
    		Sleep(72UL*1000); // 1s links herum;
    		cruiseLeft=200;
    		cruiseRight=180;
    		Sleep(72UL*1000); // 1s rechts herum;
    	}
    }
    
    //Entzieht cruiseTask nach einer Kollision die Kontrolle, und faehrt ein Stueck nach hinten.
    void avoidTask(void) {
    	while(1) {
    		switches = PollSwitch();
    		if (switches!=0) {					// Ein Taster geddueckt?
    			avoidControl = 1;				// Ja: Kontrolle uebernehmen
    			if ((switches & 0x07) != 0) {	// Taster auf der rechten Seite gedrueckt?
    				avoidLeft = -150;			// Ja: nach hinten-links ausweichen
    				avoidRight = -100;
    			} else {
    				avoidLeft = -100;			// Sonst: nach hinten-rechts ausweichen
    				avoidRight = -150;
    			}
    			Sleep(72UL*1000);				// 1s nach hinten fahren
    			avoidControl = 0;				// Kontrolle wieder an cruiseTask abgeben
    		}
    		switchTask();
    	}
    }
    
    //Gibt Statusmeldungen ueber die IR-Schnittstelle aus.
    void debugTask(void) {
    	while(1) {
    		// Motorgeschwindigkeiten
    		SerWriteInt(currentLeft);
    		SerWriteString(" ");
    		SerWriteInt(currentRight);
    		SerWriteString(" ");
    		
    		// Kontrolle
    		SerWriteInt(avoidControl);
    		SerWriteString(" ");
    		
    		// Taster
    		SerWriteInt(switches);
    		SerWriteString(" ");
    		
    		// Wieviel ist noch auf den Stacks frei?
    		SerWriteInt(freeStackSize(1));
    		SerWriteString(" ");
    		SerWriteInt(freeStackSize(2));
    		SerWriteString(" ");
    		SerWriteInt(freeStackSize(3));
    		
    		SerWriteString("\r\n");
    		Sleep(75UL*100);
    	}
    }
    
    
    //Koordiniert den Zugriff von cruiseTask und avoidTask auf die Motoren.
    int main(void)
    
    {
    	Init();		/* Asuro initialisieren */
    	initTask();	/* Task initialisieren */
    	
    	cruiseLeft=0;
    	cruiseRight=0;
    	avoidLeft=0;
    	avoidRight=0;
    	avoidControl=0;
    	
    	// Tasks starten
    	// Die Stackgroessen wurden experimentell ermittelt. Das kann etwas muesehlig sein,
    	// denn: Stack zu klein -> absturtz
    	// und: Stack zu gruss -> absturtz
    	// Eine Hilfe bietet hier die Funktion freeStackSize, die ermittelt wieviel Platz
    	// noch auf einem Stack ist. (Siehe debugTask)
    	addTask(cruiseTask, 128);
    	addTask(avoidTask, 128);
    	addTask(debugTask, 330);
    	
    
    	while(1) {
    		if (avoidControl) {				// Will avoidTask die Kontrolle haben?
    			currentLeft=avoidLeft;		// Ja: avoidTask bekommt Kontrolle
    			currentRight=avoidRight;
    		} else {
    			currentLeft=cruiseLeft;		// sonst: cruiseTask bekommt Kontrolle
    			currentRight=cruiseRight;
    		}
    		MyMotorSpeed(currentLeft, currentRight);
    		switchTask();
    	}
    
    	return 0;
    
    }
    Das ganze funktioniert soweit. Allerdings hat sich herausgestellt, das 1kb Ram recht wenig ist. Die richtigen Stackgrößen für die einzelnen Tasks herauszufinden war etwas Fummelarbeit. Mehr als 4-5 Tasks werden wohl kaum möglich sein.

    Das ganze kann man hier runterladen: http://stud.fh-wedel.de/~ii4984/Task.cruise.zip
    Angehängte Dateien Angehängte Dateien

Berechtigungen

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

Labornetzteil AliExpress