Forum: Mikrocontroller und Digitale Elektronik µC - Alles auf einmal! (Design-Pattern)


von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Hallo Leute,

ich programmiere schon eine Weile Microkontroller, bin der Meinung, dass 
ich jetzt schon ein bisschen was gelernt habe (wenn auch bei leibe nicht 
alles).

Während meiner zweiten Ausbildung lernten wir die ganze Grundlagen, also 
das 1x1 der Microkontrollerprogrammierung.
Wie etwa dimmen über PWM, mittels ADC Spannungswerte auslesen, auf 
verschiedene Art und Weisen Tasten entprellen, UART, mittels UART und 
AT-Commands weitere Peripherie ansprechen wie etwa einen 
Ethernet-Controller und damit ein kleines Netzwerk aufbauen, 
LCD-Displays, usw, usf.

Zum auf die Sahnetorte-Hauen reicht es zwar noch nicht, aber ich habe 
immerhin einigen an der Uni jetzt was voraus.

Alles Weitere müsste ja „nur” die Weiterführung bekannter Strategien 
sein. Sehr salopp ausgedrückt.

Aber genau daran zweifel ich gerade.
Denn das, was ich oben angesprochen habe, könnte ich alles ohne Probleme 
mit einem ATtiny13 ode ATtiny45 realisieren. Zusammen aber, brauche ich 
einen größeren µC. Alleine schon wegen der Ports. Alles klar soweit. 
Aber wie löst man das ganze, wenn man alles scheinbar gleichzeitig 
ablaufen lassen will?

Ich bin gerade dabei das DOGL-Display anzusprechen. (Aktuell bin ich da 
noch nicht weit.)
http://www.reichelt.de/DOG-LCD-Module/EA-DOGL128W-6/index.html?;ACTION=3;LA=444;GROUP=A5213;GROUPID=3007;ARTICLE=86713;START=0;SORT=artnr;OFFSET=16;SID=13TgBLLn8AAAIAAApYZKcc7facb4c1c94d9d088dd547b81ff243b

Das finde ich ein gutes Beispiel.
Ich denke, es ist normal, wenn ich folgendes mal ausprobieren möchte.
Ich möchte mit dem ADC analoge Werte einlesen, sie auf dem Display als 
Graph darstellen, die LEDs dimmen und vll. später noch zusätzliche 
Funktionen implementieren wie etwa Tasten für Settings nutzen.

Also wie man das ganze grundsätzlich umsetzt ist mir klar.
Wenn mein Display denn nun endlich laufen sollte, dann kann alles auch 
noch rein sequenziell ablaufen.
Nach dem Init aller Geräte erst den ADC auslesen, das Displaybild 
ausrechnen und das Display ansprechen. Dann wieder mit dem ADC beginnen.
Ich denke, das Timing des Displays lässt sich wieder mit „Takte zählen” 
realisieren.

Aber was, wenn ich später Interrupts brauche und dieser mir zum Beispiel 
dann das Displaytiming oder das Timing für den UART kaputt macht?

Wonach ich also im Grunde frage, gibt es eine Art Design-Pattern um 
komplexere µC-Programme (jetzt werden sicher die einen oder anderen 
lachen ;)) zu planen und zu programmieren?

Denn, selbst ohne Interrupts kann es vom Timing her schon schwierig 
werden.
Ich ziehe mir mal folgendes an den Haaren herbei:
Ich möchte diese Werte nicht nur anzeigen, sondern auch über UART 
schicken und Befehle über UART und  den zu entprellenden Tasten 
erhalten. Zusätzlich habe ich für das Display ja auch noch den 
Touch-Screen den ich ja auch noch auslesen möchte.
Jetzt müsste ich mir doch langsam Gedanken machen, wie ich das ganze 
ineinander verflechte, damit jedes Programmteil zur rechten Zeit, seinen 
Teil der Rechenzeit abbekommt? Oder würde vielleicht mit diesem Vorhaben 
der µC auch gar nicht erst an seine Leistungsgrenzen gebracht? Das habe 
ich jetzt nicht nachgeprüft. Ich nutze im Moment einen ATmega32, habe 
aber auch noch einen mega644 und mega1284 daliegen. Wie sieht es mit 
denen aus?

Ab wann, abgesehen, davon, dass der Flash oder RAM nicht reicht, muss 
ich auf einen größeren Kontroller wie etwa einen XMega oder gar einen 
ARM setzen? Oder auch einen der anderen zahlreichen Familien?
Gibt es da Hausnummern, an die man sich orientieren kann?
Ich meine, oftmals, lässt sich das ausrechen. Wenn man etwa ein großes 
Display anzusprechen hat und den Inhalt anzeigen muss, errechnen muss 
und diesen vielleicht sogar noch gestreamt bekommt. Dann ist mir klar, 
dass ich da schnell an meine Grenzen kommen und wo die liegen. Was aber, 
wenn ich einige Aufgaben habe, die ich einzeln mit einem Kontroller 
locker erledigen könnte, zusammen aber komplex werden?
Dabei sehe ich aber auch im Internet, wie Leute auf den Megas und diesem 
Display Graphiken in Echtzeit(TM) errechnen und darstellen.


http://www.youtube.com/watch?v=kksbmkOKyO0
http://www.youtube.com/watch?v=wohy1HPF-Fk
http://www.youtube.com/watch?v=Ps4HbTnFMCc
http://www.youtube.com/watch?v=QsQdH37aVWU
Das mit der Erwähnung der Liveberechnung,
habe ich jetzt nicht mehr gefunden.
____________________

So, jetzt habe ich mich wunderbar verloren.

Gibt es Design-Pattern für komplexere Programme?
(Eine Seite mit Design-Pattern generell wäre auch gut, aber 
mikrocontroller.net bietet da schon viel.)

Wie skaliert man die Zielplattform für ein neues Projekt richtig?
Besonders wenn größer nicht unbedingt besser ist, alleine des Geldes 
wegen.

Gruß und einen schönen Sonntag noch.
Ich hoffe, ihr hattet auch so einen schönen Sonnenaufgang wie ich. ;)
Fabian

von M. P. (phpmysqlfreak)


Lesenswert?

Fabian Hoemcke schrieb:
> Nach dem Init aller Geräte erst den ADC auslesen, das Displaybild
> ausrechnen und das Display ansprechen. Dann wieder mit dem ADC beginnen.
> Ich denke, das Timing des Displays lässt sich wieder mit „Takte zählen”
> realisieren.
>
> Aber was, wenn ich später Interrupts brauche und dieser mir zum Beispiel
> dann das Displaytiming oder das Timing für den UART kaputt macht?

