Forum: Mikrocontroller und Digitale Elektronik Werkzeuge für komplexe Programme!


von Martin (Gast)


Lesenswert?

Hallo!

Ich bin gerade etwas ratlos und deshalb wende ich mich an das Forum.
Ich weiß nicht wie ich weitermachen soll.
Folgendes:
Wir bauen in der Firma ein ziemlich komplexes Gerät. Es hat wie alle
Geräte sehr klein angefangen. Doch es wurde ständig erweitert. Es
beinhaltet Schrittmotoren, diverse Taster für Klappen, die man öffnen
kann, einen Ein-,Ausschalter, ein Display, Temperatursensoren, Sensoren
für Helligkeit, diverse Mosfets zum Schalten von Geräten, USB-Verbindung
zum Computer und UART-Kommunikationen innerhalb des Gerätes. Leider darf
ich nicht mehr verraten.

Wir benutzen hierfür einen ATMEGA128. Man kann sich vorstellen, dass
das Programm, welches diese ganzen Steueraufgaben übernehmen muss
relativ komplex ist, noch dazu dann, wenn sehr viele verschiedene
Komponenten in verschiedenen Statuszuständen des Gerätes verschiedene
Reaktionen auslösen können. Manche Komponenten (z.B. Taster oder andere
Sensoren) müssen hierbei höhere Prioritäten haben als andere.
Dann muss der µP ständig auf Anfragen des PC's antworten können und
auf diese vielen Ereignisse richtig reagieren.

Hier kann man erkennen, dass das Programm sich ständig verändert und
wächst. Dadurch war es nicht möglich von Anfang an ein entsprechendes
Programmkonzept zu entwickeln. Aus diesem Grund können manche
Erweiterungen nur noch relativ umständlich eingebaut werden. Dann
leidet aber wieder die Übersichtlichkeit des Programmes. Diese
Übersicht zu behalten war ab einem gewissen Zeitpunkt nicht mehr
möglich, besonders deshalb nicht, weil man dann mal wieder ein paar
Monate lang an anderen Projekten arbeitete. Auch die
Aufgabenstellungen, die vorher genügten müssen ausgebaut werden.
Dadurch sind manche Konzepte, die im Programm realisiert sind nicht
mehr anwendbar und müssen neu erdacht werden.

So wie das Gerät jetzt aufgebaut ist funktioniert es mit der Software
einwandfrei. Das Problem ist jetzt die Übersicht wiederzufinden,
nämlich das Konzept soweit zu vereinfachen und zu verändern, dass
Erweiterungen wieder einfacher möglich sind.

Ich programmiere mit CodeVision AVR (C) und bis jetzt ist jedes
Programm im Kopf entstanden und daraus nach und nach immer mehr Code
enstanden. Bis jetzt hat das recht gut funktioniert, da sich die
Programme im Rahmen gehalten haben. Aber das ist jetzt nicht mehr der
Fall.

Gibt es hierfür irgendwelche Werkzeuge, um solche Programmkonzepte
planen zu können, um die Übersicht zu behalten? Oder wie soll man in
diesem Fall am besten vorgehen? Das Proramm völlig neu zu schreiben
wäre, so glaube ich, zu aufwändig. Es sind auch manchmal Ideen
realisiert, die im Programmcode nicht mehr als solches erkennbar sind.
Ein Kompromiss wäre die Veränderung des Programmes. Es enthält einige
Funktionen, die man so lassen kann.
Die Namen der Variablen könnte man etwas besser wählen. Habt hier
hierfür Vorschläge?

Ich danke euch für jede Antwort.
Wie machen die richtigen Profil solche Programmkonzepte?

Tschüss
Martin

von Steffen (Gast)


Lesenswert?

Hallo Martin,

für Programmkonzepte werden umfangreiche Dokumentationen erstellt.
Diese setzen sich meist aus Flussdiagrammen etc. zusammen.

Im Softwarebereich für PC Programme hat sich hier die UML durchgesetzt.
(UML = Unified Modeling Language). Diese kann arbeitet vor allem mit
Klassen (welche bei uC nicht verwendet werden - zumindest nicht in
dieser Größenordnung).

Ein Programm, mit dem man viele Ablaufdiagramme erstellen kann (auch
UML) wäre zum Beispiel Microsoft Visio.

