Fortschrittliche Netzteile beispielsweise erfordern heutzutage nicht nur eine präzise und effiziente Regelung der Energieumwandlung durch mathematische Algorithmen und eine Echtzeit-Pulsweitenmodulation (PWM). Sie benötigen auch eine Datenanbindung, um den Betriebszustand in Echtzeit bereitzustellen und Befehle von einer Management-Einheit auf Systemebene über Protokolle wie PM-Bus zu empfangen. Ähnlich ist bei einer Lüfter- oder Pumpensteuerung in Fahrzeugen eine Kommunikation über ein Protokoll wie CAN-FD (Controller Area Network – Flexible Datarate) für Befehle, Systemüberwachung und Diagnose erforderlich. Eine Klimaanlage kann aufgrund von separaten DSP-Aufgaben für die Leistungsfaktorkorrektur im Stromnetz sowie die Drehzahlregelung in Gebläsen und Pumpen noch komplexere Anforderungen haben.

Grenzen eines Single-Cores

Überschrift

Embedded-Anwendungen, die eine hohe DSP-Leistung benötigen, verlangen nicht mehr nur eine Leistungssteigerung, um immer komplexere mathematische Algorithmen zu verarbeiten. Vielmehr sind heute zusätzliche Datenkommunikation, funktionale Sicherheit und Verwaltungsfunktionen absolut notwendig. Diese Faktoren verändern die Art und Weise, wie Anwendungen die Rechenleistung hochintegrierter Mikrocontroller und digitaler Signalcontroller einsetzen.

Im Prinzip kann ein einzelner schneller CPU-Core durch Zeitschlitze viele unabhängige Threads ausführen, um Echtzeit-Steuerungsaufgaben mit niedriger Latenz als auch Netzwerk- und Systemverwaltungsaufgaben abzufertigen. Ein Core, der für eine so hohe Leistungsfähigkeit in einer bestimmten Prozesstechnologie ausgelegt ist, kann jedoch in Bezug auf Stromverbrauch und Komplexität ein Problem darstellen.

Eine weitere Herausforderung für jede Echtzeitanwendung, die auf einem einzelnen Core ausgeführt wird, ist die Frage, wie leicht Threads und Interrupt Handler ihre jeweiligen Fristen einhalten können. Bei jeder Implementierung mit gemeinsam genutzten Ressourcen ist jene Zeitspanne ein Problem, in der ein unabhängiger Prozess oder Interrupt Handler einen bestimmten Thread blockiert. Um zu gewährleisten, dass ein Thread seine Zeitfristen unter allen Bedingungen einhält, in denen Threads keine Abhängigkeiten aufweisen, verlangen konservative Algorithmen zur Berechnung des erforderlichen Spielraums, dass ein relativ großer Teil der Verarbeitungszyklen nicht zugeordnet wird.

Es gibt auch einen Overhead für häufige Task-Wechsel, der berücksichtigt werden muss – genauso wie dessen Auswirkungen auf die Rechenleistung. Bei einer großen Anzahl von Interrupts für einen einzelnen Core kann der Aufwand für die Interrupt-Behandlung und die damit verbundenen Task-Wechsel erheblich sein.

Eine Möglichkeit der Verbesserung besteht darin, durch noch höhere Taktraten mehr Spielraum für Leistungsfähigkeit zu schaffen. In der Praxis kann es jedoch sinnvoller sein, die Anwendung auf mehr als einen Prozessor-Core aufzuteilen. Bei einer Multitasking-Anwendung, die nicht in erster Linie vom Durchsatz eines einzelnen Threads abhängt, sorgt Parallelität für mehr Energieeffizienz, Determinismus und ein einfacheres Design.

Abhilfe durch Dual-Cores

Anwendungsbeispiel eines DSPIC33CH in einer Klimaanlage.

Anwendungsbeispiel eines DSPIC33CH in einer Klimaanlage Microchip