Wenn du eine Hardware-UART nutzt, wird dieser sogar einen Interrupt 
erzeugen können. ;) Software-Technisch müsste man mit einem 
Timer-Interrupt arbeiten, um die im Taktfenster zu bleiben.
Laut Datenblatt hat das Display ein SPI-Interface - auch dabei wird das 
Senden von eigener Hardware übernommen, und hinterher kann ein 
Interrupts ausgelöst werden.
Hast du diese Dinge komplett in Software gemacht, oder die 
Controller-Eigenen Hardware-Schnittstellen genutzt?

Ein Design-Pattern generell habe ich noch nicht gefunden, aber auch 
nicht gesucht. Wenn es um ein neues Projekt geht: Stift und Zettel!
Funktionalität beibehalten, aber komprimieren. Welche Aktionen kann ich 
mit einem Timer machen (entprellen, spart Hardware), welche MÜSSEN einen 
Timer haben? ADC-Werte ermittel' ich immer im gleichen Abstand, bilde 
den Mittelwert 64 Werten und setze ein Flag in "meinem" Statusregister. 
Der Programmteil, der den Wert braucht, "entnimmt" sich den Wert und 
setzt das Flag zurück. - Erst wenn das Flag wieder gesetzt ist, wird der 
entprechende Programmteil wieder ausgeführt. (Stichwort: State-Machine 
;))

Es ist zwar nicht alles, aber ich hoffe ein Anreiz für dich, zum 
nachdenken.

Gruß,

Marcel

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Marcel Papst schrieb:
> Wenn du eine Hardware-UART nutzt, wird dieser sogar einen Interrupt
> erzeugen können. ;) Software-Technisch müsste man mit einem
> Timer-Interrupt arbeiten, um die im Taktfenster zu bleiben.
> Laut Datenblatt hat das Display ein SPI-Interface - auch dabei wird das
> Senden von eigener Hardware übernommen, und hinterher kann ein
> Interrupts ausgelöst werden.
> Hast du diese Dinge komplett in Software gemacht, oder die
> Controller-Eigenen Hardware-Schnittstellen genutzt?

Danke Dir erstmal.

Si ganz genau kann ich Dir jetzt auf die letzte Frage nicht antworten. 
Zu mindest nicht auf einmal.
Denn es waren ja meist einzelne Projekte und dass ich das letzte mal 
eines davon umgesetzt habe ist schon eine Weile her. Denn in der Uni 
hatten wir „nur” FPGAs. Auch was feines. Aber für zu hause eben zu 
teuer.

Also den UART habe glaube ich immer in Hardware umgesetzt und dann in 
polling- oder Interrupt-Mode (ich weiß es nicht mehr) dann nur noch die 
Werte gelesen oder geschrieben.

PWN hatte ich immer in Software mit einen Timer gemacht. Overflow- und 
CompareMatch- Interrupt. Aber ich weiß, dass es dafür auch spezielle 
Channels gibt.

SPI-als HW-Lösung gibt es auch? Das hatte ich bisher überlesen.
Bisher nie genutzt, daher...
Außerdem scheinen das alle hier im Forum, was ich bis hetzt überflogen 
habe, in SW zu lösen.
Wahrscheinlich so lange man experimentier.


Für den Rest vielen Dank.
Klingt sehr nach divide and conquer. ;)

Gruß
Fabian

von M. P. (phpmysqlfreak)


Lesenswert?

Fabian Hoemcke schrieb:
> SPI-als HW-Lösung gibt es auch? Das hatte ich bisher überlesen.
> Bisher nie genutzt, daher...
> Außerdem scheinen das alle hier im Forum, was ich bis hetzt überflogen
> habe, in SW zu lösen.
> Wahrscheinlich so lange man experimentier.

Ausschnitt des Datenblattes für den ATMEGA16, Seite 1

• Peripheral Features
– Two 8-bit Timer/Counters with Separate Prescalers and Compare Modes
– One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and 
Capture
Mode
– Real Time Counter with Separate Oscillator
– Four PWM Channels
– 8-channel, 10-bit ADC
8 Single-ended Channels
7 Differential Channels in TQFP Package Only
2 Differential Channels with Programmable Gain at 1x, 10x, or 200x
– Byte-oriented Two-wire Serial Interface
– Programmable Serial USART
– Master/Slave SPI Serial Interface
– Programmable Watchdog Timer with Separate On-chip Oscillator
– On-chip Analog Comparator


4 PWM-Kanäle
Hardware-TWI (für I2C z.B.)
Hardware-USART (Serielle Schnittstelle für z. B. einen PC)
*Master/Slave SPI Schnittstelle*

Alles da, würde ich mal sagen. ;)

Gruß,
Marcel

von MaWin (Gast)


Lesenswert?

> aber ich habe immerhin einigen an der Uni jetzt was voraus.
> Aber genau daran zweifel ich gerade.

Eben.

Die an der Uni wissen bei ANDEREN Dingen eben mehr als du,
selbst wenn sie zufälligerweise DEINE Kenntnisse noch nicht
erarbeitet haben.

Das, was du Design Pattern nennst, wird an der Uni durchaus
gelehrt (heisst bloss alle 10 Jahre anders), aber das ist
ja nur der DERZEITIGE Stand der Technik (und auch nur ein
kleiner Ausschnitt davon, den Rest findet man per Google :-).

Was die Uni vor allem lehren sollte, ist DARÜBERHINAUSGEHENDES,
wie man also "die Design Vorlagen der Zukunft" entwickeln kann,
und sie liefert dazu das Handwerkszeug (Komplexitätsberechnung).

Das fehlt dir vollkommen.

> Gibt es Design-Pattern für komplexere Programme?

Es gibt mehrere.

Und man muß das möglichst gut passende auswählen, damit
die Lösung gut wird (wir fordern nicht mal 'bestmöglich',
sondern es reicht schon wenn es funktioniert und in den
uC hineinpasst).

Das allgemeine Design Pattern lautet erst mal: Es gibt
eine im Prinzip endlos rumlaufende Hauptschleife, in der
anstehende Aufgaben in kleinen Häppchen abgearbeitet werden
(Event-Loop).
Es KANN nötig sein, Ereignisse (per Interrupt) schnell zu
registieren, aber wenn deren Bearbeitung länger dauert,
ist nur ein Merker zu setzen, damit die Hauptschleife die
Erledigung der Arbeit übernimmt, wenn Zeit ist (Message
Bearbeitung).
Bei lange abzuarbeitenden Aufgaben, so lange daß die
Reaktionsgeschwindigkeit der Event Loop gestört wird,
kann es nötig sein, diese als Prozess niedriger Priorität
aufzufassen, was kooperativ oder preemptiv verwaltet
werden kann.

Dieses Design Pattern reicht recht weit, vom winzigen
superschnellen Microcontroller bis zum Windows-PC, aber
natürlich ist es auch so schwammig, daß immer Möglichkeit
besteht, es besser oder schlechter umzusetzen.