Viele Grüße
Steffen

von Ralf (Gast)


Lesenswert?

Hallo,

such' mal nach Poseidon UML. Das ist ein freies UML-Tool. Zumindest
die Community Edition. UML lässt sich auch relativ gut auf uCs anwenden
um den Überblick zu wahren. Besonders die Statemachines sind ganz
interessant wenn man Steuerungsaufgaben erledigen muss.
Das wichtigste ist allerdings die Doku!

Viele Grüße,

Ralf

von Oryx (Gast)


Lesenswert?

Hallo Martin,
ich bin mir nicht sicher, ob bei Deiner Problematik eine noch so gute
Doku weiterhilft.
Nach zwei oder drei Erweiterungen ist sie veraltet.

Meine Projekte setzen sich aus etwa hundert Dateien zusammen.

Ich verwende einen vernünftigen Editor (UltraEdit)
dazu das Tool CTAG, zum suchen von Funktionen in anderen Dateien
dann einen vernünftigen Compiler (GCC)
als Programiersprache C++ und kein C
eine Versionsverwaltung (CVS) ist auch ganz hilfreich

warum diese Kombination?
Editor und CTAG zum navigieren in vielen gleichzeitig geöffneten
Dateien
GCC wegen den gut zu steuernden Fehlermeldungen und Warnungen
C++ wegen der Kapselung

Es sind alles relativ einfache Tools, die Übersicht kommt nur aus einer
sinvollen Organisation der Quellcodes. Dateinamen und Verwendung von
Verzeichnissen.

Allgemeine Regeln:
keine globalen Variablen
alles was zusammen gehört, in ein Modul
möglichst klare Regeln, um einzelne Steuerungen zu starten und zu
beenden.
Sinnvolle Funktions- und Variablennamen
soviele lokale Variablen wie möglich
alle Warnungen einschalten und auch beachten(Warnungen als Fehler
werten)
zu jedem Modul eine kurze Beschreibung
zu jeder Funktion eine kurze Beschreibung
zu jeder globalen Variablen eine kurze Beschreibung
wenn möglich new und delete vermeiden
verwende einen möglichst einfachen Programierstil, der Kompiler
optimiert für dich.

Bei Deiner Programmgrösse ist eine Überarbeitung der Programmstuktur
nie auszuschliessen. Bei einer langen Entwicklungsphase kommt es zu
einschneidenen Änderungen und auch zu einer eigenen Weiterentwicklung.
Die alte Erfahrung: Hinterher ist man immer schlauer. Aber bei Dir ist
hinterher auch schon wieder vorher. Also nutze Deine Weiterentwicklung.
Auch wenn es erst mal viel Arbeit macht.

Solltest Du ein Tool finden, das Dir weiterhilft, teile es mir bitte
mit.

Oryx

von thkais (Gast)


Lesenswert?

Hm - irgendwie kommt mir das bekannt vor. So ein Projekt habe ich
momentan auch am Bein, so halbjährlich kommen neue Ideen und man muß
dann den eigentlich lauffähigen Code "verschlimmbessern".
Zunächst einmal das Wichtigste: Der Kunde / dafür Verantwortliche muß
dahin gedrängt werden, sich endlich einmal zu entscheiden, was das
Gerät wirklich können soll. Es ist immer schwieriger, in einem
bestehenden Code eine neue Funktion zu implementieren, als dies von
vornherein zu planen. Der Hinweis auf die Mehrkosten ist meistens eine
"Entscheidungshilfe". Sollte dies nicht möglich sein, hast Du mein
ganzes Mitgefühl ;-)
Ansonsten gibts nur, wie schon erwähnt, folgendes zu beachten:
- Gute Dokumentation
- Gute Dokumentation
- Wichtig: Gute Dokumentation.
Flußdiagramme und ein Kommentar : Codeverhältnis von min. 3:1 sind zwar
bei der Erstellung aufwendig, aber gerade dann, wenn man selbst (oder
jemand anders) sich in dieses Projekt (wieder) hineinarbeiten muß,
spart man diese zusätzlich investierte Zeit vielfach wieder ein.

von Hermann (Gast)


Lesenswert?

Hallo Martin,

