kramann.info
© Guido Kramann

Login: Passwort:










EmbSyst
1 day_by_day
2 Eingebettete_Systeme
..2.1 Softwareentwicklung
....2.1.1 AgileSoftwareentwicklung
....2.1.2 Verhalten
....2.1.3 Entwurfsmuster
....2.1.4 FuzzyRegler
....2.1.5 Uebung
..2.2 Arduino
....2.2.1 Uebung1
..2.3 Android
....2.3.1 UML
......2.3.1.1 Volumenberechnung
......2.3.1.2 UML_Klassendiagramm
......2.3.1.3 Konstruktor
......2.3.1.4 Statische_Variable
....2.3.2 bluej
....2.3.3 Threads
....2.3.4 Interfacedesign
....2.3.5 Android
......2.3.5.1 Getting_Started
......2.3.5.2 App
......2.3.5.3 Beispielprojekt
........2.3.5.3.1 Richtlinien
........2.3.5.3.2 Anforderungen
........2.3.5.3.3 Layout
........2.3.5.3.4 Projekt_einrichten
........2.3.5.3.5 Refactoring
........2.3.5.3.6 Icon
........2.3.5.3.7 Icon2
........2.3.5.3.8 Kurzanleitung
........2.3.5.3.9 Architektur
........2.3.5.3.10 Anwendungsklasse
......2.3.5.4 Threads
......2.3.5.5 Activities
......2.3.5.6 Was_ist_wo
......2.3.5.7 Regelungssysteme
........2.3.5.7.1 Servo
........2.3.5.7.2 Fahrzeug
......2.3.5.8 ADB_Apps
......2.3.5.9 Veroeffentlichen
......2.3.5.10 Einzelheiten
........2.3.5.10.1 Bildschirmaufloesung
........2.3.5.10.2 Parameter
........2.3.5.10.3 Permission
........2.3.5.10.4 Latenzzeit
......2.3.5.11 Tonerkennung
........2.3.5.11.1 Wahrscheinlichkeitsrechnung
........2.3.5.11.2 Kovarianz_Scilab
........2.3.5.11.3 Java_Threads
........2.3.5.11.4 Java_Reflection
....2.3.6 Processing
......2.3.6.1 Installation
......2.3.6.2 Erste_Schritte
......2.3.6.3 Mechatronik
......2.3.6.4 Bibliotheken
......2.3.6.5 Uebung
......2.3.6.6 Snippets
........2.3.6.6.1 Dateioperationen
........2.3.6.6.2 Bilder
........2.3.6.6.3 GUI
........2.3.6.6.4 Text
........2.3.6.6.5 PDF
........2.3.6.6.8 Maus
........2.3.6.6.10 Zeit
........2.3.6.6.13 Animation
........2.3.6.6.15 Simulation
......2.3.6.7 Referenzen
....2.3.7 Android_Processing
......2.3.7.1 Basics
......2.3.7.2 Einrichten
......2.3.7.3 Crossplattform
......2.3.7.4 sinus
......2.3.7.5 sample
......2.3.7.6 analyse
......2.3.7.7 synthese
......2.3.7.8 Hilfsapps
......2.3.7.9 Eigene_Library
....2.3.8 Processing_VR
....2.3.9 Shapes3D
....2.3.10 TextToSpeech
....2.3.11 Internetprogrammierung
......2.3.11.1 Codegenerierung
......2.3.11.2 PHP_Programmierung
......2.3.11.3 PHP_OOP
......2.3.11.4 Java
......2.3.11.5 UDP
......2.3.11.6 Internetkontrolle
........2.3.11.6.1 Kamerabild
....2.3.12 OSC
......2.3.12.1 Datenaustausch
......2.3.12.2 i2audiolab
......2.3.12.3 Ardour
....2.3.13 Netzwerkprogrammierung
....2.3.14 JNI
....2.3.15 Erweitern
......2.3.15.1 sprich
......2.3.15.2 spiel
....2.3.16 thbvr
....2.3.17 Reflection
....2.3.18 Script
....2.3.19 Java3D
3 Echtzeitprogrammierung
..3.1 Echtzeit
..3.2 Korrektheit
..3.2 Semaphoren
..3.3 Hardware
..3.5 Synchronprogramm
..3.6 Zustandsmaschine
..3.7 Arduino
....3.7.1 Uebung
....3.7.2 RTOS
....3.7.3 Scheduler
....3.7.4 Semaphor
......3.7.4.1 Laufkatze
......3.7.4.2 Java
......3.7.4.3 Semaphor
....3.7.5 Messages
..3.8 Android
....3.8.2 Threads
......3.8.2.1 Java
......3.8.2.2 Synchronisierung
..3.9 Petrinetze
....3.9.1 Installation
....3.9.2 Test
4 KI
..4.1 Unueberwachtes_Lernen
..4.2 Agentensysteme
....4.2.1 Architekturen
......4.2.1.1 Verhalten
......4.2.1.2 Entwurfsmuster
....4.2.2 SUMO
......4.2.2.1 GettingStarted
......4.2.2.2 Antrieb
......4.2.2.3 Sensoren
......4.2.2.4 Zeitbasis
......4.2.2.5 Fernsteuerung
......4.2.2.6 Umsetzung_Fernst
......4.2.2.7 Fernsteuerung3
......4.2.2.10 Umsetzung
......4.2.2.11 Sockelsoftware
......4.2.2.12 Plan
......4.2.2.13 Lernen
........4.2.2.13.1 Parameter
........4.2.2.13.2 Identifikation
........4.2.2.13.3 Java
..4.3 Genetische_Algorithmen
....4.3.1 Heuristiken
....4.3.2 Genalgorithmus
..4.4 Kalmanfilter
....4.4.1 Vorarbeit
....4.4.2 Minimalversion
....4.4.3 Beispiel
5 Bildverarbeitung
..5.1 Gestalttheorie
..5.2 Bildverarbeitung
6 Technische_Systeme
..6.1 Kulturgeschichte
..6.2 Technikphilosophie
..6.3 Anthropozaen
7 Literatur
kramann.info
© Guido Kramann