Dahingegen kann eine Dual-Core-Implementierung die Arbeitslast eines Multitasking-Systems effektiver verteilen. Dies führt auch zu niedrigeren Core-Taktfrequenzen, die sich für Flash-Speicher besser eignen. Des Weiteren lässt sich so die Anzahl der Stillstands-/Wartezyklen, in denen der Prozessor auf Anweisungen oder Daten warten muss, erheblich reduzieren.

In einigen Anwendungen bevorzugen eng miteinander verknüpfte Aufgaben, die verwandte Datenfeeds verarbeiten, immer noch eine einzelne Pipeline. Soll ein Prozessor in einer leistungsstarken Embedded-Anwendung dagegen verschiedene Funktionen ausführen, ist mehr als ein Core sinnvoll, da die verschiedenen Funktionen relativ lose gekoppelt sind.

So wird die Leistungsfähigkeit eines Netzteils, in dem die Regelung in Firmware implementiert ist, vorwiegend durch jene Zeit bestimmt, die erforderlich ist, um ein analoges Sample in einen digitalen Wert umzuwandeln. Aus diesen Daten lassen sich dann ein neuer Pulsweitenwert berechnen und die PWM-Einheit aktualisieren. Ein Multicore-Controller stellt sicher, dass andere Systemaktivitäten diese latenzkritische Funktion nicht behindern, indem sie auf einem Core ausgeführt wird, der keine anderen priorisierten Aufgaben erfüllen muss. Parallel zu den zeitkritischen Regelkreisberechnungen lassen sich einem anderen CPU-Core andere Aufgaben zuweisen wie etwa die PM-Bus-Kommunikation und Systemüberwachungsfunktionen. In einer Motorsteuerung stellt eine Aufteilung der Regelkreisverarbeitung und des CAN-Interface-Stacks auf verschiedene Cores sicher, dass die Kommutierung des Motors präzise und deterministisch erfolgt.

Getrenntes Arbeiten

Die aufgeteilte Verarbeitung bietet einen weiteren Vorteil in Bezug auf die Projektentwicklungszeit. Dafür ist es jedoch essentiell, dass die beiden Cores homogen sind, um diese Funktion auch zu nutzen. Eine traditionelle Option für das Multiprocessing war bisher die Aufteilung der Arbeitslast nach Prozessortyp. Signalverarbeitungscode ist für die Ausführung in einer Pipeline vorgesehen, die für Multiplikations- und Akkumulationsaufgaben optimiert ist – aber nur wenig Möglichkeiten bietet, Steuercode effizient auszuführen, während ein Universalprozessor sich für Routinen mit vielen Verzweigungen besser eignet. In der Praxis ist dies in vielen Echtzeitanwendungen eine schwierig handhabbare Architektur. Die Signalverarbeitung hängt oft von äußeren Bedingungen ab, die sich schnell ändern können. Die Interprozessor-Kommunikation, die zum Synchronisieren von Zuständen zwischen den verschiedenen Cores erforderlich ist, kann komplex sein, da sie strengere Anforderungen und synchrones Timing erfordert als Nachrichten, die beim Weiterleiten von Befehlen und Statusaktualisierungen an eine Netzwerkschnittstelle Verwendung finden.

Einheitliche DSC-Architekturen wie der DSPIC33 von Microchip überwinden diese Synchronisierungsprobleme, indem sie die beiden Ausführungsarten in einer einzigen Architektur vereinen. Eine solche Pipeline kann Multiplikations-, Akkumulations- und Matrixoperationen mit hohen Geschwindigkeiten ausführen. Jedoch bietet sie ebenso schnelle Verzweigungen und eine schnelle Reaktion auf Interrupts, sodass sich Parameter und Algorithmen während des Betriebs an sich ändernde Bedingungen anpassen können. Dies erleichtert die Software-Implementierung komplexer Signalverarbeitungsalgorithmen. Da sich die Entwicklungszeiten zunehmend verkürzen, stehen die Kunden jedoch vor Herausforderungen bei der Code-Integration – unabhängig von der gewählten Architektur. In vielen Anwendungen übernehmen separate Entwicklungsteams die Bereiche Kommunikation und Steuerung, da sie jeweils Spezialisten auf einem Gebiet sind.

