Hallo,
ich habe folgendes Problem ich muss eine etwa 18.000 Byte große
Applikation so verändern, dass sie in einen 16K Controller reinpasst.
Einen Punkt zur Einsparung habe ich schon gefunden:
Es gibt 3 Module die doppelt vorhanden sind.
Derjenige der den Code erstellt hat, hatte die tolle Idee für 2 mehr
oder weniger unabhängige Kanäle separate Steuerungs- und
Überwachungsmodule zu erzeugen.
Im Code sieht das dann etwa so aus:
Steuerung1.c:
1
charStatus1;
2
charGrenzwert1;
Steuerung2.c:
1
charStatus2;
2
charGrenzwert2;
Diese Kanal-Codierung im Namen zieht sich durch die komplette
Applikation.
Meine Idee ist nun jeweils das redundante Modul zu entfernen und für
jede Variable ein Array anzulegen, dass im Moment 2 Elemente fassen
kann...
Hat jemand schon Erfahrung mit sowas? Oder weiß auf was man hier
besonders achten muss?
Wie gesagt muss man hier sehr stark in den Code eingreifen: in die
zentralsten Schnittstellen des Systems. Schätzungsweise muss hier sehr
viel geändert werden.. ausserdem sind die Module untereinander nicht gut
gekapselt, was heißt das es extrem viele Schnittstellen gibt ...
Schon mal vielen Dank!!!
und ein schönes WE :-)
Ha. Ja. Dann mach mal... wir koennen da glaub nicht helfen. Fuer
wieviele 1000 stueck soll die arbeit denn gemacht werden ? Alternativ
koennte man sich mal nach einem 32k Controller umschauen und sich die
Arbeit sparen...
Ohne den Quellcode und ohne CPU und Compiler zu kennen, ists schwer,
Tips zu geben.
Schau ins Assemblerlisiting, wo der Compiler große Codemonster erzeugt
und versuche dann sowas in Unterprogramme auszulagern, wenn es oft
benötigt wird.
Peter
>Hat jemand schon Erfahrung mit sowas?
Bestimmt.
>Oder weiß auf was man hier besonders achten muss?
Das das Programm hinterher das selbe macht wie vorher. Und das ist auch
die Strategie - Programm alt und Programm neu Schritt für Schritt im
Debugger vergleichen.
Oliver
@1234:
Mir ging es hier eher um Konzepte wie man sowas am besten anpacken kann.
Z.B. wie Peter geschrieben hat Teile in Unterfunktionen auslagern, aber
sowas sind doch schon tiefergehende Eingriffe wo man unter Umständen das
Timing kaputt machen kann..?
Der Code läuft bereits Serienmäßig auf einem 32k Controller. Aber aus
Kostengründen soll er auf einen 16K Flash Controller runter.
Bisherige Codegröße (ohne Optimierungen, 2 Kanäle aktiv): ca. 18.000
Byte
Codegröße (1 Kanalversion, 2 Kanal durch Compilerschalter deaktiviert):
ca. 15.700 Byte.
@Peter Dannegger
CPU ist ein HCS08 (Freescale)
Compiler ist der Cosmic Compiler 68hc08
Ziel ist es nun die 2 Kanalversion auf etwa die Größe der 1 Kanalversion
zu bringen OHNE die Funktion zu ändern. Also tatsächlich nur
Optimierungen.
Für Kanal 1 und Kanal 2 gibt es jeweils 2 Überwachungsmodule und 1
Steuerungsmodul.
Die Steuerungsmodule sind etwa funktional zu 90 % identisch (bis auf die
Namensbezeichnung x1x... x2x..)
Für die übrigen 10 % muss ich dann wohl Sonderbehandlungen einbauen wie
gesagt OHNE was an der Funktion zu ändern. Da muss man dann sehr
akribisch und ordentlich vorgehen..
Vielleicht hat das ja jemand schon mal bei einem größeren Projekt machen
müssen, also Re-factoring... und weiß was für Tricks es da gibt..
Natürlich muss ich immer genau wissen was ich da tue und nicht einfach
blind "Find & Replace".. .das is mir auch klar.
Mein Ziel ist etwa so eine Schnittstelle:
1
//vorher:
2
Steuerung_1_Funktion();
3
4
Steuerung_2_Funktion();
5
6
// danach
7
Steuerung_Funktion(enum_kanalKANAL);
durch Sonderbehandlungen hole ich mir ja auch mehr Overhead wieder ins
Boot und das will ich ja vermeiden...
An der Steuerung_1 sind etwa 5 weite Module inkludiert.
Diese haben in sich wieder jeweils separate Variablen für Kanal 1 und
Kanal 2...
mein erster Schritt, habe ich mir gedacht, wäre also jetzt erstmal diese
Low Module zu nehmen (wie Analogwert Erfassung) und hier auch jeweils 2
Variablen ein Feld zu machen.. über das dann mit einem Index (Kanal 1 /
Kanal 2) zugegriffen wird..
ist dieses modul fertig... kommen die übrigen 4 dran.. und wenn die
fertig sind, packe ich das große Steuerungsmodul an.. und vereinheitlich
hier alles, ohne große Sonderbehandlungen.. so weit möglich..
Falls eine aufritt habe ich mir das so überlegt:
1
if(KANAL==KANAL_1){
2
// Sonderbehandlung 1a
3
}
4
else
5
{
6
if(KANAL==KANAL_2){
7
// Sonderbehandlung 1b
8
}
9
}
usw.
Was haltet ihr von dem Vorgehen???
Vielen Dank!!
schobbe wrote:
> Bisherige Codegröße (ohne Optimierungen
Du meinst damit hoffentlich nicht -O0.
Wenn ein Programm nicht mit -Os läuft, ist irgendwas faul (z.B.
fehlendes volatile).
> Die Steuerungsmodule sind etwa funktional zu 90 % identisch (bis auf die> Namensbezeichnung x1x... x2x..)
Dann sollte es möglich sein, die Variablen pro Kanal in ein Struct
zusammenzufassen und dann der gemeinsamen Funktion nur den Pointer
darauf zu übergeben.
Peter
P.S.:
Deine Größenangaben sind auch das Binary, d.h. nicht das Hex oder
S-record?
Peter wrote:
>Du meinst damit hoffentlich nicht -O0.>Wenn ein Programm nicht mit -Os läuft, ist irgendwas faul (z.B.>fehlendes volatile).
Nee, also volatile ist schon nötig, so viel optimiert der Compiler dann
anscheinend schon :)
>Dann sollte es möglich sein, die Variablen pro Kanal in ein Struct>zusammenzufassen und dann der gemeinsamen Funktion nur den Pointer>darauf zu übergeben.
Wie meinst du das? Kannst du das ein bissel konkreter beschreiben?
Welchen Vorteil hätte ein struct mit Pointer Übergabe gegenüber einer
Array-Variante? Also jede bisherigen redundanten Variable durch ein
Array mit 2 Elementen zu ersten?
>P.S.:>Deine Größenangaben sind auch das Binary, d.h. nicht das Hex oder>S-record?
Die Größenangaben stammen aus dem Mapfile. Also ich habe die genutzen
Flash-Bereiche zusammen addiert. Dort wird ja auch aufgelistet, wieviel
Flashspeicher jedes Modul benötigt.
Stefan
Den Vorteil mit den structs und den Pointern gegenüber den Arrays hab
ich immer noch nicht ganz verstanden.
Könntest du das ein bisschen genauer erklären?
Danke !
Diese Struct-Sache geht in Richtung Objektorientierung: Daten stehen im
Zentrum und Funktionen, die mit diesen Daten was machen. Und welches
Objekt (struct) nun konkret manipuliert werden soll, sagt dir der
Pointer auf das konkrete Objekt.
Sonderbehandlungen find ich immer Murks, dann lieber das herausfinden,
was funktionell identisch ist und nur auf andere Daten/Objekte
angewendet wird. Oder auch in Richtung abstrakte Klassen und
Konkretisierungen schauen.
Auch wenn du normal C programmierst, kannst du sehr objektorientiert
denken und vieles davon in diese Richtung umsetzen.
Nochwas, du kannst auch ein Array anlegen, in denen du mehrer
struct-Variablen ablegst. So sparst du dir aber die Sache, für jede
Variable ein neues Array anlegen zu müssen, zumal ja logisch alle
Variablen eigentlich eine Einheit bilden und so irgendwie
zusammengehören.
@Winfried
Also wenn ich dich jetzt richtig verstanden habe meinst du sowas:
1
// Steuerungsmodul
2
3
typedefstruct{
4
typASTRG_Variable_A;
5
typBSTRG_Variable_B;
6
typCSTRG_Variable_C;
7
}Strg_Variablen;
8
9
Strg_VariablenSteuerung1;
10
Strg_VariablenSteuerung2;
11
12
voidexec_Steuerung(Strg_Variablen*strg){
13
strg->STRG_Variable_A++;
14
// ...
15
}
Aber was ist daran jetzt der Vorteil gegenüber:
1
// Steuerungsmodul
2
3
#define KANAL_ANZAHL 2
4
5
typedefenum{
6
KANAL_1,
7
KANAL_2
8
}enum_Kanal;
9
typASTRG_Variable_A[KANAL_ANZAHL];
10
typBSTRG_Variable_B[KANAL_ANZAHL];
11
typCSTRG_Variable_C[KANAL_ANZAHL];
12
13
voidexec_Steuerung(enum_KanalKanal){
14
STRG_Variable_A[Kanal]++;
15
// ...
16
}
>Nochwas, du kannst auch ein Array anlegen, in denen du mehrer>struct-Variablen ablegst. So sparst du dir aber die Sache, für jede>Variable ein neues Array anlegen zu müssen, zumal ja logisch alle>Variablen eigentlich eine Einheit bilden und so irgendwie>zusammengehören.
Ich sehe ein, dass deine Variante mit den structs übersichtlicher ist.
Aber mir geht es ja hier um Optimierung.. was erzeugt den schmäleren
Code? Die Array Variante oder die mit den structs.
Reserviert ein struct nicht mehr Speicher wenn die Datentypen wegen dem
alignment nicht genau in den Speicherbereich passen?
die Pointer schnittstelle braucht ja einen 32 Bit Pointer als
Übergabeparameter und die enum Variante 8 - 16 Bit.
Wie gesagt muss ich den Code verkleinern. Aber die Übersichtlichkeit
spielt natürlich auch ne Rolle.
Achso jetzt verstehe ich auch den Argument mit dem Pointer Array..
1
Strg_Variablen*STRG_ARRAY[KANAL_ANZAHL]
2
3
voidexec_Steuerung(enum_KanalKanal){
4
(STRG_ARRAY[Kanal]->STRG_Variable_A[Kanal])++;
5
// ...
6
}
7
8
EsmussjaeinbestehenderCodegeändertwerden.
>Sonderbehandlungen find ich immer Murks, dann lieber das herausfinden,>was funktionell identisch ist und nur auf andere Daten/Objekte>angewendet wird. Oder auch in Richtung abstrakte Klassen und>Konkretisierungen schauen.
Wie gesagt es gibt hier 2 zu 90% identische Module.
An einer Stelle ist Steuerung 2 von Steuerung 1 abhängig. Sowas muss ja
irgendwie behandelt werden. Im Moment sieht man das schön beim
File-compare.. das z.b. ein If-Zweig unterschiedlich aussieht.
Gruss
Wie soll jemand, der so elementare Frage hat, einen womöglich noch
fremden Code, refaktorisieren und optinmieren? Das kann doch nur in die
Hose gehen...
>Hier kann vom Pointer+Displacement der Wert geholt werden (LDD).
Was bedeutet LDD?
> void exec_Steuerung (enum_Kanal Kanal){> STRG_Variable_A[Kanal] ++;>>Hier muß immer erst aus dem Index die Zieladresse berechnet werden>(CLR,SUBI,SBCI,LD).
Heißt das, dass bei einem Feld Zugriff mehr Maschinenbefehle und damit
auch mehr Binärcode erzeugt wird?
stefan
Was war mit der Vermutung, dass es mehr Speicher benötigt, wenn ich
alles in structs kapsle, als jede Variable in ein array zu packen.
ich werde mich mal erkundigen wie das ist, ob ein pointer zugriff
weniger code overhead erzeugt als ein array zugriff
stefan
>Der Code läuft bereits Serienmäßig auf einem 32k Controller. Aber aus>Kostengründen soll er auf einen 16K Flash Controller runter.
Wieviel ist denn ein kleinerer Typ billiger? 2 Euro vielleicht? Und wie
groß ist die Stückzahl/Jahr?
Wenn das Programm zuverlässig läuft, laß die Finger davon. Spätere
Änderungen wegen neuer Fehler sind in der Regel teurer als die Ersparnis
beim Einkauf. Gut, bei großen Stückzahlen wird das anders sein.
Schau auch nicht nur auf Speicherplatz-Reduzierung. Die Lesbarkeit und
gute Strukturierung ist auch wichtig. Im gesamten Produkt-Lebenszyklus
muss man ja auch immer wieder mal was am Code machen und ein vermurkster
Code ist entweder irgendwann gar nicht mehr wartbar oder sorgt für jede
Menge Aufwand und Fehleranfälligkeit.
Wenn du 2 Module hast, die zu 90% identisch sind, dann kann man es so
strukturieren, das alles komplett identische herausgelöst und gemeinsam
genutzt wird und nur der Rest in jedem Modul separat programmiert wird.
Auch noch wichtig: Zu unterscheiden, was Ram und was Rom/Flash kostet
und wo der Engpass ist. Du hattest ja oben geschrieben, dass ein struct
evtl. mehr Speicherplatz braucht, aber das wäre ja Ram und ich hatte
verstanden, du hast vor allem ein Rom/Flash-Problem.
@Gruenschnabel
>Wieviel ist denn ein kleinerer Typ billiger? 2 Euro vielleicht? Und wie>groß ist die Stückzahl/Jahr?
Mhm, um wie viel Euro der 16K Controller im Vergleich zum 32K Controller
günstiger ist, kann ich gar nicht genau sagen. Aber da es hier
Stückzahlen in der Größenordnung 10^5 bis 10^6 geht, kommt es beim
Einkauf/Vertrieb auf jeden Cent an.
>Wenn das Programm zuverlässig läuft, laß die Finger davon. Spätere>Änderungen wegen neuer Fehler sind in der Regel teurer als die Ersparnis>beim Einkauf. Gut, bei großen Stückzahlen wird das anders sein.
Richtig, wie gesagt ist der Code sehr suboptimal also auch sehr schwer
wartbar / erweiterbar. Von der Projektleitung wurde auch jede
Softwareänderung abgelehnt, aber dieser Umstieg von 32K auf 16K ist ein
wichtiger Schritt. Eben sowenig soll die Funktionalität angefasst
werden. Deshalb ergeben sich daran auch viele Funktionstests
(Regressionstests).
@Winfried
>Schau auch nicht nur auf Speicherplatz-Reduzierung. Die Lesbarkeit und>gute Strukturierung ist auch wichtig. Im gesamten Produkt-Lebenszyklus>muss man ja auch immer wieder mal was am Code machen und ein vermurkster>Code ist entweder irgendwann gar nicht mehr wartbar oder sorgt für jede>Menge Aufwand und Fehleranfälligkeit.
Hier ist das Kind leider schon in den Brunnen gefallen ...
>Wenn du 2 Module hast, die zu 90% identisch sind, dann kann man es so>strukturieren, das alles komplett identische herausgelöst und gemeinsam>genutzt wird und nur der Rest in jedem Modul separat programmiert wird.
Ich weiß was du meinst.
Du meinst wenn Modul A und Modul B sich in 90 % ähneln, dann die 90 % in
eine Art Basis Klasse C auslagern und A und B davon "ableiten". Dieser
sollen dann die restlichen 10 % unterschiedlichen Code erhalten.
Hier ist die Sache, aber nicht ganz so "einfach".
Modul A <-> Modul B
Funktion 1 identisch
Funktion 2 identisch
Funktion 3 identisch
Funktion 4 90 % gleich - 10 % unterschiedlich
Nur ist Funktion 4 etwa 1000 Zeilen groß!
Wenn man sich Funktion 4 als Aktivitätsdiagramm vorstellt. Dann verzeigt
sich bei ganz bestimmten Eingangsparametern A und B etwas anders.. bzw.
A ist von B UNabhängig an dieser Stelle, aber B nicht von A. Also gibt
es hier eine "halb-seitige" Abhängigkeit.
Hier etwas als Basisklasse zu definieren und A und B davon abzuleiten
ist sehr schwierig, bzw. für mich gerade nicht vorstellbar. Wie gesagt
ist Funktion eine gigantisch aufgeblähte State-Machine mit tausend
Verschachtelungen ...
Man kann sich das wie ein Mikado-Spiel vorstellen :-)
Ein riesiger Haufen blauer und roter Stäbchen... und du bekommst die
Aufgabe die roten und blauen auseinander zu ziehen und zwei neue Stapel
zu bilden, nur müssen die blauen und roten Stäbchen dann wieder genau so
liegen wie bei der Ausgangssituation....
>Auch noch wichtig: Zu unterscheiden, was Ram und was Rom/Flash kostet>und wo der Engpass ist. Du hattest ja oben geschrieben, dass ein struct>evtl. mehr Speicherplatz braucht, aber das wäre ja Ram und ich hatte>verstanden, du hast vor allem ein Rom/Flash-Problem.
Hier muss ich dir Recht geben.
Das war ein Denkfehler von mir. Natürlich ist es egal ob ich die
Datenstrukturen als struct oder Array aufbaue, schließlich wird der
Speicher ja im RAM alokiert. Wenn ich nun den Vorteil betrachte den
Peter genannt hat (Pointer Zugriff), dann müsste doch ein kleinerer Code
enstehen, wenn ich die Redundanzauflösung mit Pointern betreibe und
nicht mir Arrays !?
Vielen Dank!!
> Aber da es hier Stückzahlen in der Größenordnung 10^5 bis 10^6 geht,> kommt es beim Einkauf/Vertrieb auf jeden Cent an.
Solche Stückzahlen und Du hast keinen Schimmer wie man so etwas macht?
>Solche Stückzahlen und Du hast keinen Schimmer wie man so etwas macht?
Ich bin derjenige der das jetzt ausbaden darf, ja.
Wie gesagt habe ich ja schon einen Ansatz genannt, wie ich die
Redundanzauflösung verwirklich würde. Jetzt geht es nur noch darum, was
die beste Lösung ist.
Wenn ich die Applikation erstellt hätte, hätte ich von vornherein eine
ganz andere Architektur gewählt. Aber nun ist es eben so und ich muss
die Redundanz rauskriegen um in erster Linie Codegröße einzusparen.
Vielleicht ist es doch einfacher/sicherer das Programm oder die
kritischen Funktionen neu zu schreiben. Da die Programmabläufe wohl
bekannt sind, kann man von Anfang an eine bessere Strukturierung
vornehmen.
Bei der Stückzahl wäre der Aufwand gerechtfertigt. Wenn's zu schwierig
werden sollte, sag Bescheid ... :-)
>Vielleicht ist es doch einfacher/sicherer das Programm oder die>kritischen Funktionen neu zu schreiben. Da die Programmabläufe wohl>bekannt sind, kann man von Anfang an eine bessere Strukturierung>vornehmen.>Bei der Stückzahl wäre der Aufwand gerechtfertigt. Wenn's zu schwierig>werden sollte, sag Bescheid ... :-)
Wenn es so einfach wäre würde ich dir Recht geben ... :-)
Aber hier gibt es 3 Faktoren:
- Termindruck
- Das Risiko durch eine komplette Neuentwicklung einen Fehler
einzubauen, der durch die Modultests / Systemtests nicht erkannt wird.
(vermeindlicher "Qualitätsverlust")
- steigende Kosten
Hier wird ganz klar von der Projektleitung: "Never touch a running
system" propagiert. Was ja auch irgendwo verständlich ist. Man stelle
sich vor es wurden schon zig tausend Euro in die Entwicklung investiert
und dann nochmal zig tausend Euro für Systemtests.
Wenn man nun vorschlägt, dass man alles neu entwickeln möchte sind die
davon nicht wirklich begeistert.
Diese 3 Faktoren verursachen Kosten!
Ziel ist es jedoch Kosten einzusparen.
Man siehe dass das 2 sich widerstrebende Ziele sind :-)
Wenn ich nun den Vorteil betrachte den
Peter genannt hat (Pointer Zugriff), dann müsste doch ein kleinerer Code
enstehen, wenn ich die Redundanzauflösung mit Pointern betreibe und
nicht mir Arrays !?
>dann müsste doch ein kleinerer Code enstehen, wenn ich die Redundanzauflösung >mit Pointern betreibe und nicht mir Arrays !?
Du kümmerst dich um die falschen Dinge. Jetzt schon über die Optimierung
im Bereich einzelner Bytes nachzudenken, ohne überhaupt einen Plan für
das Ganze zu haben, ist Blödsinn.
Arrays und Pointer sind in C (und nicht nur dort) engstens verwand, und
ergeben bei gleicher Funktionalität am Ende auch gleich großen Code. Was
du vermeiden solltest, ist ein Array, in dem verschiedene Variablen
drinstecken. So etwas ist am Ende nicht wartbar.
1
typedefstruct
2
{
3
charStatus;
4
charGrenzwert;
5
}datenstruct;
6
7
datenstructDaten_Kanal_1;
8
datenstructDaten_Kanal_2;
9
datenstructDaten_Kanal_3;
10
11
...
12
//Aufruf
13
exec_steuerung(&Daten_Kanal_1);
14
exec_steuerung(&Daten_Kanal_2);
15
exec_steuerung(&Daten_Kanal_3);
16
17
voidexec_steuerung(datenstruct*daten);
18
{
19
chardummy=daten->Status;
20
}
So würde ich das, ausgehend von deinem Beispiel ganz oben, in etwa
machen.
Oliver
>Arrays und Pointer sind in C (und nicht nur dort) engstens verwand, und>ergeben bei gleicher Funktionalität am Ende auch gleich großen Code. Was>du vermeiden solltest, ist ein Array, in dem verschiedene Variablen>drinstecken. So etwas ist am Ende nicht wartbar.
Mir ist auch klar, dass
1
data_types[Kanal_1].Grenzwert=10;
äquivalent zu
1
data_types->Grenzwert=10;
ist.
sofern Kanal_1 das 1. Element im Array ist.
An ein Array mit verschiedenen Variablen hatte ich auch nie gedacht.
An was ich dachte ist für JEDE REDUNDANTE Variable ein Array mit (in
diesem Fall) 2 Elementen zu erzeugen.
Oder Alternativ FÜR ALLE REDUNDANTE Variablen einen struct anzulegen und
dann zwei Variablen von diesem Typ zu definieren.
Ich glaube für meine Ansprüche und zum besten Refacotoring des Codes ist
es
einen solchen Codeteil:
>Hier wird ganz klar von der Projektleitung: "Never touch a running>system" propagiert. Was ja auch irgendwo verständlich ist.
Es ist völlig egal, was Du machst: Du mußt das laufende System ändern.
Meine Erfahrung ist die, daß mir einer Neuprogrammierung am meisten
Platz gespart werden kann.
Die große Frage wird keiner beantworten können, ob durch Veränderungen
am bestehenden Programm, die benötigte Code-Einsparung erreicht werden
kann. Wenn der Compiler halbwegs gut optimiert hat, vermutlich nicht!
Im Laufe einer Entwicklung wird ein Programm häufig verändert, um
geänderten Vorgaben gerecht zu werden. Bereits hier läßt man die
funktionierenden Teile so, wie sie sind, um keine neuen Fehler
einzubringen. Somit entsteht ein Flickwerk mit Ballst, dessen Code
zwangsläufig größer ausfällt. Bei Dir scheint das ja wohl der Fall zu
sein.
Viel Code kann man natürlich einsparen, wenn man große Teile in
Assembler optimiert. Aber .....
Eigentlich wäre der erste Schritt, den aktuellen Speicherverbrauch zu
analysieren, um dann zu entscheiden, wo das größte Optimierungspotential
besteht.
Fragen wie diese:
>Reserviert ein struct nicht mehr Speicher wenn die Datentypen wegen dem>alignment nicht genau in den Speicherbereich passen?
zeigen da noch Nachholbedarf.
Oliver
> Nur ist Funktion 4 etwa 1000 Zeilen groß!
Reif für die Tonne... Aber mal ganz ehrlich:
Katastrophen-Code zu reparieren geht natürlich, aber dazu braucht man:
a.) Sehr viel Erfahrung
b.) Sehr viel Erfahrung
c.) Experte der verwendeten Sprache
d.) Sehr viel Erfahrung
e.) Sehr viel Erfahrung
f.) Experte des Problemfelds
g.) Sehr viel Erfahrung
h.) Sehr viel Erfahrung
Ach, und habe ich schon erwähnt, dass man für solche Aktioen viel
Erfahrung benötigt?
Alles andere führt ins Desaster.
Du kannst das grundsätzlich so machen, wie du es vorgeschlagen hast. Das
wird wohl der schnellste Weg sein, ohne viel an der Struktur des
Gesamtprogrammes zu ändern. Und das ist ja glaub ich dein Ziel.
Schlussendlich läuft alles auf eine sinnvolle Abwägung raus,
Änderungsaufwand versus vernünftige Struktur.
Ich kenne solche Projekte auch, wo es mich anwidert, überhaupt was dran
zu machen, aber man muss und es muss billig sein. Dann muss man alles,
was man über saubere Programmierung gelernt hat über Board werfen und
kostensparend dranrumstricken...
Viel Erfolg!
>Dann muss man alles,>was man über saubere Programmierung gelernt hat über Board werfen und>kostensparend dranrumstricken...
Muß man das? Bei Stückzahlen in der Größenordnung 10^5 bis 10^6 und der
Produktklasse "Steuerung" schiesst man sich da selber ganz schnell ins
Knie. Jede "Rumstrickerei" holt einen da früher oder später wieder ein.
Mach ein sauberes Konzept, schätz den Aufwand sicher ab, und dann mit
der Projektleitung abstimmen, die soll entscheiden. Dafür wird die
bezahlt.
Oliver
Danke für die vielen Beiträge!
Um wirklich was am Steuerungsalgorithmus selbst zu optimieren braucht
man viel Erfahrung und auch viel Expertenwissen, da gebe ich euch völlig
recht.
(Das versuche ich mir Stück für Stück anzueignen, man muss ja irgendwo
ins Projekt hineinwachsen. Also abgesehen davon was man aus dem
Pflichtenheft, SDD herauslesen kann).
Bisher habe ich keine Zeile Code geändert.
Ich habe den Code nur auf Optimierungspotential hin untersucht.
Hauptsächlich habe ich mich erstmal auf Code Redundanz konzertiert, die
zu Genüge in diesem Projekt vorhanden ist.
Beispielsweise hat Modul A 5 Funktionen. Diese 5 Funktionen beinhalten
exakt den selben Code bis auf die Verwendung von verschiedenen Variablen
und verschiedenen AD Kanäle. Geschätzt kann man hier bis zu 80 % Code
einsparen durch die Verwendung eines Unterfunktion Prototypes mit
passenden Schnittstellen.
@Winfried: Danke, ich werd mein bestes tun ;-)
Module die doppelt vorhanden sind (redundant) versuche ich zu
vereinheitlichen in dem ich die spezifischen Variablen kapsle und den
Funktionen parametrierbare Schnittstellen verpasse.
Wie gesagt analysiere ich im Moment nur und stelle Konzepte auf wie man
optieren könnte. Ich will erst so gut wie möglich alle Querverbindungen
zwischen den Modulen identifizieren bevor ich damit beginne etwas zu
ändern.