(Lassen Sie uns einfach die Vorschläge überspringen, dass es die falsche Idee ist und für eine Weile unterbricht ...).
Gibt es eine Möglichkeit, die digitalWrite()
Methode zu ersetzen (zum Beispiel), damit ich etwas hinzufügen kann, was dort passieren kann? Folgende Regeln müssen jedoch beachtet werden:
- Ein Aufruf von
digitalWrite(pin, value)
muss die neue Methode aufrufen. - Ein Aufruf
digitalWrite(pin, value)
von einer anderen Bibliothek , die in meinem Code (SD.h zum Beispiel) muss die neue Methode aufzurufen. - Keine der Arduino-Dateien kann geändert werden (ich möchte dies nicht bei jedem Upgrade der Arduino-Version tun).
- Alles muss in einer Header-Datei erfolgen, die ich einschließen kann, um die neue Funktion zu verwenden.
Ich habe dies versucht und es funktioniert, aber nur in meinem Code, nicht in externen Bibliotheken, die ich nach diesem Header einfüge:
#include <Arduino.h>
class PinsHook {
public:
static void digitalWriteHook(uint8_t pin, uint8_t value) {
digitalWrite(pin, value);
if (pin == 8) {
Serial.print("Pin ");
Serial.print(pin);
Serial.print(" changed to ");
Serial.println(value);
}
}
};
#define digitalWrite(pin, value) PinsHook::digitalWriteHook(pin, value)
Antworten:
Ich bin mir nicht sicher über die Arduino IDE (ich habe sie momentan nicht installiert), aber mit UECIDE ist es so einfach wie das Definieren einer neuen
digitalWrite
Funktion in Ihrem Code. Wenn der gesamte Shebang miteinander verknüpft ist, überschreibt die Funktion in Ihrem Code die Funktion in den Bibliotheken.Kommentieren Sie die digitalWrite-Funktion aus und die LED blinkt. Kommentieren Sie es aus und es blinkt nicht mehr.
quelle
digitalWrite()
von dieser Methode nicht aufrufen , da sich die Methode selbst aufruft (Stapelüberlauf!). Kann das gelöst werden? Wenn meine Methode die verknüpfte war, dann denke ich, dass die ursprüngliche Methode überhaupt nicht enthalten war und nicht aufgerufen werden kann - habe ich recht?Ich werfe nur eine Idee. Keine Zeit zum Testen.Bearbeiten : Ich habe die unten stehende Lösung getestet und sie funktioniert wie erwartet, sofern sowohl die
__wrap_
als__real_digitalWrite()
auch deklariert sindextern "C"
.Wenn Sie die IDE davon überzeugen können, der Kompilierungsbefehlszeile zusätzliche Optionen hinzuzufügen, können Sie:
__wrap_digitalWrite()
Ihre Implementierung vondigitalWrite()
__real_digitalWrite()
Sie darin auf, wenn Sie die Implementierung vom Arduino-Kern erhalten möchten-Wl,--wrap=digitalWrite
dem Kompilierungsbefehl des letzten Verknüpfungsschritts hinzuBeispiel Wrapper:
Der Versuch, dies in eine Klasse zu bringen, hilft nicht weiter.
Vgl. Die Manpage von gnu ld .
quelle
-Wl,--wrap=digitalWrite
dem Kompilierungsbefehl des letzten Linkschritts hinzu"?Haben Sie es mit einem C-Makro versucht?
Dies ergibt die Retval von
post()
Sie können entweder die
pre()
oder diepost()
Funktionen / Makros weglassen .Dies muss an einer Stelle platziert werden, die enthalten ist, wenn der Header für digitalWrite enthalten ist, damit er überschrieben werden kann.
Die einzige andere Alternative besteht darin, mit der Bibliotheksbinärdatei kreativ zu werden.
Oder seien Sie einfach vernünftig und ändern Sie den Quellcode. Es ist speziell verfügbar, damit Benutzer es ändern können.
Wenn Sie die Änderung nicht jedes Mal wiederholen, wenn es eine neue Arduino-Version gibt, sollte dies vermeidbar sein. Wenn Sie die Umgebung aus den Git-Quellen erstellen, können Sie Ihren Patch durch Zusammenführen / erneutes Basieren auf dem Hauptzweig verwalten.
quelle
Arduino verwendet den avr-Compiler, um seine Standardbibliothek in eine
core.a
Datei zu kompilieren . Aufgrund der Funktionsweise des avr-gcc-Linkers und der Reihenfolge, in der Arduino die Linkreihenfolge angibt, können Sie das Verhalten von Kernfunktionen "überschreiben", indem Sie die Datei kopieren, die die Methode enthält, die Sie in Ihr Projekt ändern möchten.Die Verknüpfung von Arduino erfolgt in dieser Reihenfolge:
Wenn Sie also die Datei vom Arduino-Installationsort (
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino
) in Ihr Projekt kopieren und ändern, wird Ihre geänderte Implementierung verwendet.Dies wird es sicherlich für alle Dateien in Ihrem Projekt überschreiben , und ich glaube, es wird es auch in allen Bibliotheken überschreiben, die Sie ebenfalls verwenden. Seien Sie also vorsichtig mit diesem Ansatz.
quelle
Definieren Sie in Ihrem Codemodul Ihre eigene Wrapper-Funktion und verwenden Sie den globalen Bereichsoperator, um auf die Arduino-Funktion zu verweisen:
Denken Sie daran, dass der Linker Regeln hat, auf die er verweist. Der globale Bereichsoperator zwingt den Linker, den global verfügbaren auszuwählen, während die benutzerdefinierte Wrapper-Funktion vom Modul privat angezeigt wird.
quelle
"Vielleicht" kann die Verwendung der c ++ - Funktion "Funktionen überschreiben" helfen
Wenn Sie also Ihre Hauptanwendung aufrufen:
Die verpackte Version wird aufgerufen
und wenn Sie dies verwendet haben:
Das Original wird aufgerufen
Sie können auch diese Definition verwenden:
Um es zu verwenden, müssen Sie jedoch eine Variable mit doppeltem Typ definieren:
quelle
Die Informationen von Rubber Duck sind korrekt, aber unvollständig.
Ich benötige eine große Menge an digitalem PWM-Ausgang für die Steuerung von Hobbyzügen.
Also habe ich 4 x 74HC595 an mein At Mega angeschlossen, das über 0,5 ms mit einem 2-kHz-Bitmuster gespeist werden muss. unterbricht.
Meine serielle Verschiebungsfunktion, die 32 Bit in die Register verschiebt, benötigt 562 us pro Zyklus. Unmöglich.
Ich habe eine optimierte Version von digitalWrite und Read erstellt, für die wir 328 benötigen. Jetzt ist es möglich, mit 2 kHz zu PWM. Der Trick ist, dass meine optimierte Funktion die letzten 2 Pins einschließlich ihrer Bitmasken und Outports speichert; und ich überspringe die Timer-Prüfung. Es ist threadsicher. Für ein einzelnes digitalWrite dauert dies etwas länger. Durch wiederholtes Schreiben auf Datapin und Clockpin wird der Standard Arduino digitalWrite um ca. 42% verbessert.
Übrigens: Mit der digitalWriteFast-Bibliothek ergibt sich ein Ergebnis von 45,8 µs, eine wirklich enorme Verbesserung. Diese Bibliothek verarbeitet jedoch nur Schreibvorgänge, wenn die PIN-Nummer zur Kompilierungszeit bekannt (und damit fest!) Ist. Dies ist bei meiner LiquidCrystal-Bibliothek nicht der Fall, bei der entweder 4 oder 8 Bits parallel über 4 aufeinanderfolgende Pins in die Abschirmung geschrieben werden.
Ich habe mein optimiertes digitalWrite nur für meine Anwendung einschließlich LiquidDisplay verwendet, als ich die Bibliothek C: \ Users \ Dell \ Downloads \ arduino-1.8.5 \ hardware \ arduino \ avr \ cores \ arduino in einen Unterordner im Ordner von my kopiert habe Anwendung, genannt
C: \ Benutzer \ Dell \ Google Drive \… \… .. \ AppFolder \ Bibliotheken .
Als ich in beiden Ordnern die Datei wiring_digital.c durch meine optimierte Version ersetzte , funktionierte es.
Ich konnte es nicht zum Laufen bringen, als ich nur die Datei wiring_digital.c in der Arduino-Bibliothek ersetzte (der LiquidCrystal übernahm die Standardfunktion woanders).
Das Hinzufügen von nur wiring_digital.c im Unterordner meiner Anwendung führte zu einer Vielzahl von Verknüpfungsfehlern.
Daher habe ich den gesamten Arduino-Ordner (der nicht so groß ist) in meinen Unterordner in der Anwendung kopiert und er kann problemlos kompiliert werden. Keine sehr elegante Lösung, da die gesamte Bibliothek repliziert wird. Aber es funktioniert.
Schlussfolgerung zum Überschreiben einer Arduino-Kernfunktion:
• Fügen Sie Ihre geänderten Funktionen (.c und / oder .h) in die Arduino-Bibliothek ein und kopieren Sie diese Bibliothek vollständig in den Unterordner "Bibliotheken" in Ihrem Anwendungsordner. Dann verwenden auch alle anderen Bibliotheken Ihre eigene geänderte Funktion.
Fazit Leistung digitalWrite in einer echten 32-Bit-Serienverschiebung:
• Ein optimiertes generisches digitalWrite und Read übertrifft das Standardmodell mit 42% deutlich, wenn 2 Pins wiederholt verwendet werden. • digitalWriteFast (mit bestimmten Pins zur Kompilierungszeit) übertrifft das Standard-digitalWrite in einer echten 32-Bit-Shift-Anwendung mit 92% (ist 12,2-mal schneller).
Hoffe das hilft anderen Arduino Anwendern… ..
quelle