Hallo, ich bin auf der Suche nach Literatur/Beispielen wiederverwendbare, modulare Architekturen auf mittleren MCUs (Cortex M3-M4, maximal M7). Momentan wächst die Komplexität meiner Programme sehr schnell und ich muss zwingend meine Firmwares stärker modularisieren und entkoppeln um die Wiederverwendbarkeit und die Pflege zu vereinfachen. Ich programmiere momentan in C (99), bin aber auch von C++ grundsätzlich nicht abgeschreckt. Dass man grundsätzlich Interfaces definiert um eine möglichst schwache Kopplung zu erreichen ist mir klar. Dass man callbacks und dependency injection verwenden kann auch in der Theorie. Was ich suche sind aber konkrete Anwendungsbeispiele. Hier sind ein paar Beispiele, worüber ich mir den Kopf zerbreche - Modul für einen Sensor, das möglichst ohne Anpassungen auch auf einem andern uC (beschränken wir uns mal auf die Cortex-M) laufen kann. Der Sensor kann entweder per SPI oder I2C angesprochen werden. Ich könnte zwei Init Methoden schreiben, (SPI und I2C), die z.B. den Zeiger auf die Peripherie bekommen (inkl. GPIO Port, Geschwindigkeit etc - recht umständlich und nicht portabel), oder ich gebe Funktionspointer zum Initialisieren mit, müsste dann aber die Kapselung etwas aufbrechen. - RS485 wrapper auf "normaler" USART (rs232) - sehr ähnliche Probleme wie oben, wann wo initialisiere ich die Peripherie? - Kommunikationsmodul, das unabhängig von der Schnittstelle (CAN, RS485 etc) den Protokollparser enthält und je nach Anforderung Daten schreibt oder zurück gibt. Dafür muss das Modul aber alle anderen Teilmodule kennen (bzw. deren Instanzzeiger), macht man das so? - Flash/EEPROM: Bisher war es so, dass es eine große flash.h gab, in der Adressen/Register für alle Teilmodule definiert wurden. Adressen mussten manuell inkrementiert werden (waren alles nur defines in dem Header). Das ist sehr fehleranfällig und auch nicht schön, weil Implementationsdetails (welche zu speichernden Parameter hat das Modul z.B.) aus allen anderen Modulen nötig sind. Wie macht man solche Sachen sinnvoll? Vielen Dank für euren Input!
jk schrieb: > ich bin auf der Suche nach Literatur/Beispielen wiederverwendbare, > modulare Architekturen auf mittleren MCUs (Cortex M3-M4, maximal M7). AutoSAR.
jk schrieb: > Wie macht man solche Sachen sinnvoll? Indem man die Teile, die hardwarespezifisch sind, von der eigentlichen Funktionalität entkoppelt. Die eigentliche Funktionalität ist zum Beispiel eine Berechnung. Oder vielleicht die Abarbeitung eines Protokolls. Diesen Teil kann man so schreiben, dass der exakt gleiche Code auf den verschiedensten Plattformen kompiliert werden kann. So kann man den Code z.B. auch auf dem PC laufen lassen, um ihn dort zu testen.
Eric B. schrieb: > jk schrieb: >> ich bin auf der Suche nach Literatur/Beispielen wiederverwendbare, >> modulare Architekturen auf mittleren MCUs (Cortex M3-M4, maximal M7). > > AutoSAR. Gucke ich mir an. Mark B. schrieb: > Indem man die Teile, die hardwarespezifisch sind, von der eigentlichen > Funktionalität entkoppelt. Das versuche ich ja bereits. Das Kommunikationsmodul z.B. bekommt nur einen Eingangs- und Ausgangspuffer, die Quelle ist egal. Dennoch braucht dieses Modul viele Informationen aus anderen Modulen. Aber auch die hardwarespezifischen Dinge müssen konfigurierbar und modular bleiben, um Port, Device etc einstellen zu können. Die Flash Geschichte wurmt mich, wie kommt man da von einem globalen Ansatz weg?
jk schrieb: > Aber auch die hardwarespezifischen Dinge müssen konfigurierbar und > modular bleiben, um Port, Device etc einstellen zu können. Nö. Hardwarespezifische Dinge sind eben HARDWARESPEZIFISCHE Dinge. Da ist nix modular und so. W.S.
jk schrieb: > ich bin auf der Suche nach Literatur http://shop.oreilly.com/product/0636920017776.do Das ist zwar im Wesentlichen auf C bezogen, die Konzepte und Ideen lassen sich aber auch -- und oft viel eleganter -- mit C++ umsetzen. HTH, YMMV.
Du hast 3 Themen angesprochen, für die es verschieden Lösungen gibt, jedoch nicht bei nur vagen Andeutungen. Beispiel Flash: hier geht von Linker machen lassen über Verzeichnisse bis Quelltext-Parser alles mögliche. Es ist aber z.B. wichtig zu wissen, ob neue Software alte Parametersätze lesen können muss. Beim Sensor oder auch bei den Kommunikationsprotokollen: Eine Generalisierung ist nur unter Kenntnis der bisherigen Anforderungen möglich. Die Verschiedenheit (Uart/CAN: beliebig lange Telegramme vs. feste Grenzen, P2P vs. Bus etc) macht einen "allgemeinen" Ansatz wertlos. Wenn Du den Sensor mit 3 oder 4 direkten Zugriffsfunktionen ausreichend Steuern kannst (z.B. Reset, Bytes Lesen, Bytes schreiben), dann schreibe lieber 2 getrennte Treiber (SPI und I2C), die Dir Funktions- und Kontextpointer liefern, die Du nach der Initialsierung verwendest. Denke auch über Code-Kopien nach. Nicht manuell, sondern automatisch in der Makeumgebung. Wenn Du konkrete Sensoren oder Hardware hast, dann kann direkter verdreifachter Code deutlich effektiver sein als jeweils was generisches mit Übergabe des Kontexts. Und über alle Arten von Textfressern, die Dir z.B. das Parameter-Layout beim Make generieren, indem die jeweiligen Initialisierungen geparst werden. Bei größeren Quellen kann es auch sinnvoll sein, aus den C-Quellen bestimmte Zeilen herauszuparsen und daraus quasi ein "C-Skript" zu machen, also das zu einem C-File zusammenfügen und per gcc und Kommandozeile output zu generieren. Beispiel: Wenn Du wissen willst, wie groß "MAX_ANZAHL" ist, kannst Du den Original-Code vom Cross-Präprozessor bearbeiten lassen und dessen Output direkt in gcc verwenden ('printf("%i", MAX_ANZAHL;'). Gebe uns also ein Beispiel, egal ob Source-File oder Pseudocode.
Ein Link noch: https://www.duckware.com/bugfreec/index.html Nichts was ich direkt so umsetzen würde, teils veraltet. Aber die Konzepte sind ein guter Start. Und m.W. der erste, der Compile-Time-Asserts in C propagiert hat.
ich mag das openSource project chibiOS (http://www.chibios.org/dokuwiki/doku.php) das sind 2 verschiedene RTOS kernels mit möglichst gleicher API und eine HAL. leider hauptsächlich in C
W.S. schrieb: > jk schrieb: >> Aber auch die hardwarespezifischen Dinge müssen konfigurierbar und >> modular bleiben, um Port, Device etc einstellen zu können. > > Nö. Hardwarespezifische Dinge sind eben HARDWARESPEZIFISCHE Dinge. Da > ist nix modular und so. > > W.S. Ja, es ist auf eine MCU abgestimmt. Trotzdem muss es konfigurierbar sein. An alle anderen: Vielen Dank, werde mir die Buchtipps anschauen! @Achim: top, ich muss über ein einfaches Pseudocode Beispiel nachdenken, danke. Ich habe gar nichts gegen C, im Gegenteil, es es mein Hauptentwicklungswerkzeug :)
Nach einem wirklich schlüssigen Konzept für Plug- and Play Module suche ich auch schon länger. Das Beispiel hier ist tatsächlich ein wenig von AUTOSAR inspiriert: Beitrag "Re: Plug and Play Interface Konzept für Module in C" Ich kenne es so, das dort die Module über die sogenannte RTE verknüpft werden. Das kann dazu führen, dass die RTE dann zu einer riesigen Anzahl von Include Files führt, die dann die verschiedenen Interfaces miteinander verknüpfen. Das sieht erst mal ziemlich umständlich aus und ist auch lästig beim Code verfolgen in einer IDE, weil die Verknüpfungen oft über "#defines" gemacht werden und dann die IDE dem Pfad nicht mehr folgen kann. Mittlerweile scheint mir das aber ein gangbarer Weg, die Module wirklich zu entkoppeln.
> Die Flash Geschichte wurmt mich, wie kommt man da von einem globalen > Ansatz weg? Dateisystem! Es muss nicht eins sein mit allen Schikanen, da gibt's auch ganz simple. (z.B. RO von Daten welche at build Time C-Quellcode werden) Steigen später die Ansprüche, kommt zwar ein raffinierterer FS-Treiber dazwischen, aber nach mount bleibt's bei /fopen(..)/ & Co.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.