Forum: Mikrocontroller und Digitale Elektronik ARM bevorzugter Betriebsmode der End-Application


von Dietmar (Gast)


Lesenswert?

Hallo Leute,

nun, der ARM7 (LPC21xx) läuft und läuft, ganz gut, ich möchte nur noch 
mal heraus finden, ob ich mit einfachen Mitteln den Code vereinfachen 
und die Performance verbessern kann, ohne der Anwendung zu schaden.

Ich möchte heute mal in Erfahrung bringen, in welchem Mode man seine 
Anwendung auf einem ARM7 sinnvoll betreiben kann. Nicht, daß ich die 
Modes und deren jeweilige Einschränkung und Vorteile nicht kenne. Gehen, 
tut ja vieles, und im Grunde kann ich auch machen was ich will, 
Hauptsache die Anwendung läuft hinterher sauber. Aber: ARM gibt in 
seinen Manuals die bevorzugte Benutzung des USER-Modes an, stellt aber 
andere Modes zur Debatte. Im USER-Mode jedoch, ist man auch am weitesten 
in der Benutzung des Controllers eingeschränkt.

Ein Kollege, mit anderen ARM, ARM9, beschäftigt, sagte mir dazu, der 
USER-Mode sei schon sinnvoll, verhindere eine Menge Unfug und 
unstrukturierte Programmierung. Nun, ich kann das noch nicht ganz 
nachvollziehen.

An anderen Stellen liest man wieder Diskussionen, ob der Betriebsmode 
der Anwendung der USER-Mode, SYSTEM-Mode oder SUPERVISOR-Mode sein kann.

Meine Anwendung läuft zur Zeit im USER-Mode. Möchte ich Teile des Codes 
gegen alle IRQ gesperrt haben, z.B. so sensible Dinge wie FIFO-Zugriffe, 
die keinesfalls reentrant sein dürfen, muß ich diese im SWI-Mode laufen 
lassen, da aus dem USER-Mode kein Zugriff auf CPSR, um IRQ- und FIQ- 
Line direkt zu sperren. Interrupt-Sperre geht aus dem USER-Mode nur über 
VIC mit Sicherung aller Flags in einer Variablen.

Im SYSTEM-Mode könnte ich Interrupts IRQ und FIQ direkt über CPSR 
sperren und hätte den Code-Overhead des SWI nicht.

Die SWI-Numerierung muß ich unter GCC oder RealView parallel an 2 
Stellen und zwar für das SWI-Assembler-File und in einem C-Header-File 
verwalten. Bei Fehlern in der Numerierung, gibt es keine 
Compiler-Errors, weil logische Fehler. Hinzu kommt, daß es auch mehrere 
Targets gibt, wobei jeweils Teilmengen der SWI-Funktionen benötigt 
werden. Das macht das ganze zur Compile-Time schon störungsanfällig. 
Keil CARM, 2005 eingestellt und nicht mehr zur weiteren Verwendung 
empfohlen, generiert die SWI-Tabelle noch automatisch, da fiel eine der 
beiden Definitionsquellen weg, und es war problemlos.

Das sind jetzt nur mal ein paar Überlegungen, Details und Anregungen.

Wer hat denn da gute Erfahrung mit der einen oder anderen Lösung?

Gruß

Dietmar

von Andreas K. (a-k)


Lesenswert?

Ich sehe wenig Sinn darin, auf einem Controller mit in jedem Modus 
unbeschränker Adressierfähigkeit ein paar kleine Systemfunktionen wie 
Interrupt-Steuerung über User/System Trennung einschränken zu wollen. In 
Controllern ohne MMU gibt es heutzutage keine unkontrollierten 
Anwenderprozesse, vor denen sich zu schützen es sich lohnt.

Diese Trennung ergibt erst dann wirklich Sinn, wenn der Adressraum eines 
USER Prozesses auf seine eigenen Code+Daten-Bereiche beschränkt ist, 
d.h. eine MMU verwendet wird. DANN erst entsteht durch die 
Privilegientrennung ein erhebliches Mass an Sicherheit. Die meisten 
Programmfehler entstehen in C durch unbeabsichtigten Speicherzugriff, 
nicht durch unberechtigte Interrupt-Steuerung.