Login: Passwort:




05.10.2011 - Einführende Veranstaltung zum Umgang mit RTOS (Real-Time Operating Systems) am Beispiel von Salvo

(EN google-translate)

(PL google-translate)

Theoretischer Teil: RTOS Grundlagen (vergl. Kapitel 2 Salvo-Manual)

Möglichkeiten Tasks zu verwalten und deren Vor- und Nachteile
Englischer Begriff Direkte Übersetzung Bedeutung
foreground / background (or superloop)-system Vordergrund / Hintergrund (oder auch Superschleife)-Systeme Abarbeitung der Tasks läuft durch Aufruf von Funktionen aus einer Main-Endlos-Schleife heraus.
Event driven Multitasking Ereignisbasierter Multiprogrammbetrieb Aufruf von Funktionen über Interrupts
RTOS with preemptive context switching RTOS mit bevorrechtigter Kontext-Umschaltung Unterbrechung von Tasks an beliebiger Stelle und Retten und Wiederherstellen aller vom Task verwendeten Register-Inhalte
RTOS with cooperative context switching RTOS mit kooperativer Kontext-Umschaltung Im Quelltext sind bei den einzelnen Task-Funktionen Stellen markiert, an denen der Scheduler Gelegenheit erhält, einen anderen Prozeß zu starten.

Tabelle 0-1: Systeme zur Verwaltung von Tasks.

Lexikon
Englischer Begriff Direkte Übersetzung (im Sinne von RTOS)
eligible wählbar
context switching (Register-)Kontext Umschaltung
Latency Latenzzeit (Dauer, bis z.B. eine Interrupt-Funktion nach Auftritt eines Events abgearbeitet wird)
maintain aufrechterhalten / unterhalten (z.B. einen Task in einem bestimmten Zustand)
provide bereitstellen
reliable betriebssicher / zuverlässig
scheduler Zeitplanungsprogramm
state machine Zustandsautomat
stack Kellerspeicher
system tick Kleinste Zykluszeit eines Maschinenbefehls auf einem System
voluntarily relinquish control freiwillig die Kontrolle preisgeben
yield (Betriebssystem-)Einschub
to yield (etwas) abgeben

Tabelle 0-2: Lexikon zentraler Begriffe im Zusammenhang mit RTOS

Verständnisfragen / Themen
  • Gründe, ein RTOS einzusetzen, statt superloop-systems.
  • Vor- und Nachteile von preemptive und cooperative context switching.
  • Ursachen für Latenzzeiten beim Start von Tasks.
  • RTOS-Typ von Salvo.

Praktischer Teil: Anwendung von Salvo als RTOS für einen ATmega32

Hinweise zum herausgegebenen Material
  • Pumpkin hat ein AVR-Studio-Beispiel-Projekt (Tut5) für einen ATmega16 herausgegeben.
  • Siehe in C:\Pumpkin\Salvo\Example\AVR\ATmega16\AVR_Studio\Tut.
  • 001_Anzeige_muecA, 002_Test_muecB, 003_RS232_test: gewöhnliche ATmega32-Projekte aus "Mikrocontrollertechnik"
  • fhb_rtos_002_vereinfacht: aus Tut5 abgeleitetes vereinfachtes Projekt mit einem Rechteckgenerator-Task und einem RS232-Task.
  • Dateien des Beispielprojektes:
  • tut5.c: Hauptprogramm (liegt unter /media/sda1/Pumpkin/Salvo/Example/AVR/AT90S8515/AVR_Studio/Tut/Tut5 !)
  • tut5_board.c: Konfigurationsdatei, in der beispielsweise auch die Taktrate des Schedulers eingestellt wird.
  • salvocfg.h: Konfigurationsfile gibt Auskunft über verfügbare Events (1 bei kostensloser Lite-Version) und Multitasks (3 bei kostenloser Lite-Version).
  • Auswahl des Devices über: Project->Configuration Options->Device
Übung