Mögliche Anwendungsgebiete für Master- und Slave-Cores.

Mögliche Anwendungsgebiete für Master- und Slave-Cores Microchip

Entscheidend bei der Integration des Codes aus zwei oder mehr Teams sind die Zeitplanung und die Priorisierung von Aufgaben. Scheinbar kleine Entscheidungen wie die Priorität einzelner Aufgaben können einen großen Einfluss auf das gesamte Echtzeitverhalten der Anwendung haben. Schlechte Entscheidungen führen dazu, dass wichtige Aufgaben länger für den Prozessor gesperrt sind, als dies für hohe Leistungsfähigkeit wünschenswert wäre. Durch die Verteilung der Task-Sets auf zwei Prozessoren sind jene Entwickler mit dem größten Wissen über die jeweils nötigen Thread-Prioritäten auch für die entsprechende Festlegung dieser Prioritäten verantwortlich.

Die aufgeteilte Verarbeitung ermöglicht auch eine einfachere Verwaltung und Zuweisung von Datenspeicher und stellt sicher, dass Makefiles und Linker-Einstellungen, die während des Projekts erstellt und debuggt wurden, im endgültigen Softwarepaket erhalten bleiben. Dies reduziert den Aufwand für das Software-Integrationsteam und verkürzt die Markteinführungszeit.

Obwohl die getrennte Verarbeitung bereits dazu beiträgt, den Entwicklungsaufwand und die Rechenleistung zu optimieren, verbessert Microchip weiterhin laufend die Architektur, um die Leistungsfähigkeit zu steigern. Im Dual-Core DSPIC33CH kommen etwa mehr kontext-selected Arbeitsregisterbänke zum Einsatz, um die Reaktionsfähigkeit der Interrupts zu erhöhen. Der Core bietet zudem zusätzliche Anweisungen, um die DSP-Leistungsfähigkeit zu verbessern.

Signalwandler für gängige Embedded-Anwendungen

Als DSC bietet der DSPIC33CH fortschrittliche Peripherie, um die Systemkosten und die Board-Größe zu reduzieren. Dazu gehören schnelle A/D-Wandler, D/A-Wandler mit Signalgenerierung, analoge Komparatoren, analoge Verstärker mit programmierbarer Verstärkung (PGA) und hochauflösende PWM-Generatoren mit einer Auflösung von bis zu 250 ps. Erweiterte Funktionen wie intelligentere Peripheriemodule und ein Trigger-Generator für Peripherieeinheiten tragen dazu bei, die Anzahl der Interrupts zu reduzieren, denen ein Core in einer Stromversorgung oder Motorsteuerung ausgesetzt ist. Die UARTs bieten beispielsweise Hardwareunterstützung für LIN/J2602, IrDA, DMX und Smartcard-Protokollerweiterungen, um den Software-Overhead zu reduzieren. Ebenso enthält die CAN-FD-Peripherie einen Bit-Stream-Prozessor und eine programmierbare automatische Weiterleitung, damit sie unabhängiger vom CPU-Core laufen kann.

Mit einem auf die Anforderungen heutiger Entwicklungsteams ausgerichteten Design ist der DSPIC33CH von Microchip für leistungsstarke und zeitkritische, praxistaugliche Embedded-Steuerungen optimiert. Die Architektur bietet den Support, den die Kunden benötigen, um getrennt zu entwickeln und nahtlos zu integrieren. Das Ergebnis ist eine Architektur, die die Leistungsfähigkeit erhöht und gleichzeitig die Dauer der Markteinführung, die Systemgröße und die Kosten reduziert.