Prozesssteuerung & RobotikReal Time .NET
Sebastian Klose
7. Januar 2009
Gliederung
■ Überblick über .NET
■ Analyse der Echtzeittauglichkeit
□ Geschwindigkeit
□ Speicherverwaltung
□ Hardwarezugriff
□ Timing
■ Echtzeit mit dem Compact/Micro Framework
■ RT.NET
□ Geschwindigkeit
□ Speicherverwaltung
□ Hardwarezugriff
□ Timing
□ EvaluationReal Time .NET | Sebastian Klose | 7. Januar 2009
2
Überblick über .NET
Real Time .NET | Sebastian Klose | 7. Januar 2009
3
Überblick über .NET
DesktopFramework
Compact Framework
MicroFramework
Mono
Plattform Windows Desktop + Server
Windows Mobile/CE, Xbox
32 Bit CPUs (auch ohne MMU)
Windows,Linux, Mac OS X, BSD, Solaris, iPhone, Wii
Version 3.5 SP1 3.5 3.0 2.0.1
Größe 250MB 7MB 200KB 70MB
Ausführung JIT JIT Interpreter JIT
GC compacting, generational Mark & Sweep
compacting, generational Mark & Sweep
Mark & Sweep
compacting, generational Mark & Sweep
Real Time .NET | Sebastian Klose | 7. Januar 2009
4
.NET Micro Framework
Real Time .NET | Sebastian Klose | 7. Januar 2009
5
.NET Micro Framework
Real Time .NET | Sebastian Klose | 7. Januar 2009
6
Analyse der Echtzeittauglichkeit
Real Time .NET | Sebastian Klose | 7. Januar 2009
7
Echtzeittauglichkeit - Geschwindigkeit
■ Untersucht von Chris Tacke auf Basis vom CF 2.0
■ Veröffentlicht im MSDN Magazine 2006
Real Time .NET | Sebastian Klose | 7. Januar 2009
8
Echtzeittauglichkeit - Geschwindigkeit
ee
Real Time .NET | Sebastian Klose | 7. Januar 2009
#define GPIO3 (1 << 3)...DWORD *p = MapAddress(0x40E00000);
DWORD *gpdr = p + (0x10 /sizeof(DWORD));
DWORD *gpsr = p + (0x18 /sizeof(DWORD));
DWORD *gpcr = p + (0x24 /sizeof(DWORD));
*gpdr |= GPIO3;while(true){*gpsr = GPIO3;*gpcr = GPIO3;
}
int gpio3 = (1 << 3);
PhysicalAddressPointer pap;pap = newPhysicalAddressPointer(0x40E00000, 0x6B);
// make an GPIO outputint gpdr = pap.ReadInt32(0x10);pap.WriteInt32(gpdr | gpio3);
while(true){// turn it offpap.WriteInt32(gpio3, 0x24);// turn it onpap.WriteInt32(gpio3, 0x18);
}
// toggle GPIO 3int gpio3 = (1 << 3);
// map all of GPIO spacePhysicalAddressPointer pap;pap = newPhysicalAddressPointer(0x40E00000, 0x6B);
unsafe{int *p =(int*)pap.GetUnsafePointer();int *gpsr = p + (0x18 / 4);int *gpcr = p + (0x24 / 4);int *gpdr = p + (0x10 / 4);while(true){
// set the pin*gpsr = gpio3;*gpcr = gpio3;
}}
Periodenlänge: 110nsPeriodenlänge: 740ns
Periodenlänge: 110ns
C C# C#9
Micro Framework: „Performance remains an area of
ongoing research”
Echtzeittauglichkeit - Geschwindigkeit
■ Michael H. Lutz von Siemens Health Services
■ Messungen auf Basis von .NET 1.0
Real Time .NET | Sebastian Klose | 7. Januar 2009
10
Echtzeittauglichkeit -Speicherverwaltung
■ Alle Frameworks verwenden Mark & Sweep Algorithmus
□ Dauer eines Durchlaufs abhängig von
◊ Anzahl der Objekte im Gesamtsystem
◊ Anzahl der Generationen
◊ Defragmentierung des Arbeitsspeichers
□ GC wird aktiv, wenn
◊ Objekte der Größe von 1MB allokiert wurden (CF)
◊ Größe von Gen0 einen Schwellenwert überschreitet (Desktop)
◊ Die Anwendung in den Hintergrund verschoben wird
◊ Ein Fehler beim allokieren von Speicher auftrat
◊ GC.Collect() explizit aufgerufen wird
Real Time .NET | Sebastian Klose | 7. Januar 2009
11
Echtzeittauglichkeit - Hardwarezugriff
■ Desktop & Compact Framework
□ Komponente für Zugriff auf seriellen Port
□ keine weiteren Mechanismen vorgesehen
□ P/Invoke unter Windows CE
◊ Abbildung von physikalischen auf virtuelle Adressen
● VirtualAlloc
● VirtualCopy
■ Micro Framework
□ Konzept von „Managed Drivers“ für
◊ GPIO, PWM/VTU, I2C, SPI, USB 1.1, or USART
□ herstellerspezifische APIs für andere Hardware
Real Time .NET | Sebastian Klose | 7. Januar 2009
12
Hardwarezugriff Micro Framework
Real Time .NET | Sebastian Klose | 7. Januar 2009
using System;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;
public class Program{
public static void Main(){
InterruptPort port = new InterruptPort(Cpu.Pin.GPIO_Pin3, false, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
port.OnInterrupt += new GPIOInterruptEventHandler(port_OnInterrupt);Thread.Sleep(Timeout.Infinite);
}
private static void port_OnInterrupt(Cpu.Pin port, bool state, TimeSpan time){
Debug.Print("Pin=" + port + " State=" + state + " Time=" + time);}
}
13
Echtzeittauglichkeit - Timing
■ System.Windows.Forms.Timer
□ basiert auf Win32 Timer
□ minimale Intervalllänge 50ms
■ System.Timers.Timer und System.Threading.Timer
□ minimale Intervalllänge 15ms
■ Microsoft.SPOT.ExtendedTimer
□ nur im Micro Framework
■ QueryPerformanceFrequency + QueryPerformanceCounter
□ nicht Teil von .NET, aber der P/Invoke erreichbar
□ hochauflösender Timer
□ Auflösung hängt von Plattform ab
□ 14.318.180 Counts/s auf diesem Laptop (~0,07µs)
Alle Timer geben keine Garantie für Einhaltung des Intervalls
Real Time .NET | Sebastian Klose | 7. Januar 2009
14
Echtzeittauglichkeit - Timing
■ System.Threading.Thread
□ basiert auf normalen Windows Threads
□ nur 5 Prioritäten vorgesehen (keine davon für Echtzeit)
□ Echtzeitpriorität kann per P/Invoke auf Echtzeit gesetzt
werden
■ keine periodischen Threads mit garantierter Startzeit
■ Priority Inversion
□ Windows CE implementiert Priority Ceiling Protokoll
□ .NET CF Anwendungen profitieren aber nicht davon
Real Time .NET | Sebastian Klose | 7. Januar 2009
15
Echtzeit mit Microsoft .NET
Real Time .NET | Sebastian Klose | 7. Januar 2009
16
Echtzeit mit dem .NET Framework
■ Verhindern, dass GC aktiv wird
□ alle Objekte bei Initialisierung anlegen
□ nach der Initialisierung
◊ keine neuen Objekte mehr anlegen
◊ kein boxing/unboxing verwenden
■ performancekritische Teile
□ beim Micro Framework in nativen Code auslagern
■ exakte Timer
□ mit QueryPerformanceCounter implementieren
Real Time .NET | Sebastian Klose | 7. Januar 2009
17
Real Time .NET
Real Time .NET | Sebastian Klose | 7. Januar 2009
18
RT.NET - Überblick
■ 2 Ansätze für ein echtzeitfähiges .NET Framework
1. Adaption der RTSJ
◊ vorgeschlagen von University of York
◊ keine Implementierung verfügbar
2. Austausch nicht-echtzeitfähiger Komponenten
◊ vorgeschlagen und implementiert von Martin von Löwisund Andreas Rasche
Real Time .NET | Sebastian Klose | 7. Januar 2009
19
RT.NET - Ziele
■ AOT Compiler statt JITter
■ echtzeitfähiger Garbage Collector
■ Erweiterung von System.Threading
□ mehr Prioritäten
□ periodische Threads
□ Priority Ceiling Protokoll
■ direkter Zugriff auf die Hardware
■ Interrupt Handler
Real Time .NET | Sebastian Klose | 7. Januar 2009
20
RT.NET - Geschwindigkeit
Real Time .NET | Sebastian Klose | 7. Januar 2009
21
RT.NET – Speicherverwaltung
■ Referenzzählung statt Mark & Sweep
□ Objekte werden sofort freigegeben
□ Garbage Collection findet immer zur gleichen Zeit statt
□ potentielle Probleme
◊ zirkuläre Referenzen
◊ Freigabe eines Objekts kann zur Freigabe weiterer Objekte führen
■ Erweiterte Referenzzählung
□ Objekte werden nicht sofort freigegeben, sondern in eine
Queue eingeordnet
□ Hintergrundthread löscht Objekte in Queue
□ Thread kann in den RT Schedule eingeplant werden
Real Time .NET | Sebastian Klose | 7. Januar 2009
22
RT.NET - Timing
Real Time .NET | Sebastian Klose | 7. Januar 2009
public delegate void ThreadStart();
public class PeriodicThread{PeriodicThread(ThreadStart start, RelativeTime period);static void WaitforNextPeriod();static void Sleep(RelativeTime time);static PeriodicThread CurrentThread();void Start();ThreadPriority Priority {get; set;};
}
23
RT.NET - Timing
Real Time .NET | Sebastian Klose | 7. Januar 2009
enum MutexProtocol{PriorityCeiling, PriorityInheritance, None
}
class ExtendedMutex: Mutex{public ExtendedMutex();public ExtendedMutex(PriorityCeiling ceiling);public bool WaitOne(int millisecondsTimeout, bool
exitContext);public void ReleaseMutex();public void Close();public ThreadPriority PriorityCeiling{get; set;}public MutexProtocol Protocol{get; set;}
}
24
RT.NET - Hardwarezugriff
Real Time .NET | Sebastian Klose | 7. Januar 2009
struct Port {[MemoryAlias(0xffb2)] static byte DataRegister;
[PortAlias(0xffa0)]static byte OutputPort;
}
[InterruptHandler] static void Irq0H() {}
H8_3297.Irq0 = Irq0H;
25
RT.NET - Evaluation
Real Time .NET | Sebastian Klose | 7. Januar 2009
26
RT.NET - Evaluation
Real Time .NET | Sebastian Klose | 7. Januar 2009
27
Referenzen
[1] An Overview of the .Net Compact Framework Garbage
Collector - Steven Pratschner
http://blogs.msdn.com/stevenpr/archive/2004/07/26/197254.aspx
[2] Garbage Collection: Automatic Memory Management in the
Microsoft .NET Framework - Jeffrey Richter
http://msdn.microsoft.com/de-de/magazine/bb985010(en-us).aspx
[3] C# and the .NET Framework: Ready for Realtime?
Michael H. Lutz, Phillip A. Laplante
[4] Towards a Real-Time Implementation of the ECMA Common
Language Infrastructure
Martin v. Löwis, Andreas Rasche
[5] C# For Real Time - Examining Execution Speed of JITted
Code With CF 2.0 - Chris Tacke
Real Time .NET | Sebastian Klose | 7. Januar 2009
28
Referenzen
[6] Comparing the Timer Classes in the .NET Framework Class
Library - Alex Calvo
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
[7] The .NET Micro Framework
http://informatix.miloush.net/microframework/WhatIs.aspx
[8] Embedded .NET
Jens Kühner / Vallon GmbH, dotnetpro 11/08
[9] Die Garbage Collection des .NET Frameworks
Christoph Oster, dotnetpro 7/07
[10] Requirements for a Real-Time .NET Framework
A. Zerzelidis and A.J. Wellings
Department of Computer Science, University of York, U.K.
Real Time .NET | Sebastian Klose | 7. Januar 2009
29