Daher gibt es eine unverrückbare Messlatte nach der die
Qualität der Gesamtlösung bewertet und gemessen werden
kann:
Alles, was an Prozessorinstruktionen ausgeführt wird,
die weggelassen werden könnten ohne die äussere Funktion
des Programms zu beeinträchtigen, war überflüssig und
damit schlecht.
Optimal ist es, wenn auch mit anderen Algorithmen und
Strukturen nichts mehr weglassbar ist, dann ist es die
vielgesuchte "elegante Lösung".
"Weglassen" bezieht sich dabei nicht unbedingt auf die
Anzahl der Prozessorinstruktionen, 3 Schiebebefehle
können besser sein als 1 Divisionsbefehl wenn der länger
dauert, mehr Strom verbraucht, mehr Resourcen belegt, die
Schiebebefehle bewirken aber weniger Mikrocodeinstruktionen,
so daß trotzdem die Instruktionsanzahl die Messlatte ist.

von Karl H. (kbuchegg)


Lesenswert?

Timing Sachen können schon problematisch sein.
Man muss da ein wenig unterscheiden.
Ist das Timing ein Mindesttiming und spielt es keine Rolle wenn ein Puls 
mal etwas länger wird. Oder muss es ganz exakt eingehalten werden.

Oft ist es so, dass bei synchroner Ansteuerung von externen Komponenten 
das Timing nicht so wahsinnig kritisch ist. Die Synchronisierung erfolgt 
ja zb durch Pulsflanken und ob der Level ein paar µs länger als 
mindestens notwendig ist, ist nicht so kritisch.

In diesem Hintergrund: Kurze Zeiten, ein paar µs, kann man dann durchaus 
zb mittels _delay_us machen und wenn sich diese Zeit durch einen 
Interrupt etwas verlängert, dann ist das oftmals nicht kritisch. Falls 
doch, dann macht man eben eine Interruptsperre rundum.

Längere Wartezeiten mittels _delay_ms sind hingegen oftmals tödlich. Ein 
derartiges 'Design' taugt oft nicht viel. Sobald mehrere Komponenten im 
Spiel sind, die nach Möglichkeit alle mehr oder weniger gleichzeitig 
angesteuert werden sollen, gibt es mit hoher Wahrscheinlichkeit Ärger 
und das Design ist nicht zu retten. Hier führt der Ausweg praktisch 
immer über Timer. Damit einher geht ein Umdenken. Weg von "Ich benötige 
eine Wartezeit" und hin zu "Es gibt einen Basistakt, was ist jetzt, bei 
erneutem Auftreten das Basistaktes, zu tun". Im Grunde also schon eine 
Form von Event-basiertem Programmieren.

Als Design-Pattern hat sich die State-Maschine bewährt, mit der man eine 
große Klasse von Aufgaben relativ problemlos in den Griff kriegt und die 
auch das Einbinden von "Events" sehr einfach ermöglicht. Im Einzelfall 
kann es natürlich sein, dass eine State-Maschine etwas abgespeckt und 
vereinfacht bzw. implizit vorhanden ist und daher als solche nicht 
gleich erkennbar ist, sie aber nichts desto trotz vorhanden ist. Auch 
ist es oft problemlos möglich, mehrere voneinander unabhängige 
State-Maschinen in einem Programm zu betreiben und so das Multitasking 
zu erreichen.

Das wäre also das 'Pattern', das ich jedem auf einem µC ans Herz legen 
würde:
Es gibt so etwas wie 'Zustände' für einzelne Komponenten und diese 
Zustände durchlaufen abhängig von Ereignissen gewisse Werte und lösen 
dabei Aktionen aus.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Vielen Dank.

MaWin schrieb:
> Die an der Uni wissen bei ANDEREN Dingen eben mehr als du,
> selbst wenn sie zufälligerweise DEINE Kenntnisse noch nicht
> erarbeitet haben.

Arroganz steht mir nicht gut zu Gesicht.
Es war auch überhaupt nicht so gemeint. Es sollte eher eine Orientierung 
sein, wo ich gerade stehe. Klar dass es in anderen Fächern Leute gibt, 
die besser sind als ich. Ich wollte noch nicht mal damit gesagt haben, 
dass ich im Thema µC der Beste bin. Stimmt meines Wissens auch gar 
nicht.
Sondern nur, dass ich etwas mehr drauf habe, als man von uns erwartet.

Was deine anderen Punkte angeht, vielen Dank.
Mit solch einer Antwort habe ich jetzt nicht gerechnet, aber ich denke, 
sie bringt mich ein Stück weiter.
Jedoch weiß ich im Moment auch nichts mehr darauf zu antworten.

Wie gesagt:
MaWin schrieb:
> (Komplexitätsberechnung).
>
> Das fehlt dir vollkommen.

Gruß
Fabian

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> In diesem Hintergrund: Kurze Zeiten, ein paar µs, kann man dann durchaus
> zb mittels _delay_us machen und wenn sich diese Zeit durch einen
> Interrupt etwas verlängert, dann ist das oftmals nicht kritisch. Falls
> doch, dann macht man eben eine Interruptsperre rundum.

Und das macht man wie?

_

Wie betreibt man denn zwei voneinander unabhängige State-Machines in 
einem µC die sich nicht gegenseitig beeinflussen?

von Karl H. (kbuchegg)


Lesenswert?

Fabian Hoemcke schrieb:
> Karl Heinz Buchegger schrieb:
>> In diesem Hintergrund: Kurze Zeiten, ein paar µs, kann man dann durchaus
>> zb mittels _delay_us machen und wenn sich diese Zeit durch einen
>> Interrupt etwas verlängert, dann ist das oftmals nicht kritisch. Falls
>> doch, dann macht man eben eine Interruptsperre rundum.
>
> Und das macht man wie?

  Interrupts abschalten/disablen
  _delay_us
  Interrupts wieder einschalten/enablen

> Wie betreibt man denn zwei voneinander unabhängige State-Machines in
> einem µC die sich nicht gegenseitig beeinflussen?

jede als eigene Funktion, die die State-Auswertung und damit zugehörigen 
Aktionen ausführt

Und die dann wechselseitig aufrufen.

(OK, bei kurzen und einfachen Statemaschines geht das auch direkt in der 
Hauptschleife und eigene Funktionen sind nicht notwendig)

