Multiple Definitions Linker -Fehler Bitte werfen Sie einen Blick auf HowTO, um Multiple Definitions für Linkerfehler zu beheben
Die FlashStorage_Samd-Bibliothek, basierend auf dem FlashStorage von Cristian Maglie, bietet eine bequeme Möglichkeit, die Daten des Benutzers mithilfe von Emuled-Eprom aus dem nichtflüchtigen Flash-Speicher von SAMD21/SAMD51-Boards zu speichern und abzurufen.
Der Flash -Speicher, der im Allgemeinen zum Speichern des Firmware -Codes verwendet wird, kann auch zum Speichern / Abrufen von mehr Benutzerdaten und schneller als von EEPROM verwendet werden. Dank des gepufferten Datenschreibens und Lesens wird die Flash -Zugriffszeit stark verkürzt, um die Lebensdauer des Blitzes zu erhöhen .
Arduino IDE 1.8.19+ für Arduino.Arduino SAMD core 1.8.13+ für SAMD Arm Cortex-M0+ Boards.Adafruit SAMD core 1.7.11+ für SAMD Arm Cortex-M0+ und M4-Boards (Nano 33 IoT usw.).Seeeduino SAMD core 1.8.3+ für SAMD21/SAMD51 -Boards (XIAO M0, WIO -Terminal usw.).IndustruinoSAMD core 1.0.3+ für SAMD21 -Boards (Industruino DG21 usw.).IndustruinoSAML core 1.0.0+ für SAML21 -Boards (Industruino 420Maker usw.).Sparkfun SAMD core 1.8.4+ für SAMD21/SAMD51 -Boards (Sparkfun_redboard_turbo, Sparkfun_Samd51_Thing_plus usw.). Der beste und einfachste Weg ist die Verwendung Arduino Library Manager . Suchen Sie nach FlashStorage_Samd und wählen Sie die neueste Version aus / installieren Sie sie.
Eine andere Möglichkeit zu installieren ist:
FlashStorage_SAMD-master.zip herunter.FlashStorage_SAMD-master VerzeichnisFlashStorage_SAMD-master Ordner zum Verzeichnis der Arduino-Bibliotheken wie ~/Arduino/libraries/ .Um ohne Fehler kompilieren zu können und bough .
Angenommen, die Arduino SAMD -Version beträgt 1.8.13. Jetzt darf nur eine Datei in das Verzeichnis kopiert werden:
~/.arduino15/packages/arduino/hardware/samd/1.8.13/platform.txtWenn eine neue Version installiert ist, denken Sie daran, diese Dateien in das neue Versionsverzeichnis zu kopieren. Zum Beispiel ist eine neue Version x.yy.zz
Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/arduino/hardware/samd/x.yy.zz/platform.txtAngenommen, die Arduino SAMD -Version beträgt 1.8.9. Diese Dateien müssen in das Verzeichnis kopiert werden:
~/.arduino15/packages/arduino/hardware/samd/1.8.9/platform.txt~/.arduino15/packages/arduino/hardware/samd/1.8.9/cores/arduino/Arduino.hWenn eine neue Version installiert ist, denken Sie daran, diese Dateien in das neue Versionsverzeichnis zu kopieren. Zum Beispiel ist eine neue Version x.yy.z
Diese Dateien müssen in das Verzeichnis kopiert werden:
~/.arduino15/packages/arduino/hardware/samd/x.yy.z/platform.txt~/.arduino15/packages/arduino/hardware/samd/x.yy.z/cores/arduino/Arduino.hDies ist obligatorisch, um den berüchtigten Arduino SAMD -Compiler -Fehler zu beheben. Siehe Arduino -Kompatibilität mit der STL (MIN und Max Makro) Verbesserung
...arm-none-eabiincludec++7.2.1bitsstl_algobase.h:243:56: error: macro "min" passed 3 arguments, but takes just 2
min(const _Tp& __a, const _Tp& __b, _Compare __comp)
Immer wenn das oben genannte Problem mit der neuen Arduino SAMD-Version behoben wird, müssen Sie die Datei Arduino.h nicht mehr kopieren.
Um ohne Fehler kompilieren zu können und bough .
Angenommen, die Adafruit SAMD -Kernversion ist 1.7.11. Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/adafruit/hardware/samd/1.7.11/platform.txt~/.arduino15/packages/adafruit/hardware/samd/1.7.11/cores/arduino/Print.h~/.arduino15/packages/adafruit/hardware/samd/1.7.11/cores/arduino/Print.cppWenn eine neue Version installiert ist, denken Sie daran, diese Datei in das neue Versionsverzeichnis zu kopieren. Beispielsweise ist eine neue Version x.yy.zz Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/platform.txt~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/cores/arduino/Print.h~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/cores/arduino/Print.cppUm ohne Fehler kompilieren zu können und board_name automatisch auf Seeduino SAMD (XIAO M0, WIO Terminal usw.) zu erkennen und anzuzeigen , müssen Sie die Dateien in Seeduino SAMD Pakages_Patches in das SAVEDUINO -SAMD -Verzeichnis (~/.arduino15/pakete/packages/seeeduino/samd/1.8.3) kopieren.
Angenommen, die Seeduino SAMD -Kernversion beträgt 1.8.3. Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/Seeeduino/hardware/samd/1.8.3/platform.txt~/.arduino15/packages/Seeeduino/hardware/samd/1.8.3/cores/arduino/Arduino.h~/.arduino15/packages/Seeeduino/hardware/samd/1.8.3/cores/arduino/Print.h~/.arduino15/packages/Seeeduino/hardware/samd/1.8.3/cores/arduino/Print.cppWenn eine neue Version installiert ist, denken Sie daran, diese Datei in das neue Versionsverzeichnis zu kopieren. Beispielsweise ist eine neue Version x.yy.zz Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/platform.txt~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/cores/arduino/Arduino.h~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/cores/arduino/Print.h~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/cores/arduino/Print.cppUm ohne Fehler kompilieren und automatisch board_name auf Sparkfun samd (xiao sparkfun_redboard_turbo, sparkfun_samd51_thing_plus) erkennen und anzeigen , müssen Sie die Datei Sparkfun SAMD Paket_Patches in Sparkfun SAMD -Direktorie (~/.HARTUINAL/PACKAGE/PACKAGES/PACKAGES/PACKAGES/PACKAGES/PACKAGES/PACKAGES/PACKAGE/PACKAGE/FACKFUN/AMd/.
Angenommen, die Sparkfun SAMD Core -Version beträgt 1.8.3. Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/SparkFun/hardware/samd/1.8.3/cores/arduino/Print.h~/.arduino15/packages/SparkFun/hardware/samd/1.8.3/cores/arduino/Print.cpp~/.arduino15/packages/SparkFun/hardware/samd/1.8.3/cores/arduino51/Print.h~/.arduino15/packages/SparkFun/hardware/samd/1.8.3/cores/arduino51/Print.cppWenn eine neue Version installiert ist, denken Sie daran, diese Datei in das neue Versionsverzeichnis zu kopieren. Beispielsweise ist eine neue Version x.yy.zz Diese Datei muss in das Verzeichnis kopiert werden:
~/.arduino15/packages/SparkFun/hardware/samd/x.yy.zz/cores/arduino/Print.h~/.arduino15/packages/SparkFun/hardware/samd/x.yy.zz/cores/arduino/Print.cpp~/.arduino15/packages/SparkFun/hardware/samd/x.yy.zz/cores/arduino51/Print.h~/.arduino15/packages/SparkFun/hardware/samd/x.yy.zz/cores/arduino51/Print.cppMultiple Definitions Linker -Fehler Die aktuelle Implementierung der Bibliothek unter Verwendung von xyz-Impl.h anstelle von Standard xyz.cpp erstellt möglicherweise bestimmte Multiple Definitions Linkerfehler in bestimmten Anwendungsfällen.
Sie können diese .hpp -Datei einfügen
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
# include " FlashStorage_SAMD.hpp " // https://github.com/khoih-prog/FlashStorage_SAMD in vielen Dateien. Verwenden Sie jedoch unbedingt die folgende .h -Datei in nur 1 .h , .cpp oder .ino -Datei , die in keiner anderen Datei enthalten sein darf, um Multiple Definitions zu vermeiden, linker
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
# include " FlashStorage_SAMD.h " // https://github.com/khoih-prog/FlashStorage_SAMD Überprüfen Sie das neue MultifileProject -Beispiel für eine HOWTO -Demo.
Schauen Sie sich die Diskussion in unterschiedlichem Verhalten unter Verwendung des SRC_CPP oder SRC_H Lib #80 an
Der Flash -Speicher hat eine begrenzte Menge an Schreibzyklen. Typische Flash -Erinnerungen können etwa 10000 Schreibzyklen in denselben Flash -Block ausführen, bevor es mit dem "Abnutzen" beginnt, und die Fähigkeit zu verlieren, Daten zu halten.
Also hüten Sie auf: Die unangemessene Verwendung dieser Bibliothek kann den Flash-Speicher Ihres Micro schnell und dauerhaft zerstören . Insbesondere sollten Sie vermeiden, die write() -Funktion zu oft aufzurufen, und sicherstellen, dass im gesamten Leben des Mikro die Anzahl der Anrufe zum write weit unterhalb der obigen Grenze von 10000 bleibt (es ist eine gute Anzahl von Dummköpfen, auch wenn der Hersteller von Micro-Garantien eine große Anzahl von Zyklen).
Die gleiche Vorsicht muss gemacht werden, wenn Sie die EEPROM -API -Emulation (siehe unten) mit der Funktion EEPROM.commit() verwenden.
Zunächst müssen Sie ein globales FlashStorage -Objekt für jede Daten deklarieren, die Sie im Flash -Speicher speichern möchten.
Wenn Sie beispielsweise das Alter einer Person speichern möchten, müssen Sie ein solches age_storage deklarieren:
FlashStorage (age_storage, int ); Diese Anweisung bedeutet "Erstellen Sie eine FlashStorage , um eine int -Variable zu speichern und sie age_storage zu nennen". Jetzt können Sie age_storage als Ort verwenden, um eine Ganzzahl sicher zu speichern:
void readAndStoreUserAge ()
{
Serial. println ( " Please enter your age: " );
String age = Serial. readStringUntil ( ' n ' );
age_storage. write (age. toInt ()); // <-- save the age
}Nach einem Reset des Mikrocontrollers zum Abrufen des gespeicherten Alters können Sie verwenden:
int user_age = age_storage.read(); Fügen Sie FlashStorage_SAMD.h ein, um eine EEPROM -Emulation mit dem internen Flash -Speicher zu erhalten.
Siehe Emulationseeeeeeeeeeeeeeakrom -Skizze für ein Beispiel.
Die API ist der bekannten API der Arduino EEPROM-Bibliothek sehr ähnlich, jedoch mit 4 zusätzlichen Funktionen:
bool isValid() gibt true zurück, wenn Daten im emulierten Effekt gültig sind (die Daten, die mindestens einmal von EEPROM.commit() oder EEPROM.put() ) geschrieben wurden. Andernfalls sind emulierte Effektdaten "undefiniert" und die Funktion gibt false zurück.void commit() speichern die EEPROM -Daten in Flash. Verwenden Sie dies mit Sorgfalt: Jeder Anruf schreibt die vollständigen emulierten E-E-E-E-Daten, um zu blinken. Dadurch werden die verbleibenden Blitzschreiberzyklen verringert. Nennen Sie diese Methode nicht in einer Schleife, sonst töten Sie Ihren Blitz bald.void setCommitASAP(bool value = true) um die private Variable _commitASAP festzulegen oder zu löschen (Standard ist true , um sicher zu sein). Wenn _commitasap falsch ist, erzwingt der Aufruf an EEPROM.put() das EEPROM.commit() nicht, die Flash -Lebensdauer zu verlängern. Sie müssen sich daran erinnern, EEPROM.commit() manuell anzurufen, um die emulierten Effektdaten in Flash zu speichern, oder Daten gehen verloren.bool getCommitASAP() , um den aktuellen Wert von _commitASAP zurückzugeben.FlashStorage_Samd/Beispiele/StorenAmandsurname/StorenAmandsurname.ino
Zeilen 26 bis 128 in 102E13E
Das Folgende ist die Ausgabe des Beispielanterminals beim Ausführen von Beispiel W5500_blynk auf Adafruit SAMD51 ITSYBitSY_M4 mit W5500 Ethernet Shield
Start W5500_Blynk on ITSYBITSY_M4
[ 936 ] ChkCrR:CrCCSum= 0xaf50 ,CrRCSum= 0xffffffff
[ 936 ] CCSum= 0x0 ,RCSum= 0x0
[ 936 ] Invalid Stored Dynamic Data. Load default from Sketch
[ 937 ] SaveEEPROM,Sz= 1024 ,DataSz= 0 ,WCSum= 0x1d4d
[ 944 ] CrCCSum= 0x29a6
[ 944 ] MAC:FE-A8- 80 -C6-CE-A3
_pinCS = 0
W5100 init, using SS_PIN_DEFAULT = 10 , new ss_pin = 10 , W5100Class::ss_pin = 1
W5100::init: W5500, SSIZE = 8192
[ 2632 ] IP: 192.168.2.153
[ 2633 ] b:Stay in CfgPortal:No CfgDat
[ 2633 ] CfgIP= 192.168.2.153
F
Your stored Credentials :
MQTT Server = default -mqtt-server
Port = 1883
MQTT UserName = default -mqtt-username
MQTT PWD = default -mqtt-password
Subs Topics = default -mqtt-SubTopic
Pubs Topics = default -mqtt-PubTopic
FFFFF
[ 339285 ] SaveEEPROM,Sz= 1024 ,DataSz= 0 ,WCSum= 0x2e89
[ 339292 ] CrCCSum= 0x219f Save => Neustart Start W5500_Blynk on ITSYBITSY_M4
[ 1547 ] ChkCrR:CrCCSum= 0x219f ,CrRCSum= 0x219f
[ 1547 ] CCSum= 0x0 ,RCSum= 0x0
[ 1548 ] CrCCSum= 0x219f ,CrRCSum= 0x219f
[ 1548 ] ======= Start Stored Config Data =======
[ 1548 ] Hdr=W5X00,BName=Seeeduino_W5500_BlynkWM
[ 1548 ] Svr=account.duckdns.org,Tok=new_token1
[ 1549 ] Svr1=account.ddns.net,Tok1=new_token2
[ 1549 ] Prt= 8080 ,SIP= 192.168.2.220
[ 1549 ] connectEthernet: Use static_IP= 192.168.2.220
[ 1549 ] MAC:FE-A1-D4-BC- E8 -CB
W5100 init, using SS_PIN_DEFAULT = 10 , new ss_pin = 10 , W5100Class::ss_pin = 1
W5100::init: W5500, SSIZE = 8192
[ 3131 ] IP: 192.168.2.220
[ 3131 ] bg:ECon.TryB
[ 3131 ]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ / '_/
/____/_/_, /_ // _/_/_
/___/ v0.6.1 on Arduino Zero
[ 3132 ] BlynkArduinoClient.connect: Connecting to account.duckdns.org: 8080
[ 3244 ] Ready (ping: 6ms).
[ 3311 ] Connected to BlynkServer=account.duckdns.org,Token=new_token1
[ 3311 ] bg:EBCon
Conn2Blynk: server = account.duckdns.org, port = 8080
Token = new_token1, IP = 192.168.2.220
B
Your stored Credentials :
MQTT Server = new -mqtt-server
Port = 1883
MQTT UserName = new -mqtt-username
MQTT PWD = new -mqtt-password
Subs Topics = new -mqtt-SubTopic
Pubs Topics = new -mqtt-PubTopic
BBBBBBBBB BBBBBBBBBB BBBBBBBBBB BBBBBBBBBB BBBBBBBBBB BBBBBBBBBB BBBBBBBBBBStart StoreNameAndSurname on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
EEPROM length: 1024
EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:
Insert your name : John
Insert your surname : Doe
<< Your name: John. Your surname: Doe >> have been saved. Thank you!
You can reset to check emulated-EEPROM data retention.Start StoreNameAndSurname on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
EEPROM length: 1024
Hi John Doe, nice to see you again :-)
Clearing WRITTEN_SIGNATURE for next try
Done clearing signature in emulated EEPROM. You can reset nowStart EEPROM_Clear on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
Emulated EEPROM length (bytes) = 1024
Done clearing emulated EEPROM. Time spent (ms) = 11
Start EEPROM_Clear on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
Emulated EEPROM length (bytes) = 2048
Done clearing emulated EEPROM. Time spent (ms) = 22Start EEPROM_Clear on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
Emulated EEPROM length (bytes) = 4096
Done clearing emulated EEPROM. Time spent (ms) = 42Start EEPROM_get on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
EEPROM length: 1024
EEPROM doesn ' t store valid data, writing WRITTEN_SIGNATURE and some example data
Float written to EEPROM: 123.456
Done writing custom object to EEPROM:
===============
Field1: 3.14159
Field2: 65
Name: Working!
===============
Reset to see how you can retrieve the values by using EEPROM_get! Start EEPROM_get on SEEED_XIAO_M0
FlashStorage_SAMD v1 .3.2
EEPROM length: 1024
EEPROM has valid data with WRITTEN_SIGNATURE. Now read some example data
Read float from EEPROM: 123.456
Read custom object from EEPROM:
===============
Field1: 3.14159
Field2: 65
Name: Working!
=============== Ja, Sie können eine struct mit mehr Feldern deklarieren und einen EEPROM.put() anrufen, um die gesamte Struktur zu speichern. Sehen Sie sich den StorlenAmands -Name an, wie es geht.
Ja, jedes Mal, wenn Sie eine neue Skizze hochladen, wird der vorherige Inhalt des FlashStorage gelöscht.
Nein. Wenn Ihr Vorstand ein integriertes E-E-E-E-E-E-E-E-E-Eanz bietet, ist es ratsam, dies zu verwenden, da EEPROM eine längere Lebensdauer, die Anzahl der Schreibzyklen usw. hat).
In Ermangelung eines integrierten Effekts oder seiner Größe ist zu klein für Ihren Anwendungsfall. Sie können diese Bibliothek verwenden, um einen kleinen Portions-Flash-Speicher als emuliertes E-Effekt zu verwenden, sofern Sie die Grenzen wie in begrenzter Anzahl von Schreibungen beachten,
Wenn Sie Kompilierungsfehler erhalten, müssen Sie möglicherweise eine neuere Version des Kerns für Arduino -Boards installieren.
Manchmal funktioniert die Bibliothek nur, wenn Sie den Board Core auf die neueste Version aktualisieren, da ich neu hinzugefügte Funktionen verwende.
Senden Sie Probleme an: FlashStorage_Samd -Probleme
EEPROM.put() und EEPROM.get() Funktionen zum Lesen/Schreiben der gesamten Struktur in emuliertem Effektmultiple-definitions für Linkerfehler.SAMD21E1xA , SAMD21G1xA und SAMD21J1xA![]() Cristian Maglie |
Wenn Sie zu diesem Projekt beitragen möchten: