Multiple Definitions Error de enlazador Eche un vistazo a cómo solucionar Multiple Definitions Error de enlazador
La biblioteca FlashStorage_STM32, inspirada en el FlashStorage de Cristian Maglie, proporciona una forma conveniente de almacenar y recuperar los datos del usuario utilizando EMULET-EPROM, desde la memoria flash no volátil de STM32F/L/H/G/WB/MP1.
La memoria flash, generalmente utilizada para almacenar el código de firmware, también se puede utilizar para almacenar / recuperar más datos del usuario y más rápido que EEPROM. Gracias a la escritura y lectura de datos almacenados , el tiempo de acceso flash se reduce enormemente para aumentar la vida útil del flash .
Actualmente, la biblioteca admite tanto STM32 Core V2.0.0+ y STM32 Core V1.9.0- anterior
Arduino IDE 1.8.19+ para Arduino.Arduino Core for STM32 v2.3.0+ para tableros STM32. La mejor y más fácil forma es usar Arduino Library Manager . Busque FlashStorage_STM32 , luego seleccione / instale la última versión. También puede usar este enlace para instrucciones más detalladas.
Otra forma de instalar es:
FlashStorage_STM32-main.zip .FlashStorage_STM32-mainFlashStorage_STM32-main en el directorio de las bibliotecas de Arduino, como ~/Arduino/libraries/ . Para los placas Generic STM32F4 series , como STM32F407VE , usando LAN8720 , use STM32 Core v2.2.0 como Breaking Core v2.3.0 crea el error de compilación.
Para usar LAN8720 en algunos tableros STM32
Tiene que copiar los archivos STM32F4XX_HAL_CONF_DEFAULT.H y STM32F7XX_HAL_CONF_DEFAULT.H en el directorio STM32 STM32 (~/.arduino15/paquete/stm32/hardware/stm32/2.2.0/sistema) para sobrescribir los archivos antiguos.
Suponiendo que la versión Core STM32 STM32 es 2.2.0. Estos archivos deben copiarse en el directorio:
~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F4xx/stm32f4xx_hal_conf_default.h para stm32f4.~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F7xx/stm32f7xx_hal_conf_default.h para nucleo-144 stm32f7.Cada vez que se instala una nueva versión, recuerde copiar este archivo en el directorio de nueva versión. Por ejemplo, la nueva versión es x.yy.zz, estos archivos deben copiarse en el directorio correspondiente:
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F4xx/stm32f4xx_hal_conf_default.hPara usar Serial1 en algunos placas STM32 sin la definición Serial1 (Nucleo-144 Nucleo_F767Zi, Nucleo-64 Nucleo_L053R8, etc.) Boards , debe copiar los archivos STM32 Variant.h en Directory STM32 STM32 (~/.arduino15/paquete/STM32/hardware/STM32/2.3.0). Debe modificar los archivos correspondientes a sus tableros, esto es solo una ilustración cómo hacer.
Suponiendo que la versión Core STM32 STM32 es 2.3.0. Estos archivos deben copiarse en el directorio:
~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_F767ZI/variant.h para nucleo-144 nucleo_f767zi.~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_L053R8/variant.h para nucleo-64 nucleo_l053r8.Cada vez que se instala una nueva versión, recuerde copiar este archivo en el directorio de nueva versión. Por ejemplo, la nueva versión es x.yy.zz, estos archivos deben copiarse en el directorio correspondiente:
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/NUCLEO_F767ZI/variant.h~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/NUCLEO_L053R8/variant.hMultiple Definitions Error de enlazador La implementación actual de la biblioteca, utilizando xyz-Impl.h en lugar del estándar xyz.cpp , posiblemente crea ciertos errores de enlazador Multiple Definitions en ciertos casos de uso.
Puede incluir este archivo .hpp
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
# include " FlashStorage_STM32.hpp " // https://github.com/khoih-prog/FlashStorage_STM32 en muchos archivos. Pero asegúrese de usar el siguiente archivo .h en solo 1 .h , .cpp o archivo .ino , que no debe incluirse en ningún otro archivo , para evitar Multiple Definitions Error de enlazador
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
# include " FlashStorage_STM32.h " // https://github.com/khoih-prog/FlashStorage_STM32 Verifique el nuevo ejemplo de mulifileproject para obtener una demostración HOWTO .
Eche un vistazo a la discusión en un comportamiento diferente utilizando el src_cpp o src_h lib #80
La memoria flash tiene una cantidad limitada de ciclos de escritura. Los recuerdos de flash típicos pueden realizar alrededor de 10000 ciclos de escritura al mismo bloque de flash antes de comenzar a "desgastarse" y comenzar a perder la capacidad de retener datos.
Por lo tanto , tenga cuidado: el uso inadecuado de esta biblioteca puede destruir de manera rápida y permanente la memoria flash de su micro , en particular que debe evitar llamar a las funciones put() o commit() con demasiada frecuencia y asegurarse de que en toda la vida de la vida micro del número de llamadas a put() o commit() se mantenga muy por debajo del límite anterior de 10000 (es una buena regla de tumba para tener ese número en la mente si el fabricante de los fabricantes de los micrones un micro un número más grande de ciclos).
Incluya FlashStorage_STM32.h para obtener una emulación de EEPROM con la memoria flash interna.
Vea el boceto EmulateeProm para obtener un ejemplo.
La API es muy similar a la conocida API Arduino Eeprom.H pero con 4 funciones adicionales:
bool isValid() devuelve true si los datos en el EeProm emulado son válidos (los datos escritos para flashear al menos una vez por EEPROM.commit() o EEPROM.put() ). De lo contrario, los datos emulados-EEPR están "indefinidos" y la función devuelve false .void commit() almacene los datos de EEPROM en flash. Use esto con cuidado: cada llamada escribe los datos completos de EEGROM emulados para flash. Esto reducirá los ciclos de escritura flash restantes. No llame a este método en un bucle o pronto matará su flash.void setCommitASAP(bool value = true) para establecer o borrar la variable privada _commitASAP (el valor predeterminado es true para ser seguro). Si _ComMitasAP es falso, la llamada a EEPROM.put() no obligará al EEPROM.commit() a extender la vida flash. Tendrá que recordar llamar EEPROM.commit() manualmente para guardar los datos emulados-EEPR en Flash o se perderán los datos.bool getCommitASAP() para devolver el valor actual de _commitASAP .Bi_ethernet_blynk
Bi_ethernet_blynk_email
Bi_ethernet_wm_config
LAN8720_ETHERNET_BLYNK
Lan8720_ethernet_blynk_email
LAN8720_ETHERNET_WM_CONFIG
......
Y vienen muchas más a las bibliotecas.
FlashStorage_STM32/ejemplos/storenameandndsurname/storenameanddsurname.ino
Líneas 15 a 106 en BB0DD71
La siguiente es la salida del terminal de muestra cuando se ejecuta Ethernet_stm32_lan8720 en STM32F4 Black_F407VE con LAN8720 Ethernet usando la biblioteca STM32Ternet.
Start Ethernet_STM32_LAN8720 on BLACK_F407VE
Ethernet Shield type : LAN8720 Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1 .3.2
DoubleResetDetector_Generic v1 .8.1
EEPROM size = 16384 , start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] EEPROMsz: 4096
[ETM] EEPROM Length ():16384
[ETM] CCSum=0xaed,RCSum=0x4d385471
[ETM] ChkCrR:CrCCsum=0x21dd,CrRCsum=0x3338
[ETM] InitCfgFile,sz=60
[ETM] SaveEEPROM,Sz=16384,DataSz=0,WCSum=0x569
[ETM] CrCCSum=0xc30
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-98-FC-DD-D9-BA
[ETM] Dynamic IP OK, connected
[ETM] IP:192.168.2.169
[ETM] bg: isForcedConfigPortal = false
[ETM] bg:Stay forever in CP:No ConfigDat
Connected! IP address: 192.168.2.169
Your stored Credentials :
MQTT Server = blank
Port = blank
MQTT UserName = blank
MQTT PWD = blank
Subs Topics = blank
Pubs Topics = blank
HStop doubleResetDetecting
ClearFlag write = 0xd0d04321
HHHHH[ETM] h:Updating EEPROM. Please wait for reset
[ETM] SaveEEPROM,Sz=16384,DataSz=0,WCSum=0x729
[ETM] CrCCSum=0x1087
[ETM] h:Rst
Start Ethernet_STM32_LAN8720 on BLACK_F407VE
Ethernet Shield type : LAN8720 Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1 .3.2
DoubleResetDetector_Generic v1 .8.1
EEPROM size = 16384 , start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] EEPROMsz: 4096
[ETM] EEPROM Length ():16384
[ETM] CCSum=0x729,RCSum=0x729
[ETM] ChkCrR:CrCCsum=0x1087,CrRCsum=0x1087
[ETM] CrCCSum=1087,CrRCSum=1087
[ETM] Valid Stored Dynamic Data
[ETM] ======= Start Stored Config Data =======
[ETM] Header=STM32, BoardName=Black_V407VE
[ETM] StaticIP=blank
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-98-FD-D6-DA-BA
[ETM] Dynamic IP OK, connected
[ETM] IP:192.168.2.170
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.170
Your stored Credentials :
MQTT Server = mqtt_server
Port = 1883
MQTT UserName = mqtt_user
MQTT PWD = mqtt_pass
Subs Topics = Subs
Pubs Topics = Pubs
HStop doubleResetDetecting
ClearFlag write = 0xd0d04321
HSetFlag write = 0xd0d01234
[ETM] EEPROMsz:4096
[ETM] EEPROM Length():16384
[ETM] CCSum=0x729,RCSum=0x729
[ETM] ChkCrR:CrCCsum=0x1087,CrRCsum=0x1087
[ETM] CrCCSum=1087,CrRCSum=1087
[ETM] Valid Stored Dynamic Data
[ETM] ======= Start Stored Config Data =======
[ETM] Header=STM32, BoardName=Black_V407VE
[ETM] StaticIP=blank
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-98-FD-D6-DB-BA
[ETM] Dynamic IP OK, connected
[ETM] IP:192.168.2.149
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.149
Your stored Credentials :
MQTT Server = mqtt_server
Port = 1883
MQTT UserName = mqtt_user
MQTT PWD = mqtt_pass
Subs Topics = Subs
Pubs Topics = Pubs
HStop doubleResetDetecting
ClearFlag write = 0xd0d04321
HHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH
HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH
HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH
HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HLa siguiente es la salida del terminal de muestra cuando se ejecuta el ejemplo de StorenamEndsurname en STM32H7 NUCLEO-144 NUCLEO_H743ZI2
Start StoreNameAndSurname on NUCLEO_H743ZI2
FlashStorage_STM32 v1 .2.0
EEPROM length: 16384
EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:
Insert your name : My_Name
Insert your surname : My_Surname
<< Your name: My_Name
. Your surname: My_Surname
>> have been saved. Thank you!Start StoreNameAndSurname on NUCLEO_H743ZI2
FlashStorage_STM32 v1 .2.0
EEPROM length: 16384
Hi My_Name
My_Surname
, nice to see you again :-)
Clearing WRITTEN_SIGNATURE for next try
Done clearing signature in emulated EEPROM. You can reset nowLa siguiente es la salida del terminal de muestra cuando se ejecuta el ejemplo de StorenameAndsurname en STM32L5 NUCLEO-144 NUCLEO_L552ZE_Q
Start StoreNameAndSurname on NUCLEO_L552ZE_Q
FlashStorage_STM32 v1 .2.0
EEPROM length: 2048
EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:
Insert your name : My_Name
Insert your surname : My_Surname
<< Your name: My_Name
. Your surname: My_Surname
>> have been saved. Thank you!Start StoreNameAndSurname on NUCLEO_L552ZE_Q
FlashStorage_STM32 v1 .2.0
EEPROM length: 2048
Hi My_Name
My_Surname
, nice to see you again :-)
Clearing WRITTEN_SIGNATURE for next try
Done clearing signature in emulated EEPROM. You can reset nowLa siguiente es la salida del terminal de muestra al ejecutar el ejemplo de StorenameAndsurname en STM32F7 Nucleo-144 Nucleo_F767Zi
Start StoreNameAndSurname on NUCLEO_F767ZI
FlashStorage_STM32 v1 .2.0
EEPROM length: 16384
EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:
Insert your name : My_Name
Insert your surname : My_Surname
<< Your name: My_Name
. Your surname: My_Surname
>> have been saved. Thank you!Start StoreNameAndSurname on NUCLEO_F767ZI
FlashStorage_STM32 v1 .2.0
EEPROM length: 16384
Hi My_Name
My_Surname
, nice to see you again :-)
Clearing WRITTEN_SIGNATURE for next try
Done clearing signature in emulated EEPROM. You can reset now Sí, puede declarar una struct con más campos y llamar a un EEPROM.put() para almacenar toda la estructura. Vea el Storenameandndsurname sobre cómo hacerlo.
No con STM32.
No. Si su junta proporciona un EEGROMEPROM integrado, es aconsejable usarlo porque EEPROM tiene una vida útil más larga, número de ciclos de escritura, etc.).
En ausencia de una E-Ee-Errem o su tamaño integrado es demasiado pequeño para su caso de uso, puede usar esta biblioteca para usar una memoria de una pequeña porción de memoria Flash como emulada-Error, siempre que tenga en cuenta los límites como en un número limitado de escrituras.
Si recibe errores de compilación, la mayoría de las veces, es posible que deba instalar una versión más nueva del núcleo para las tablas Arduino.
A veces, la biblioteca solo funcionará si actualiza el núcleo del tablero a la última versión porque estoy usando funciones recientemente agregadas.
Enviar problemas a: FlashStorage_STM32 Problemas
multiple-definitions .allman Style. Restile la bibliotecaMuchas gracias por todos por los informes de errores, una nueva función que sugieren, pruebas y contribuyen al desarrollo de esta biblioteca.
![]() Maglie de Cristian |
Si desea contribuir a este proyecto:
Copyright (c) 2021- Khoi Hoang