zb
1
uint8_t Led1On;
2
uint8_t Led2On;
3
4
...
5
6
7
  while( 1 ) {
8
9
    if( get_key_press( 1 << TASTE_LINKS ) {
10
      if( IsLed1On() ) {
11
        Led1_Off();
12
        Led1On = 0;
13
      }
14
      else {
15
        Led1_On();
16
        Led1On = 1;
17
      }
18
    }
19
20
    if( get_key_press( 1 << TASTE_RECHTS ) {
21
      if( IsLed2On() ) {
22
        Led2_Off();
23
        Led2On = 0;
24
      }
25
      else {
26
        Led2_On();
27
        Led2On = 0;
28
      }
29
    }
30
  }

sind im Prinzip schon 2 State-Maschines. Alle Zutaten sind vorhanden: 
Jede State-Maschine hat eine Zustandsvariable (die in dem Fall vermerkt, 
in welchem Zustand die jeweilige LED ist). Abhängig vom Zustand wird bei 
Auftreten eines Erignisses eine Aktion ausgeführt und die jeweilge 
Maschine wechselt in einen anderen Zustand.
Die beiden State-Maschines sind nicht in der klassischen Form 
ausgeführt, weil in beiden Maschinen der jeweilige Zustandswechsel für 
beide Zustände  durch gleiche Aktionen eingeleitet wird (Tastendruck), 
aber es ist eine relativ triviale Umformung von der klassischen 
State-Maschine zu dieser Form hier. Würde zb ein Blinktakt zum Blinken 
der LED ins Spiel kommen, dann würde diese Umformung wieder anders 
aussehen, programmiert man das alles allerdings als klassische 
Statemschine einfach runter, dann kann erst mal nicht viel schief gehen.


1
ZustandA      // Zustand der Statemaschine A
2
ZustandB      // Zustand der Statemaschine B
3
4
5
   while( 1 ) {
6
     case (ZustandA) {
7
8
       switch Zustand1:
9
         mach möglicherweise was
10
         if( Ereignis )
11
           mach den Übergang - Aktionen ausführen
12
           ZustandA = neuer Zustand
13
         break;
14
15
       switch Zustand2:
16
         mach möglicherweise was
17
         if( Ereignis )
18
           mach den Übergang - Aktionen ausführen
19
           ZustandA = neuer Zustand
20
         break;
21
22
       ...
23
     }
24
25
     case (ZustandB) {
26
        ....
27
   }


> Wie betreibt man denn zwei voneinander unabhängige State-Machines in
> einem µC die sich nicht gegenseitig beeinflussen?

Das ist die falsche Fragestellung.
Denn komplett 'gegenseitig nicht beeinflussen' geht nicht. Zumindest ein 
bischen Rechenzeit klaut eine Maschine immer der anderen. Die Frage ist 
dann eben: Wieviel ist das, und macht das etwas aus?

von J. W. (jw-lighting)


Lesenswert?

Fabian Hoemcke schrieb:
> Und das macht man wie?

Die Interruptsperre? Ganz einfach (Beispiel in C für AVR):
1
uint8_t SREG_cpy = SREG;
2
cli();
3
4
// ungestörter Code
5
6
SREG = SREG_cpy;

Das man nicht mit sei() arbeitet und statt dessen das SREG sichert, hat 
den Grund das sonst unter Umständen das I-Bit durch den sei()-Befehl 
setzt, obwohl es zuvor (vor cli()) gar nicht gesetzt war.

LG :)

PS: Interessanter Thread und vielen Dank für deine Fragestellung. Ich 
hoffe hier auch noch etwas (mehr) draus lernen zu können.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> sind im Prinzip schon 2 State-Maschines.

Das
1
Led1On = 0;
ist aber überflüssig oder?
Geht es hier mehr ums Prinzip? Also dass der eigene Zustand irgendwo 
geschrieben steht?

Karl Heinz Buchegger schrieb:
> Das ist die falsche Fragestellung.
> Denn komplett 'gegenseitig nicht beeinflussen' geht nicht.

Schade, das hatte ich gemeint. Aber deine Antworten vorher gaben ja 
genug auskunft.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

J. W. schrieb:
> PS: Interessanter Thread und vielen Dank für deine Fragestellung.

Hey, danke!
Ich überlege mir zwar immer zweimal (bis auf wenige Ausnahme) bevor ich 
was schreibe, dennoch passiert es mir zu oft, dass ich mir Fragen hätte 
sparen können.
Deshalb, danke!

von Simon K. (simon) Benutzerseite


Lesenswert?

J. W. schrieb:
> ...

Wesentlich besser ist
1
#include <util/atomic.h>
2
3
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
4
{
5
   //Hier Aktionen ausführen
6
}


Ich möchte gerne meine Stimme dafür abgeben diesen Thread oder den 
Inhalt der Beiträge von MaWin und Karl-Heinz aufgearbeitet in die 
Artikelsammlung einzubauen.
In der Hoffnung, dass es da jemand findet.

Nach vielen Jahren Mikrocontrollerprogrammierung meinerseits kann ich 
bestätigen, dass das der praxisnahe und auch in der Realität 
angetroffene Weg ist.

von Karl H. (kbuchegg)


Lesenswert?

Fabian Hoemcke schrieb:
> Karl Heinz Buchegger schrieb:
>> sind im Prinzip schon 2 State-Maschines.
>
> Das
>
1
Led1On = 0;
> ist aber überflüssig oder?
> Geht es hier mehr ums Prinzip? Also dass der eigene Zustand irgendwo
> geschrieben steht?

richtig.
Ich dachte bei mir: Wenn ich das jetzt auch noch implizit mache, dann 
entferne ich mich formal schon so weit von der SM, dass sie eventuell 
nicht mehr erkennbar ist.


>> Denn komplett 'gegenseitig nicht beeinflussen' geht nicht.
>
> Schade, das hatte ich gemeint.

Na ja.
Das ist aber auch logisch. Eine einzige µC kann nun mal nicht x Sachen 
absolut gleichzeitig machen, sondern immer nur hintereinander.

Eine weitere Ebene kommt hinzu, wenn es Resourcen gibt, die übergreifend 
von allen gemeinsam genutzt werden müssen. Zb LCD, zb UART.
Die müssen dann koordiniert werden und auch das hat Auswirkungen auf die 
Einzel-SM

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Simon K. schrieb:
> J. W. schrieb:
>> ...
>
> Wesentlich besser ist
>
>
1
> #include <util/atomic.h>
2
> 
3
> ATOMIC_BLOCK
4
> {
5
>    //Hier Aktionen ausführen
6
> }
7
>

Steht irgendwo genau beschrieben, was genau das macht?

von Simon K. (simon) Benutzerseite


Lesenswert?

Fabian Hoemcke schrieb:
> Simon K. schrieb:
>> ...
> Steht irgendwo genau beschrieben, was genau das macht?

Aber latürnich! ;-) In der Doku zur avr-libc:
http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html

Beachte, dass in dem von dir zitierten Code noch ein Fehler war, den ich 
in meinem Post herauseditiert habe.

von Oliver J. (skriptkiddy)


Lesenswert?

Fabian Hoemcke schrieb:
> Steht irgendwo genau beschrieben, was genau das macht?

Ja. Hier in der avr-libc-Dokumentation:
http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html

Gruß Oliver

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Karl Heinz Buchegger schrieb:
>>> Denn komplett 'gegenseitig nicht beeinflussen' geht nicht.
>>
>> Schade, das hatte ich gemeint.
>
> Na ja.
> Das ist aber auch logisch. Eine einzige µC kann nun mal nicht x Sachen
> absolut gleichzeitig machen, sondern immer nur hintereinander.

Ja, aber ich hatte gedacht, oder eher gehofft, dass es irgendwo ein 
Feature gibt, dass ich noch nicht kenne. Wie etwa Hardware-Threading 
oder so! (Habe ich mir jetzt ausgedacht).

Denn irgendwie muss ja der Kontroller auch die Interruptlösung 
implementiert haben. Was zu mindest der erste Schritt hin zur 
Nebenläufigkeit ist.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

@Simon K. @Oliver J. Danke!

@Karl Heinz Buchegger @All
Unfassbar was Ihr alles wisst!

_

Ohne das Forum hier, wäre Deutschland wohl nicht das Ingenieursland, was 
es ist.

^^

von Simon K. (simon) Benutzerseite


Lesenswert?

Fabian Hoemcke schrieb:
> Karl Heinz Buchegger schrieb:
>>>> Denn komplett 'gegenseitig nicht beeinflussen' geht nicht.
>>>
>>> Schade, das hatte ich gemeint.
>>
>> Na ja.
>> Das ist aber auch logisch. Eine einzige µC kann nun mal nicht x Sachen
>> absolut gleichzeitig machen, sondern immer nur hintereinander.
>
> Ja, aber ich hatte gedacht, oder eher gehofft, dass es irgendwo ein
> Feature gibt, dass ich noch nicht kenne. Wie etwa Hardware-Threading
> oder so! (Habe ich mir jetzt ausgedacht).
Hehe! :-) Das, was du als bereits vorhandenes Feature suchst ist der 
Knackpunkt, an dem gute und schlechte Programmierer sich unterscheiden.
Das Schreiben von großer Software, die wartbar bleiben soll und dabei 
eine gute Performance erzielt ist eben der Punkt, um dem es bei der 
Programmierung geht.

Und wie MaWin schon sagt, gibt es hier kein "globales Konzept", sondern 
man muss das Konzept eben passend zur Anwendung wählen.
Herausstellen welche Programmabschnitte eine hohe Priorität haben und 
das bei der Programmierung eben so vorsehen.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Simon K. schrieb:
> Hehe! :-) Das, was du als bereits vorhandenes Feature suchst ist der
> Knackpunkt, an dem gute und schlechte Programmierer sich unterscheiden.
> Das Schreiben von großer Software, die wartbar bleiben soll und dabei
> eine gute Performance erzielt ist eben der Punkt, um dem es bei der
> Programmierung geht.

Das ist klar.
Große Programme in kleine µCs packen, die dann noch schnell und 
fehlerfrei funktionieren.

Je enger und kritischer es wird, um so eher wird man gezwungen in ASM zu 
schreiben und Clocks zuzählen. ^^

Da denke ich an die sagenumwobene Geeks die bei den Demos das letzte aus 
dem C64 und Co rausholen.

Aber soweit bin ich laaaange noch nicht.

von Karl H. (kbuchegg)


Lesenswert?

> Je enger und kritischer es wird, um so eher wird man gezwungen in
> ASM zu schreiben und Clocks zuzählen. ^^

Aber Vorsicht!

Nicht immer ist der Schritt von C nach ASM notwendig, wenn sich in einem 
Programm herausstellt, dass es eng wird. Viele "Engstellen" entstehen 
nur durch ungeschickte Programmierung.

Auf Anhieb fällt mir jetzt nur das AVR-Basic Projekt aus der 
Codesammlung ein, bei dem es nicht anders geht, als einen Teil in ASM zu 
formulieren. Und das ist die Generierung des Videosignals. Das ist so 
zeitkritisch, dass es tatsächlich auf jeden einzelnen Taktzyklus ankommt 
und dann kommt man mit C nicht mehr weiter.
Aber abgesehen davon, fällt mir jetzt nichts weiter ein, was tatsächlich 
Asm erzwingen würde.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Fabian Hoemcke schrieb:
>> Karl Heinz Buchegger schrieb:
>>> sind im Prinzip schon 2 State-Maschines.
>>
>> Das
>>
1
Led1On = 0;
>> ist aber überflüssig oder?
>> Geht es hier mehr ums Prinzip? Also dass der eigene Zustand irgendwo
>> geschrieben steht?
>
> richtig.
> Ich dachte bei mir: Wenn ich das jetzt auch noch implizit mache, dann
> entferne ich mich formal schon so weit von der SM, dass sie eventuell
> nicht mehr erkennbar ist.

Um da noch mal auszuholen.

Normal würde man das wohl so schreiben
1
  ...
2
3
  while( 1 ) {
4
5
    if( get_key_press( 1 << TASTE_LINK )
6
      PORTA ^= ( 1 << LED_ROT );
7
8
    ...
9
  }

Und wenn du mir ein bischen Interpretationsspielraum zugestehst, dann 
ist auch das eine Statemaschine. Es sind alle Zutaten vorhanden.
Da ist eine "Variable", die sich den Zustand der Maschine "LED" merkt. 
Wo steckt sie? Es ist das Portbit selber, welches diese Funktion 
erfüllt. Und da die Maschine nur 2 Zustände haben kann (Led ein / Led 
aus), reicht es auch aus diesen Zustand zu toggeln und nicht explizit 
umzuschalten. Die bei einem Zustandswechsel auszuführende Aktion ist mit 
diesem Zustandswechsel gekoppelt, in dem am Portpin, welcher den Zustand 
repräsentiert, die LED hängt.
Die Maschine wechselt ihren Zustand bei auftreten eines Ereignisses, 
eben dem Tstendruck und da beide Zuständswechsel durch dasselbe Ereignis 
ausgelöst werden, kann man den vorziehen.

-> Im Grunde ist das eine "Zustandsmaschine", die allerdings so 
umgeformt und 'verfremdet' wurde, dass sie als solche nicht unmittelbar 
und direkt erkennbar ist. Aber von der Funktionsweise unterscheidet sie 
sich in nichts  von einer klassisch implementierten.

von Oliver J. (skriptkiddy)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das ist so
> zeitkritisch, dass es tatsächlich auf jeden einzelnen Taktzyklus ankommt
> und dann kommt man mit C nicht mehr weiter.

Ulrich Radig z.B. hat es in C geschafft[1].


[1] Beitrag "ATmega8 erzeugt Video in C!"


Gruß Oliver

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Nicht immer ist der Schritt von C nach ASM notwendig, wenn sich in einem
> Programm herausstellt, dass es eng wird. Viele "Engstellen" entstehen
> nur durch ungeschickte Programmierung.

Gibt es eine Liste mit Dos und Don'ts der Programmierung?
Wenn nein, gibt es jemand, der zu mindest initial eine solche Liste 
erstellen könnte?

Ich lese hier in der Werbung und auch bei Amazon von ein Haufen Büchern, 
die sich alleine mit der Programmierung von AVRs beschäftigen. Wie diese 
Evil Genius Reihe.

Oder auch:
http://www.amazon.de/gp/product/3895762180/ref=ox_sc_act_title_1?ie=UTF8&m=A3JWKAKR8XB7XF
http://www.amazon.de/gp/product/3895761761/ref=ox_sc_act_title_3

Hat die jemand gelesen? (Nicht wirklich ernst gemeint)
Steht in denen brauchbares zu diesem Thema drin?

Ich selber lese im Moment 
http://www.amazon.de/Mikrocomputertechnik-Controllern-Atmel-AVR-RISC-Familie-Programmierung/dp/3486589881/ref=pd_sim_b_1
Habe aber derartiges noch nicht gefunden.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Um da noch mal auszuholen.

Jup! Danke!

Auch wenn es bereits für mich klar war, durch deine früheren Posts, 
finde ich diese Ausformulierung super. Schön zu sehen, wie theoretische 
Konstrukte in der Praxis für Formen annehmen.
Also auch, dass sie weiterhin Gültigkeit haben.

von 123 (Gast)


Lesenswert?

Zum thema C und ASM.

lass dass lieber den C compiler machen. Wenn der C compiler nicht gerade 
vom hintern Mode kommpt wird der Sehr guten code erzeugen, den man von 
hand mit ASM fast nicht besser hinbekommt.

Bei der ASM programmierung gibt es viele teilaspekte mit zu 
berúcksichtigen.

Welche zwischenergibnisse soll man sich merken um berechnungen nicht 
unnötig doppelt zu machen.
Wo diese werte speichern? im Register oder auf dem Stack.
Wie wirken sich speicherzugriffszeiten aus? (RAM  Register  Flash)
Ist es z.B. besser irgend eine nonsens berechnung zu machen und dann das 
ergebniss wegzuschmeisen oder doch lieber einen sprung? (pipline neu 
laden)
Was ist schneller, ein code der in ASM sehr sehr gross ist, weil viele 
"Funktionen" nicht angesprungen werden sondern mit copy past immer an 
der stele wo sie benötigt werden eingabaut wuden oder der 
platzsparendere in dem der code nur einmal existert, und ein call / ret 
verwendet wird.

Wie wiren sich caches auf die speicherzugriffzeiten aus? kann man da ggf 
was tunen (code im cach vorladen / verfügbar halten)

bei kleinen MCUs wo RAM und Register gleich schnell sind, und der core 
selber keine pipline hat mag das ja noch recht überschaubar sein.

sobald register schneller anzusprechen sind als das ram, der core eine 
pipline hat und auch noch caches ins spiel kommen wird das nicht mehr 
ganz so einfach.

und von den ganz grossen brüdern reden wir mal lieber nicht.

Welche Befehlsreihenfolge ist die bessere? Thema paring von asm 
Befehlen.

von guenther (Gast)


Lesenswert?

123 schrieb:
> Zum thema C und ASM.
>
> lass dass lieber den C compiler machen. Wenn der C compiler nicht gerade
> vom hintern Mode kommpt wird der Sehr guten code erzeugen, den man von
> hand mit ASM fast nicht besser hinbekommt.
>

Bwaaahahaahahahaaaaa! Selten so gelacht - Und das nicht nur über die 
Rechtschreibschwäche!

Wieder so ein C-Jünger, der sicher auch meint, mit 'nem Spoiler und 100 
Oktan Sprit würde sein Polo schneller laufen!

Wenn es auf Geschwindigkeit oder kritisches Timing ankommt, führt kein 
Weg an Assembler vorbei!

Gruß,
Günni

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

guenther schrieb:
> 123 schrieb:
>> Zum thema C und ASM.
>>
>> lass dass lieber den C compiler machen. Wenn der C compiler nicht gerade
>> vom hintern Mode kommpt wird der Sehr guten code erzeugen, den man von
>> hand mit ASM fast nicht besser hinbekommt.
>>
>
> Bwaaahahaahahahaaaaa! Selten so gelacht - Und das nicht nur über die
> Rechtschreibschwäche!
>
> Wieder so ein C-Jünger, der sicher auch meint, mit 'nem Spoiler und 100
> Oktan Sprit würde sein Polo schneller laufen!
>
> Wenn es auf Geschwindigkeit oder kritisches Timing ankommt, führt kein
> Weg an Assembler vorbei!
>
> Gruß,
> Günni

Ich mag keine Absolutismen.
Ich wette, es gibt Gruppen von Fällen oder Problemen in denen sich 
Assembler fasst aufdrängt, und Fälle, die ebenso Zeitkritisch und 
Komplex sind, die sich aber dennoch mit C besser lösen lassen. Zum 
Beispiel, wenn die HW zu komplex ist.

Bei Java würde ich mich da aber schon aus dem Fenster legen. :D

von Karl H. (kbuchegg)


Lesenswert?

guenther schrieb:

> Wenn es auf Geschwindigkeit oder kritisches Timing ankommt, führt kein
> Weg an Assembler vorbei!

Das es derartige Fälle gibt, mag ich dir gerne zugestehen.
Aber in >90% der Fälle um die es hier im Forum geht, ist Assembler 
völlig unnötig und ob seiner langen Programme eher hinderlich, sofern 
man ihn nicht wirklich gut beherrscht.

Die Frage ist nämlich nicht, ob der Polo mit Spoiler und 100-Oktan Sprit 
schneller läuft, sondern ob er in Normalausrüstung schnell genug läuft.
Das ist ein klitzekleiner Unterschied. Um damit zum Discounter zum 
einkaufen zu fahren langt das allemal. Dazu brauch ich keine Blue Flame, 
die erst mal 5 Stunden Vorbereitungsarbeit benötigt, nur im dieselbe 
Strecke anstat von in 2 Minuten in 25 Sekunden zurückzulegen und wenn 
ich einen winzigen Fehler mache, geht der Raketenmotor 20 Meter vor dem 
Ziel hoch.

von Peter D. (peda)


Lesenswert?

Fabian Hoemcke schrieb:
> Wonach ich also im Grunde frage, gibt es eine Art Design-Pattern um
> komplexere µC-Programme (jetzt werden sicher die einen oder anderen
> lachen ;)) zu planen und zu programmieren?

Ergänzend zu dem bereits gesagten kann man noch das Prinzip der 
maximalen Faulheit nennen:
Mache Sachen nur so oft wie nötig und so spät wie möglich.

Es hat z.B. keinen Sinn, jeden neuen ADC-Wert in float umzurechnen, den 
Mittelwert zu bilden und auf das LCD auszugeben.
Besser macht man den Mittelwert in integer und rechnet erst zur Ausgabe 
nach float um.
Und kein Mensch kann alle 100µs einen neuen Wert ablesen. In der Praxis 
haben sich 2..5 Werte/s als ergonomisch erwiesen.
Also muß man die Umrechnung und Anzeige nur alle 200ms machen.

Oder man mißt eine Temperatur. Das ist ne ziemlich träge Angelegenheit, 
mehr als eine Messung alle 5..10s ist unnötig.
Das ist sogar sinnvoll, damit man den Meßkreis in den Pausen abschalten 
kann, d.h. man spart Strom und der Sensor erwärmt sich nicht selbst.


Peter

von W.S. (Gast)


Lesenswert?

Fabian Hoemcke schrieb:
> Wonach ich also im Grunde frage, gibt es eine Art Design-Pattern um
> komplexere µC-Programme (jetzt werden sicher die einen oder anderen
> lachen ;)) zu planen und zu programmieren?

Ja, eigentlich gibt es sowas schon, ich würde es aber eher 
"Herangehensweise" nennen - und da hat jeder seine Sichtweise. Das ganze 
hängt auch von den näheren Umständen ab. Bei manchen Geräten hab ich 
einen Kaltstartlader hineingesetzt, der immer im Gerät bleibt, egal, was 
für ne Firmware draufkommt und bei anderen Geräten geht es einfach so 
mit ein paar Zeilen Startupcode in Assembler und gleich danach kommt 
main().
Aber, um dir nen allgemeinen Rat zu geben, sieht main() bei mir 
prinzipiell etwa so aus:

- zuerst die allerwichtigsten Initialisierungen
- dann irgendeine sinnvolle Reaktion, damit der Benutzer sieht, daß die 
Kiste zu leben beginnt
- dann die restlichen Initialisierungen
- fast immer mache ich mir mit irgendeinem Timer eine Systemuhr, damit 
man langsame Sachen nur gelegentlich nachfragt und damit nicht sinnlos 
Systemzeit vergeudet.
- dann eine Schleife, die nie verlassen wird und wo nacheinander alles 
aufgerufen wird, was Beachtung braucht. Dabei achte ich darauf, daß 
nichts blockierend geschrieben ist.
Also nicht "wait until event arrived", sondern "if event arrived then do 
something"