Historisch gesehen hatte bereits die erste eingesetzte Generation von 
ARM Prozessoren eine MMU, wenngleich extern. Und so wurde die 
User/System-Privilegientrennung von Anfang an auch verwendet. Die 
Eignung von ARM für Embedded Systems war nicht Ziel der Entwicklung 
sondern ergab sich ursprünglich als Nebeneffekt. Und so steckt das halt 
auch im ARM7 Core drin, ohne dass es im Kontext monolithischer 
Microcontroller-Programme sonderlich viel bringt.

von Andreas K. (a-k)


Lesenswert?

> Ein Kollege, mit anderen ARM, ARM9, beschäftigt, sagte mir dazu, der
> USER-Mode sei schon sinnvoll, verhindere eine Menge Unfug und
> unstrukturierte Programmierung.

Könnte daran liegen, dass viele ARM9 Systeme über eine MMU verfügen und 
nicht selten echte Betriebssysteme wie Linux eingesetzt werden, die eine 
MMU auch erforderlich machen.

ARM7 mit MMU ist hingegen eher selten und die verwendeten Programme sind 
meist von monolithischem Charakter. Entsprechen also weniger einem PC 
mit separatem Betriebssystem und all seinen darauf laufenden 
unabhängigen Programmen als vielmehr einem einzelnen PC-Programm, 
möglicherweise mit RTOS-Library vgl. manchen älteren reinen 
Userspace-Threadings in Unix.

von Andreas K. (a-k)


Lesenswert?

Apropos unstrukturierter Code: Es stimmt schon, dass man bei 
Privilegientrennung dazu gezwungen wird, Funktionen (SWIs) für 
Interrupt-Steuerung zu verwenden. Nichts und niemand ausser dem inneren 
Schweinehund hindert einen jedoch daran, auch ohne Privilegientrennung 
strukturiert zu programmieren.

Mit dieser gleichen Logik sollte man lieber nicht in C programmieren. Es 
gibt weiteraus besser definierte und kontrollierende Programmiersprachen 
(Ada beispielsweise). Da man jedoch um C in der Praxis meist nicht herum 
kommt, hat man ohne eine gewisse Disziplin hinsichtlich 
Programmiertechnik und Programmstrukturierung ohnehin schnell verloren.

Um zu einem konkreten Beispiel zu kommen: Was Interrupt-Steuerung 
angeht, kommt man mit C++ weitaus weiter. Darin sieht eine vor Interrupt 
geschützte Funktion nämlich so aus:
1
void
2
UARTbase::put(int c)
3
{
4
    OS::Critical cs;
5
    if (txidle) {
6
        uart->thr = c;
7
        txidle = false;
8
    } else {
9
        tx.put(c);
10
    }
11
}
Die ganze Interrupt-Steuerung steckt hier in Konstruktur (save+disable) 
und Destruktor (restore) vom Objekt "cs". Insbesondere kann man so nicht 
versehentlich vergessen, die Interrupts wieder einzuschalten (per return 
irgendwo zwischendrin) weil der Compiler selber dafür sorgt, dass der 
Destruktor garantiert und an der richtigen Stelle aufgerufen wird.

Ob man in der Implementierung von OS::Critical die Interrupt-Flags 
direkt steuert oder auf SWIs abstützt, ist dann gleichwertig, das eine 
nicht sicherer als das andere. Und weil das Zeug ggf. nur aus 
inline-Funktionen besteht, ist es auch effizient.

von Rolf Magnus (Gast)


Lesenswert?

> Die SWI-Numerierung muß ich unter GCC oder RealView parallel an 2
> Stellen und zwar für das SWI-Assembler-File und in einem C-Header-File
> verwalten.

Warum?

> Wer hat denn da gute Erfahrung mit der einen oder anderen Lösung?

Ich benutze einen ARM7, bei dem das Programm im System-Modus läuft. Ich 
sehe keinen Sinn darin, die Interruptsperrung durch einen SWI zu leiten. 
Letztendlich kann das Programm dann immer noch die Interrupts sperren, 
wenn auch nur indirekt. Welche Fehler willst du konkret dadurch 
vermeiden?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.