irgendwie kämpft jeder mit dem Problem, dass das Programm und die Ideen
im Kopf schneller wachsen als die Dokumentation.
Ich bemühe mich zwar zumindest die Prototypen im Header entsprechend zu
kommentieren, wenn es aber dann eilt, bleibt die Doku manchmal doch
wieder auf der Strecke.  :-(

Ich verwende das Tool „doxygen“ (www.doxygen.org, GNU-Lizenz).
Damit kann man aus dem Sourcecode eine prima HTML-Doku seines Projekts
erzeugen.
Man benötigt dazu lediglich ein Paar Schlüsselwörter im Kommentar.
So hat man immer auf Knopfdruck eine aktuelle Dokumentation zur
Verfügung. (Vorausgesetzt die Kommentare im SRC-Code sind aktuell!)

Darüber hinaus  kann ich mich Oryx nur anschließen mit der
Einschränkung, dass man auch mit C objektorientiert und gekapselt
programmieren kann.
(Kapselung ist überhaupt kein Thema bei C, bei Vererbung wird’s schon
etwas problematischer.)


Als UML Tool möchte ich „ArgoUML“ (http://argouml.tigris.org)
einsetzen.
Hab allerdings noch kaum Erfahrungen damit.


Prinzipiell ist zu UML-Tools zu sagen, dass sie ihr volles Potential
erst ausschöpfen, wenn man damit sowohl aus dem Modell Code erzeugen
kann und evtl. eigenen Code auch in das Modell übernehmen kann. Diese
Tools kosten allerdings dann meist auch eine Menge Geld.

Verwendet man UML nur als reines Dokumentationswerkzeug, hat man häufig
das Problem, dass Modell und Implementierung nicht übereinstimmen.

Hermann

von Ralf (Gast)


Lesenswert?

Hallo,

was vielleicht auch noch ganz gut ist, ist das Programm Source Insight.
Mit diesem Programm kann man einmal codieren und zum anderen kann man
sich auch ganze Aufrufbäume anzeigen lassen um zu sehen, wie alle
Funktionen zusammenhängen.
Bei den Erweiterungen ist es natürlich klar, dass damit ein Mehraufwand
verbunden ist. Auf der anderen Seite merkt man dann auch, ob das
Systemdesign passt oder nicht. Das heißt am besten immer erst mal viele
Gedanken an einem guten und flexiblen Konzept verwenden. Dann hat man
später immer weniger Probleme wenn Änderungen dazukommen, was ja
eigentlich normal ist. Welcher Kunde weiß denn schon vorher was er will
;-) Datenkapselung/Modularisierung und definierte Schnittstellen helfen
hier schon sehr weiter.

Viele Grüße,

Ralf

von Joline (Gast)


Lesenswert?

Hallo,

kennt jemand ein gutes und freies UML-Tool, das auch ANSI-C Code
erzeugen kann?

von Ralf (Gast)


Lesenswert?

Hallo,

meine Erfahrung ist, dass der von den Tools erzeugte Code recht
aufwendig ist. Ich halte das ganze also eher für PC-Software für
richtig anwendbar. Gibt's da andere Erfahrungen?

Ralf

von Peter D. (peda)


Lesenswert?

Wichtig für eine gute Erweiterbarkeit ist eigentlich nur, daß alle Tasks
kooperativ geschrieben sind.
D.h. sie dürfen:
- keine Rechenzeit mit Warteschleifen vernichten
- nicht zuviel am Stück machen
- keine Ressourcen exklusiv belegen
- möglichst wenige globale Variablen belegen.

Und für die Ressourcen (Timer, ADC) sind separate Treiber zu erstellen,
die die Verwendung durch mehreren Tasks gestatten.

Z.B. statt eine Timer zu stoppen läuft er ständig durch und die
Funktion, die eine Zeitverzögerung benötigt macht das über die
Differenzzeit.
Sind viele verschiedene zeitgesteuerte Prozesse gleichzeitig nötig,
lohnt sich auch der Einsatz eines Schedulers.

Und auch extra Treiber für Tastenentprellung, LCD-Ausgabe und andere
zentrale Dinge.


Dann ist es eigentlich ganz leicht ein bestehendes Programm fast
beliebig zu erweitern.


Peter

von Philipp Sªsse (Gast)


Lesenswert?

Ich habe mal eine Fortbildung zu dem Thema besucht ("agile
Embedded-Programmierung" oder so). Fazit: Objektorientierung und UML
mit code generation lohnen sich heute auch im µC-Bereich. Der Overhead
ist gar nicht so gewaltig gegenüber dem eines typischen gewachsenen
Code-Chaos mit einer Krücke hier und einer Krücke da. Im Zweifelsfall
lieber den nächst-größeren Controller nehmen (bei Dir natürlich blöd,
weil Du schon beim Flaggschiff der Baureihe angelangt bist und somit
die Plattform wechseln müßtest).

Meine Erfahrungen damit: tolle Sache für ein neues Projekt, aber in der
Praxis müßte man bei fast null anfangen, um ein gewachsenes Projekt
damit zu entwirren. Die Zeit hat/bekommt man im Normalfall nicht, weil
dringend noch zeitaufwendige Änderungen am alten Code zu machen sind --
ein Teufelskreis. Wie mit dem Holzfäller, der keine Zeit hat, seine Axt
zu schärfen, weil er erst sein Tagespensum schaffen muß, was so lange
dauert, weil seine Axt so stumpf ist ...

Ich habe den von meinem Vorgänger "geerbten" Code nach und nach
aufgeräumt; dabei ist er trotz erheblich erweitertem Funktionsumfang
von über 400 kB auf 130 kB geschrumpft und hat weniger "seltsame
Nebenwirkungen". Trotzdem wünsche ich mir immer noch, ich hätte lieber
bei null richtig angefangen!

Ich drücke Dir die Daumen, daß Du es schaffst!

von Martin (Gast)


Lesenswert?

Hallo!

Ich danke euch für eure großartigen Denkanstöße.

Ich werde versuchen, den einen oder anderen Tipp auszuprobieren und
anzunehmen.

Tschüss
Martin

von Gregor Knappik (Gast)


Lesenswert?

Hallo Martin,

wie andere hier schon erwähnten ist eine Doku unerlässlich.
Generell sollte man sich an einen Development-Zyklus halten,
z.b. den bei großen Unternehmen verwendeten V-Zyklus.
Dabei erstellt man erstmal eine Software-Requirement, quasi was soll
diese überhaupt können. Beschreibt das grobe Thema, und arbeitet sich
in Details voran. Danach folgt die Software-Architektur und Design,
sprich welche Interfaces gibt es, welche Module kommunizieren
miteinander, Programm-Ablauf-Pläne, Beschreibung der State-Machine etc.
Erst jetzt sollte man mit dem Programmieren beginnen, wenn alle Details
abgeklärt und abgesegnet worden sind. (der Kunde kann sich danach z.b.
nicht mehr herausreden wenn er sagt: "das teil soll aber auch dies
machen können"). Die erstellten Requirements helfen dann auch, einen
Testplan zu erstellen.

Was man sich noch unbedingt abgewöhnen (oder nie angewöhnen) sollte,
für alles erdenkliche sog. "Compiler-Switches" zu verwenden, also
#ifdef's etc.
Ich habe derzeit eine Clean-Up Study durchzuführen eines ca. 15Jahre
alten Codes, und um den Ablauf verstehen zu können, bleibt mir nur noch
übrig ihn Schritt-Für-Schritt zu debuggen. Da bin ich schon seit Wochen
dran.

Weiterhin, ist es wichtig, wirklich alles was zusammengehört, in ein
Modul zu packen. Also z.B. hardwarenahe Routinen zu einem Low-Level
Module, und dazu ein High-Level Module für den "ANwender".

Als Tools für die DOkus empfehle ich MS Visio für Flussdiagramme etc.
MS Word tut den Rest ;)

Doxygen ist mit einem Add-ON namens "Graph-Viz" oder "Vis" sehr
hilfreich, um einen Überblick der Beziehungen zwischen verschiedenen
Dateien (C) oder Klassen (C++) zu bekommen.
Es erstellt "UML-Ähnliche" grafische(!) Skizzen und erstellt eine
Doku daraus, durch die man vollständig Navigieren kann. PDF, RTF, HTML
etc. sehr viele Formate werden unterstützt.

Was bei jeder Entwicklung nicht fehlen darf, ist eine
Versionsverwaltung. Ich nehme da SubVersion, es ist Datenbankbasiert
und erzeugt sehr wenig OVerhead. WIchtig ist aber, dass man wirklich
nur Source Files zur Versionsverwaltung heranzieht, nicht irgendwelche
Debug Files etc., da diese ja eh bei jedem COmpile neu generiert
werden. Es bietet komfortable Benutzerumgebung, die sich
im WindowsExplorer einbettet. Ein neues Projekt aufnehmen geschieht
einfach mit rechtem Mausklick auf Ordner, und dem entsprechenden
COmmando. "Auschecken" geht genauso einfach.
Der Backup geht sehr einfach, die Datenbankdatei komprimieren (am
besten mit bzip2) und auf CD Brennen.

Für Dich würde ich folgendes VOrgehen empfehlen:
Schreibe eine CleanUp-Study, also quasi einen Auftrag an Dich selbst.
Danach erstelle die Requirements an die Software, ein Design und einen
Testplan und sprich mit allen Mitarbeitern die irgendwie etwas mit dem
Projekt zutun haben. Wenn alles umfassend abgeklärt ist, fange das
Redesign an. Gehe wie oben beschrieben, modular vor. Benutze die
Versionsverwaltung täglich, sprich jeden Tag einchecken.
Du glaubst gar nicht wie oft man sich wünscht, einen bestimmten Schritt
rückgängig machen zu können.

Hoff Dir helfen diese Anregungen ein wenig.
Gruß

von Martin (Gast)


Lesenswert?

Hallo.

Schade ist, dass ich nur C kann. C++ haben wir in der Schule mal so in
2 Einheiten theoretisch durchgenommen. Darum kenne ich C++ von der
Struktur her nicht wirklich.
Wir machten nur so ein kleines Beispiel mit einem Baum, den man
vererbte. Mehr leider nicht.

Leider haben wir auch im Bereich Programmplanung usw. nur in ganz ganz
groben Ansätzen was gemacht (Einmal kurz auf der Tafel).
Ich war aber kein Schüler, der den Unterricht einfach so an sich
vorbeilaufen ließ, besonders im Bereich Programmierung entging mir
nichts.

Um mal das Problem mit den globalen Variablen zu lösen.
Ich habe genau das Problem, dass es bei mir immer zu viele sind.
Man hat die dann ganz oben stehen und weiß eigentlich gar nicht mehr wo
die eigentlich überall verwendet werden.
Ein Beispiel, warum bei mir die globalen Variablen immer zuviel
werden:
Alle Motoren werden mittels IRQ-Timerroutine gesteuert. Um jetzt einen
Motor beim Start auswählen zu können, benötige ich schon wieder eine
globale Variable, damit in der IRQ-Routine die Steuerroutine für den
richtigen Motor aufgerufen werden kann.
Oder:
Eine Timerroutine fragt im 100ms-Abstand Taster und Schalter ab oder es
werden Variablen in dieser Routine hochgezählt, die für spätere
Ereignisse verantwortlich sind. Z.B. Automatisches Abschalten nach
einer gewissen Zeit.

Hier liegt die eigentliche Unübersichtlichkeit begraben: Also das
Zusammenspiel zwischen Hauptprogramm und IRQ-Routinen.
Durch die IRQ-Routinen hat man das Problem, dass alles so
auseinandergerissen ist.

Könnt ihr mir in diesem Zusammenhang bitte Tipps geben?


Tschüss
Martin

von Andreas Schwary (Gast)


Lesenswert?

Du koenntest z.B. eine Liste erstellen in die sich die Komponenten
(Tastaturtreiber, Motortreiber) mit den benoetigten Aufrufintervallen
eintragen koennen (Pseudocode):

void keys_init(void) {
  timer_register_periodic_task(keys_debounce, 100);
}

Damit weiss dann die Interruptroutine dass die Funktion keys_debounce
alle 100 ms aufgerufen werden will. Das hat u.a. den Vorteil dass du
nicht in der Int.routine herumbasteln musst wenn du die Intervalle
aendern oder Komponenten hinzufuegen willst.

Evtl. koennte auch ein einfaches kooperatives Multitasking oder gleich
ein fertiges OS sinnvoll sein (da gibt's fuer AVR auch einiges zur
Auswahl).

von Daniel D. (daniel1976d)


Lesenswert?

wie waere es mit einem RTOS... ich fand das immer recht hilfreich...

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.