- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: Code / Projekt richtig strukturieren

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578

    Code / Projekt richtig strukturieren

    Anzeige

    E-Bike
    Hallo,

    ich habe ein recht umfangreiches Projekt, welche schon diverse HW-Iterationen durchgemacht hat (angefangen bei AVR, dann XMega, jetzt STM32-wird auch bleiben!).
    Um bei einer neuen HW-Version nicht immer allzu viel umschreiben zu müssen (und weil der Code über die Jahre auch ziemlich fett und hässlich geworden ist), möchte ich alles neu strukturieren. Programmiert wird in Plain-C, das soll auch so bleiben.
    Momentan siehts so aus:
    Verschiedene Bibliotheken lesen zb Sensoren aus, deswegen brauchen sie Funktionen, um auf die Hardware zuzugreifen (meistens SPI). Wenn jetzt eine neue HW kommt, kann es sein, dass Sensor X vorher an SPI1 angeschlossen war, jetzt aber an SPI2 hängt. Dadurch ändern sich aber diverse Dinge, zb. der Bus (wichtig für Clock), die Pins....

    Meine Frage ist, wie löse ich das möglichst "professionell" und zukunftssicher?
    Die erste Idee war, eine Header Datei zu erstellen "HWBoard.h", in welcher ich alle Peripherien etc. definiere und dann in Zukunft nur noch diese ändern muss.
    Dann bekommt jedes Modul, welches auf HW zugreifen muss, nur noch eine Glue-Funktion, welche dann den Zugriff auf die richtige Schnittstelle umleitet.

    Wäre das der goto Weg oder gibt es bessere Möglichkeiten?
    Der Aufwand der Umsetzung ist für mich zweitrangig, solange es eine einmalige Sache ist und ich in Zukunft neue HW schnell einpflegen kann!

    Vielen Dank & Gruß
    Chris

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    Hallo!

    Ist nicht eindeutig zu beantworten. Kommt auf das Gesamtkonzept an. Eine brauchbare Variante sind Makros in C. Die kannst Du zentral hinterlegen und im Quelltext nur mit den Makronamen arbeiten. Dann kannst Du das jederzeit nachträglich ändern. Wenn sich nicht nur Pins, sondern auch Schnittstellen ändern, musst Du die umleiten, auf die jeweils richtigen Funktionen. Dann hast Du u.U. für jede definierte Schnittstelle in der zentralen Datei einen Wert, der die Schnittstelle angibt, so dass Du dann nach diesem Wert die Umleitung vornehmen kannst. Noch flexibler geht das über Variablen. Die kann man dann auch zur Laufzeit noch ändern, dann ergibt sich schnell die Möglichkeit eines Setup, wie bei einem Mainboard eines x86 z.B., die Werte kann man dann im Flash speichern oder woanders, wo sie nicht verloren gehen; dann bei Systemstart auslesen und die Werte evtl. übertragen.

    MfG

    Bewehrte Systemlösungen sehen immer so aus, dass man allgemeingültige Funktionen definiert. Z.B. "Read" oder "Write". Dann wird festgelegt, was man dort übertragen kann: Strings (Zeichenketten), Zahlen (Werte), Bytes. Mit Schnittstellenkennung kannst Du dann innerhalb der Funktion die Umleitung auf den jeweils richtigen Code vornehmen, der die Daten über die angegebene Schnittstelle verschickt oder von dort liest. In C(++) selber kann man mehrere Konstruktoren (objektorientiert) erstellen, für jeden speziellen Fall einen, der Compiler sucht sich dann - je nach Übergabeparameter - den Passenden aus, so dass der richtige Code dann am Ende ausgeführt wird. Welches Konzept magst Du lieber? - Das ist die Frage.
    Geändert von Moppi (27.02.2021 um 11:50 Uhr)

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi!

    Makros werde ich wohl definitiv verwenden, variable Schnittstellen brauche ich nicht, weil sich die HW nicht on the fly ändert! Mir stellt sich aber noch die Frage, wie und wo ich die Markos definiere..
    Wo mache ich die HW-Initialisierungen? Alle in einer Datei, oder jede Schnittstelle in dem jeweiligen Modul (also Spi1 in Sensor X Modul zb)?
    Definiere ich alle Variablen und ändere in Zukunft nur noch diese oder ändere ich jedes mal den Code selbst? Also definiere ich die Pins zb und schreibe den Code mit den Defines oder ändere ich die Pins im Code direkt?

    Gruß
    Chris

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.04.2015
    Beiträge
    898
    Das ist eine Frage der Vorgehensweise.
    Wenn Du beim Erstellen eines neuen Projektes, einer neuen Version oder Variante die Dateien kopierst, kannst Du die Definitionen peux a peux direkt in den Dateien anpassen.
    Wenn Du die Dateien verlinkst (Verweis auf einen projektübergreifenden Ordner), wirst Du wohl die Hardwaredefinitionen extrahieren müssen.

    Beides hat Vor- und Nachteile. Wenn Du willst, das sich Bugfixes oder Erweiterungen automatisch über all Deine Projekte verteilen lassen, nimmst Du die Dateiverlinkung. Wenn Dich davor graut , kopierst Du besser.

    (ohne Versionsverwaltung würd's mich grauen)
    Geändert von Holomino (28.02.2021 um 16:09 Uhr)

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    "define"s sind Textmakros. Wenn Du die verwendest, machst Du das an einer übersichtlichen Stelle, also in einer Datei *.h
    Ich benutze z.B. eine "defines.h". Die binde ich dann an geeigneter Stelle ein. Da weiß ich, stehen meine Makros drin. Beispiel: #define name wert
    Du verwendest dann überall die Makronamen (-bezeichnungen). Der Compiler ersetzt dann die Namen/Bezeichnungen durch den Text dahinter. Da kannst Du auch Code hinschreiben (nicht nur Werte), manchmal kann das nützlich sein.

    MfG


    Code:
    #ifndef __defines__
    #define __defines__
    
    
    
    
    .....
    
    #define LiPoIn_12 A3
    #define LiPoIn_08 A5
    #define LiPoIn_04 A4
    #define bps 115200
    #define INPUT INPUT_PULLUP
    
    #define setStatePin stateVal = 1; digitalWrite(State, 1);
    
    
    
    
    
    #endif
    "stateVal = 1; digitalWrite(State, 1);" ist Code, der in den Quelltext übernommen wird, wenn ich dort "setStatePin" schreibe.
    Mit "#define INPUT INPUT_PULLUP" definiere ich das Makro INPUT neu, als INPUT_PULLUP, das habe ich zum Ausprobieren. Gibt eine Warnung, funktioniert aber.

    - - - Aktualisiert - - -

    Schau mal im Internet nach "Überladen von Funktionen". Du kannst denselben Funktionsnamen mehrfach verwenden, jedes mal mit andern Übergabeparametern und anderem Code, falls Du so was brauchen kannst.

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.684
    Hallo Chris!
    .. möchte ich alles neu strukturieren. Programmiert wird in Plain-C, das soll auch so bleiben ..
    So ähnlich hatte ich es auch vor Jahren. Meine Systematik hatte dann auch mit ner Strukturdarstellung "über alles" angefangen (hier vorzugsweise HW, dort aber schon Verweise auf SW):

    ......Bild hier  
    ......© 2021 by oberallgeier - Originalformat im Bild verlinkt

    Dazu dann natürlich feinere Aufteilungen (teils nicht wirklich präsentabel hier - aber es hilft bei der Orientierung) für die einzelnen Controller, Controllerquellcodes etc. Vor allem verschiedene Sensoren an verschiedenen Controllern sind so gut im Griff. Wichtig natürlich nicht nur Ort- sondern auch Datumsangaben.

    Die Softwareskizzen sind ähnlich und erlauben damit eine schnelle Übersicht über den Code - und dessen Lage auf meinem Computer (wozu gibts denn sonst hyperlinks in Textverarbeitungsprogrammen *gg*).

    PS: die Angaben im präsentierten Bild sind teils veraltet - I²C läuft z.B. mittlerweile mit 400 kHz, auch auf den PingPongs habe ich mittlerweile die müden mega8 gegen mega328 mit 20 MHz-Quarz getauscht und UART funzt jetzt mit 512 MBd usf.
    Geändert von oberallgeier (01.03.2021 um 11:31 Uhr)
    Ciao sagt der JoeamBerg

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hallo,

    vielen Dank erstmal für die hilfreichen Antworten!
    Ich habe mich jetzt dazu entschieden, eben alle Hardware Funktionen und Variablen etc.. in eine eigene Datei zu packen, in welcher ich auch das jeweilige Board definiere, sodass ich dann im Hauptprogramm, falls nötig, auch mit dem Define zwischen versch. Funktionen unterscheiden kann.
    Wenn ich das auf die schnelle richtig gesehen habe, gibt es die Überladung von Funktionen nur in objektorientierten Sprachen oder täusche ich mich?
    Was mich noch sehr interessieren würde, wäre die Versionsverwaltung. Ich arbeite mit EM:Bitz, da gibt es die Funktion "Autoversioning", allerdings hab ich das noch nie verwendet.
    Vielleicht weiß da jemand mehr?

    Vielen Dank
    Chris

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    nur in objektorientierten Sprachen ....

    funktioniert in C++ ... in der Arduino-IDE mit dem Compiler funktioniert das daher auch, in den INO-Dateien.

    Leider wohl aber mit dem älteren C nicht.


    MfG

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.04.2005
    Ort
    Bad Aibling
    Beiträge
    212
    Schon eine weile her aber vielleicht interessiert es Dich: wenn Du Modernes C benutzen magst benutze für die Hardware unabhängigen Teile Funktionstemplates die als Template Parameter die Implementierung der Hardwarespezifischen Teile als Datentyp übergeben bekommen. Dann musst Du nur in Zukunft die Hardware nahen Funktionen neu schreiben und alles andere erledigt der Compiler.

    Benutze für Konstanten besser die C Variante und nicht den Präprozessor: const int iPort = 4;
    Die sind Typsicher was die defines nicht sind. Kann man genauso in einer Datei Sammeln um sie an Zentraler stelle zu Pflegen.
    Geändert von alexander_ro (23.05.2021 um 09:58 Uhr)

Ähnliche Themen

  1. Ein Stück C-Code - sieht richtig aus, aber es gibt ne Fehlfunktion
    Von oberallgeier im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 28.12.2012, 12:21
  2. RP6: Projekt Morse-Code
    Von Dirk im Forum Robby RP6
    Antworten: 6
    Letzter Beitrag: 21.03.2012, 18:48
  3. C-Programm strukturieren/aufteilen
    Von dreadbrain im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 09.06.2010, 19:27
  4. Wie kopiert man Quelltexte richtig in ein anderes Projekt?
    Von rogerberglen im Forum Assembler-Programmierung
    Antworten: 2
    Letzter Beitrag: 18.08.2007, 12:49
  5. MIDI- Code richtig?
    Von Xtreme im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 15.03.2006, 08:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test