my_loop:
  if (CharAvail(com1) HandleChar(GetChar(com1), 1);
  if (CharAvail(com2) HandleChar(GetChar(com2), 2);
  if (CharAvail(com3) HandleChar(GetChar(com3), 3);
  if (oldtick!=CurrentTick)
  { DoSlowFunctions();
    oldtick = CurrentTick;
  }
  und so weiter...

  goto my_loop;
}


W.S.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Peter Dannegger schrieb:
> In der Praxis haben sich 2..5 Werte/s als ergonomisch erwiesen.

Generell Danke erstmal. "Faulheit" ist sicher ein gutes Dogma.

Was die Ergonomie angeht, geht es darum, dass wenn ich z.B. einen Poti 
auslese, es doch immer Wackler gibt und die Werte dann rasch und zackig 
wechseln und es schwerer ist, den gewünschten Wert einzustellen?

@W.S. (Gast) Danke!
Vor allem für den Tipp mit dem Blocking-Mode.
Was ist aber, wenn ich etwas im Blocking-Mode abfragen oder machen muss? 
Und dann nicht nur eines? Dann bleibt mir ja nur der Non-Blocking-Mode 
und ich muss schauen, dass ich alles recht Zeitnah abgefrühstückt 
bekomme. Oder?

(Mit ist klar, dass es hier für ja schon die Interrupt-Flags gibt die 
man mit Polling oder in Intterupt-Routinen bearbeiten kann. Mir fällt 
jetzt auch leider kein gutes Beispiel an. Alles viel zu unkonkret. 
Leider.)

Gruß
Fabian

von Karl H. (kbuchegg)


Lesenswert?

Fabian Hoemcke schrieb:

> Generell Danke erstmal. "Faulheit" ist sicher ein gutes Dogma.

Und auch schnell.
Sowohl in der Programmierung als auch im Programmlauf.
"Lazy Evaluation" hat schon so manchem Projekt Beine gemacht.

> Was die Ergonomie angeht, geht es darum, dass wenn ich z.B. einen Poti
> auslese, es doch immer Wackler gibt und die Werte dann rasch und zackig
> wechseln und es schwerer ist, den gewünschten Wert einzustellen?

In erster Linie geht es darum, dass zb auch ein LCD träge ist. Von daher 
hat es keinen Sinn, dem 50 mal in der Sekunde ein Update zu geben, weil 
es gar nicht hinterher kommt. Und wenn man das dann auch noch mit der 
Methode "LCD löschen, neu hinschreiben" macht, dann flimmert das wie 
verrückt und man kann erst recht nichts lesen.

Wenn du einen Benutzer hast, dann folgt aus dieser simplen Tatsache, 
dass die I/O Sachen langsam sein können. Menschen sind langsam. Sowohl 
was Ablesen als auch einstellen betrifft.

>
> @W.S. (Gast) Danke!
> Vor allem für den Tipp mit dem Blocking-Mode.
> Was ist aber, wenn ich etwas im Blocking-Mode abfragen oder machen muss?

Kann nicht sein. Du 'musst' eben nicht blockend abfragen. Das kannst du 
ruhig als Dogma ansehen. Bei einer UART muss man eben vorher nachfragen, 
ob ein Zeichen da ist. Aber gewartet wird nicht (ausser vielleicht ganz 
kurz). Grundsätzlich. Auf nichts und niemanden. Was im jetzigen 
Durchlauf durch die Hauptschleife nicht fertig ist, muss eben bis zum 
nächsten Durchlauf warten. (*)

Wenns gar nicht anders geht, dann muss man eben das Gerät wegwerfen, 3 
mal heftig fluchen und einen anderes Gerät kaufen, welches eine 
getrennte Abfrage ermöglicht. Im AVR kann man jegliche Hardware immer so 
benutzen, dass man nicht warten muss (oder wenn, dann nur sehr kurz - zb 
ADC)

(*) eine Ausnahme wäre zb I2C in Software, bei dem du am Timing nichts 
machen kannst. Aber da sind wir im Bereich: kurz warten.

von Peter D. (peda)


Lesenswert?

Fabian Hoemcke schrieb:
> Was die Ergonomie angeht, geht es darum, dass wenn ich z.B. einen Poti
> auslese, es doch immer Wackler gibt und die Werte dann rasch und zackig
> wechseln und es schwerer ist, den gewünschten Wert einzustellen?

Keine Regel ohne Ausnahme. Während des Einstellens kann man natürlich 
die Rate erhöhen, z.B. auf 50ms.


Peter

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Hey!

Danke erstmal an alle für die tollen Beiträge.

Abschließend kann ich sagen, dass es sicher ein paar Prinzipien gibt, 
die man je nach Fall verfolgen kann, aber eine Ansammlung von 
Design-Pattern wie ich sie aus der Objekt Orientierten Programmierung 
kenne gibt es wohl nicht.

Es gibt kleine Lösungen für immer wiederkehrende Fälle, wie etwa das 
Entprellen von Tastern, aber nicht für komplexere Probleme. Vermutlich 
schießt man dann auch schon über die Lösung mit einem µ C über das 
Ziel hinaus.

Vielen Dank
Fabian

von Peter D. (peda)


Lesenswert?

Fabian Hoemcke schrieb:
> aber eine Ansammlung von
> Design-Pattern wie ich sie aus der Objekt Orientierten Programmierung
> kenne gibt es wohl nicht.

Der Grund ist ganz einfach, daß eine MC-Schaltung nicht standard ist.
Es gibt viele tausende MCs und viele tausende ICs, die man auf viele 
verschiedene Wege an den MC anschließen kann und haufenweise 
Programmiersprachen dazu.
Es gibt somit Billiarden Möglichkeiten, etwas zu realisieren. Und daher 
ist es unmöglich, Billiarden Bibliotheken vorrätig zu halten und zu 
verwalten.

Schon um ein Standard-LCD (Text oder Grafik) an einem AVR zu betreiben, 
kann man es spielend auf 1000 Bibliotheken bringen, je nach Typ, Format, 
Interface, Funktionen, gepuffert/ungepuffert, Interrupt/nicht Interrupt 
usw..


Peter

von GoP (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Fabian Hoemcke schrieb:
>> aber eine Ansammlung von
>> Design-Pattern wie ich sie aus der Objekt Orientierten Programmierung
>> kenne gibt es wohl nicht.
> Der Grund ist ganz einfach, daß eine MC-Schaltung nicht standard ist.

Welche Softwareloesung ist das?

> Es gibt somit Billiarden Möglichkeiten, etwas zu realisieren. Und daher
> ist es unmöglich, Billiarden Bibliotheken vorrätig zu halten und zu
> verwalten.

Design-Patterns haben mit Bibliotheken gar nichts zu tun. Sie sind auch 
nicht auf Software-Loesungen beschraenkt. Design-Patterns werden 
manchmal mit "Kochrezepte" uebersetzt und das trifft den Nagel auf den 
Kopf. Wenn dir Jemand erzaehlt, wie er eine Mehlschwitze fuer eine 
dunkle Sosse macht, dann ist das ein Design-Pattern und keine 
Bibliothek, wie der Sossenbinder aus der Tuete. Und noch etwas wichtiges 
zeigt dieses Gleichnis - es ist gut, viele Design-Patterns zu kennen und 
es ist noch besser, wenn man ohne kochen kann.

von MaWin (Gast)


Lesenswert?

> aber eine Ansammlung von Design-Pattern wie ich sie aus der
> Objekt Orientierten Programmierung kenne gibt es wohl nicht.

Die gibt es schon, in Lehrbüchern über SPS,
in irgendeinem Lehrbuch über den Z80 das ich habe aber nicht mehr finde,
bloss hat man das damals noch nicht so genannt,
denn wie geschildert: Die Wortwahl ändert sich alle 10 Jahre,
damit die nachfolgende Generation den Eindruck so voll top modern zu 
sein,
wenn sie den alten Wein in neuen Schläuchen säuft.

In der Realität sind Design Patterns der Ersatz von mangelnder 
Intelligenz durch massives Auswendiglernen, denn genau darauf käme es 
an: Eine Vielzahl von Design Patterns zu kennen mit ihren jeweiligen 
Nachteilen (die nie beschrieben werden sondern die man schmerzhaft 
erfahren müsste) und Vorteilen, damit man sie beim aktuellen Problem 
gegenüberstellen könnte um das bestpassende auszuwählen.

Da ist der Weg über Intelligenz klar der einfachere, insbesondere bei uC 
die von Haus aus nicht so besonders komplex sind und deren Aufgaben in 
99% der Fälle von simpelster Natur sind. Wenn einen natürlich schon 
nebenläufige Prozesse (auch so ein Design Pattern) verwirren, können 
auch uC schwer genug erscheinen.

von Karl H. (kbuchegg)


Lesenswert?

> aber eine Ansammlung von Design-Pattern wie ich sie aus der Objekt
> Orientierten Programmierung kenne gibt es wohl nicht.

Design Patterns kannst du natürlich verwenden. Aber oft ist das 
Overkill. Du darfst nicht vergessen, dass wir uns auf kleinen µC 
bewegen, die nicht über die Kapazität und die Rechenpower von Desktop 
Systemen verfügen. Auch benötigt man oft die Felxibilität nicht, die in 
Design Pattern steckt.

Gegebenenfalls muss man das Pattern vielleicht etwas vereinfachen. Aber 
im Grunde spricht nichts dagegen zb ein Visitor Pattern einzusetzen.

von Karl H. (kbuchegg)


Lesenswert?

> In der Realität sind Design Patterns der Ersatz von mangelnder
> Intelligenz durch massives Auswendiglernen

So krass würde ich das nicht ausdrücken. Design Pattern giessen einfach 
Strukturen, die sich bewährt haben, in eine Form, so dass nur das für 
das jeweilige Pattern charakteristische Verhalten übrig bleibt. Ein 
"Design Pattern" ist einfach nur ein Name für eine Programmstruktur, so 
wie eine spezifische "Datenstruktur" (Liste, Baum) ein Name für eine 
spezifische Datenorganisationsform ist. Ein paar typische Design Pattern 
für Standardaufgaben zu kennen, schadet nicht.

Aber im Grunde hast du recht. Das ist nichts neues, nur weil es 
heutzutage Design Pattern heißt. Neu ist lediglich, dass die 
Programmstrukturen aufs wesentliche reduziert und einen Namen bekommen 
haben.

von Mischmasch (Gast)


Lesenswert?

Natürlich gibt es auch Leute, die bei Embedded-Systemen auf der 
Design-Pattern Welle mitreiten wollen oder wollten.

Da werden zum Beispiel 1000 Seiten Abhandlungen wie diese geschrieben 
http://www.tte-systems.com/books/pttes (warum wundert es mich nicht, 
dass das von einer Consulting-Bude kommt?) und nachdem es als Buch nicht 
mehr so gut läuft verschenkt.

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.