Multiple Definitions Error de enlazador Eche un vistazo a cómo solucionar Multiple Definitions Error de enlazador
La biblioteca FlashStorage_STM32F1, inspirada en el FlashStorage de Cristian Maglie, proporciona una forma conveniente de almacenar y recuperar los datos del usuario utilizando EMULET-EPROM, de la memoria flash no volátil de STM32F1/F3, incluidas las no genuinas CH32F103XX, CS32F103XX, etc. Boards.
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 es compatible con 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_STM32F1 , luego seleccione / instale la última versión. También puede usar este enlace para instrucciones más detalladas.
Otra forma de instalar es:
FlashStorage_STM32F1-main.zip .FlashStorage_STM32F1-mainFlashStorage_STM32F1-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_STM32F1.hpp " // https://github.com/khoih-prog/FlashStorage_STM32F1 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_STM32F1.h " // https://github.com/khoih-prog/FlashStorage_STM32F1 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_STM32F1.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 .FlashStorage_STM32F1/Ejemplos/FlashStoreanDrieve/FlashStoreAndretrieve.ino
Líneas 26 a 81 en CB76B66
La siguiente es la salida del terminal de muestra al ejecutar el ejemplo EEPROM_GET en STM32F1 BLUEPILL_F103C8 con flash de 64kb
Start EEPROM_get on BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x800F800
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 64
[FLASH] USING_FLASH_SECTOR_NUMBER = 62
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 BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x800F800
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 64
[FLASH] USING_FLASH_SECTOR_NUMBER = 62
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!
===============La siguiente es la salida del terminal de muestra al ejecutar el ejemplo FlashStoreanDretrieve en STM32F1 BLUEPILL_F103C8 con flash de 64 kb
Start FlashStoreAndRetrieve on BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x800FC00
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 64
[FLASH] USING_FLASH_SECTOR_NUMBER = 63
Number = 0x0
Done writing to emulated EEPROM. You can reset nowStart FlashStoreAndRetrieve on BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x800FC00
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 64
[FLASH] USING_FLASH_SECTOR_NUMBER = 63
Number = 0x1
Done writing to emulated EEPROM. You can reset nowLa siguiente es la salida del terminal de muestra al ejecutar el ejemplo EEPROM_WRITE en STM32F1 BLUEPILL_F103C8 con Flash de 128 kb
Start EEPROM_write on BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x801F800
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 128
[FLASH] USING_FLASH_SECTOR_NUMBER = 126
Done writing emulated EEPROM. Time spent (ms) = 29
Done writing emulated EEPROM. Time spent (ms) = 0
Done writing emulated EEPROM. Time spent (ms) = 0
Done writing emulated EEPROM. Time spent (ms) = 0
Done writing emulated EEPROM. Time spent (ms) = 0
Done writing emulated EEPROM. Time spent (ms) = 0La siguiente es la salida del terminal de muestra cuando se ejecuta el ejemplo emulado, EMULETEPROM en STM32F1 BLUEPILL_F103C8 con Flash de 128 kb
Start EmulatedEEPROM on BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x801FC00
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 128
[FLASH] USING_FLASH_SECTOR_NUMBER = 127
EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:
-> 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
Done writing to emulated EEPROM. You can reset now to testStart EmulatedEEPROM on BLUEPILL_F103C8
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x801FC00
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 128
[FLASH] USING_FLASH_SECTOR_NUMBER = 127
EEPROM has been written.Signature = 0xBEEFDEED
Here is the content of the next 16 bytes:
-> 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 11913
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 FlashStoreanDretrieve en STM32F1 Generic_F103RCTX con Flash de 2564 kb

| Stlink | <---> | Genérico_f103rctx |
|---|---|---|
| Swclk | <---> | SWCLK / PA14 |
| Swdio | <---> | SWDIO / PA13 |
| Gnd | <---> | Gnd |
| 3.3V | <---> | 3.3V |
Start FlashStoreAndRetrieve on GENERIC_F103RCTX
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x803F800
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 256
[FLASH] USING_FLASH_SECTOR_NUMBER = 254
Number = 0xFFFFFFFF
Done writing to emulated EEPROM. You can reset nowStart FlashStoreAndRetrieve on GENERIC_F103RCTX
FlashStorage_STM32F1 v1 .1.0
EEPROM length: 1019
Start Flash Address: 0x803F800
[FLASH] REGISTERED_NUMBER_FLASH_SECTORS (KB) = 256
[FLASH] USING_FLASH_SECTOR_NUMBER = 254
Number = 0x0
Done writing to 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 STM32F1/F3.
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_STM32F1 Problemas
EEPROM.put() y EEPROM.get() para leer/escribir toda la estructura en EMULET-EPROMmultiple-definitions .Muchas 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