Vereinfachen Sie das Projekt Tut5 so, dass ein Rechtecksignal mit 500Hz auf PD7 ausgegeben wird (TaskBlink). Als weiterer Task soll eine Datenübertragung über RS232 laufen (TaskRS232): Ein mit jedem Schleifendurchlauf in TaskBlink inkrementierter unsigned-char-Wert "zaehler" soll über die serielle Verbindung an das Hyperterminal des PCs geschickt werden.

#include <salvo.h>

extern void board_init ( void );
extern void board_enable_interrupt ( void );

#define TASK_RS232_P             OSTCBP(1)   // task #1
#define TASK_BLINK_P             OSTCBP(2)   // task #2

#define PRIO_RS232               10          // niedrige Priorität
#define PRIO_BLINK               2           // hohe Priorität

//------------------------------------------
//Definition von Taktfrequenz und Bausrate als Konstanten
#define TAKTFREQUENZ 9216000
#define BAUDRATE 115200

volatile unsigned char zaehler;

void TaskRS232(void)
{
    unsigned char l,m,r;	//Variablen für Anzeige links, mitte, rechts
    unsigned char akku=0;

    DDRC = 255;


    //Merken des in UBRR zu speichernden Wertes.
    unsigned int baudregister = TAKTFREQUENZ/8/BAUDRATE-1;
	//setzen der Baudrate
	UBRRH = (unsigned char) (baudregister>>8); //Setzen des HIGH-Bytes des Baudraten-Registers
	UBRRL = (unsigned char)  baudregister;     //Setzen des LOW -Bytes des Baudraten-Registers	
	//Einschalten des Senders und des Empfängers
	UCSRB = (1<<TXEN) | (1<<RXEN);		        
	//Setzen des Nachrichtenformats: 8 Datenbits, 1 Stopbits
	UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
    UCSRA = (1<<U2X);

    while (1) 
	{
      OS_Yield();
        akku = zaehler;
      OS_Yield();
        l= akku / 100;			//links = Inhalt von akku dividiert mit 100 
      OS_Yield();
	    m= (akku % 100) / 10;	//mitte = Inhalt von akku modulo mit 100 , anschließend dividiert mit 10 
      OS_Yield();
	    r= akku % 10;			//rechts = Inhalt von akku modulo mit 10	
        
        //Die drei Ziffern der aktuellen Zahl werden in ASCII-Zeichen umgewandelt
        //und mit UDR = ... seriell gesendet.
        //Dann muß gewartet werden, bis das Senden beendet ist.
        //Es folgen ein Zeilenumbruch und ein Zurücksetzen des Cursers auf den 
        //Zeilenanfang:

        while( !(UCSRA & (1<<UDRE)) ) //Warten bis der Uebertragungspuffer leer ist
            OS_Yield();
        UDR = l+48;                    //Daten in den Puffer schreiben und übertragen
        while( !(UCSRA & (1<<UDRE)) )
            OS_Yield();
        UDR = m+48;
        while( !(UCSRA & (1<<UDRE)) )
            OS_Yield();
        UDR = r+48;
        while( !(UCSRA & (1<<UDRE)) )
            OS_Yield();
	    UDR = '\n';
        while( !(UCSRA & (1<<UDRE)) )
            OS_Yield();
	    UDR = '\r';

        //Zahl außerdem wie gewohnt nach Port C schicken:
        PORTC = akku;
    }
    // Context-switch, damit der andere Task laufen kann.
    OS_Yield();
}


void TaskBlink(void)
{
  //PD7 als Beeper benutzen:
  zaehler=0;
  DDRD   = 0b10000000; 
  PORTD  = 0b00000000; 

  while (1) 
  {
    // Toggle PORTC:0
    PORTD ^= 0b10000000; //EXOR      
    zaehler++;
    // Context-switch für 1 tick.
    OS_Delay(1);               
  }
}


int main (void)
{  
  board_init();
  OSInit();

  // Erzeuge Salvo tasks.
  OSCreateTask(TaskRS232, TASK_RS232_P,  PRIO_RS232 );
  OSCreateTask(TaskBlink, TASK_BLINK_P,  PRIO_BLINK );

  // Benötigt: Timer1 ISR ruft den OSTimer auf.
  board_enable_interrupt();

  // Endlosschleife für Scheduler.
  while (1) 
  {
      OSSched();
  }
}

Code 0-1: Hauptprogramm

...
void board_init ( void )
{
  TCCR1B =                           0x00;  // Stoppe Timer1
  TCNT1H =                           0x00;  // Lösche Timer1

//FHB_RTOS anpassen:
  OCR1AH =                           0x00;  // Setze Compare A auf 39
  OCR1AL =                           0x23;  //  ((9.216MHz/256)/36) = 1ms

//FHB_RTOS anpassen statt Vorteiler 1024, Vorteiler 64:
  TIMSK  =                    _BV(OCIE1A);  
  TCCR1B = _BV(WGM12)|_BV(CS12);  
}
...

Code 0-2: Änderungen in der Konfigurationsdatei