Multiple Definitions 링커 오류를 수정하는 방법 Multiple Definitions 링커 오류를 수정하는 방법을 살펴보십시오.
Cristian Maglie 's FlashStorage에서 영감을 얻은 FlashStorage_STM32F1 라이브러리는 Genuine CH32F103XX, CS32F103XX 등을 포함하여 STM32F1/F3의 비 휘발성 플래시 메모리에서 Emulated-Eyprom을 사용하여 사용자 데이터를 저장하고 검색하는 편리한 방법을 제공합니다.
일반적으로 펌웨어 코드를 저장하는 데 사용되는 플래시 메모리는 더 많은 사용자의 데이터를 저장 / 검색하는 데 사용될 수 있으며 EEPROM보다 빠릅니다. 버퍼링 된 데이터 작성 및 읽기 덕분에 플래시 액세스 시간이 크게 줄어들어 플래시 수명을 높입니다 .
현재 라이브러리는 새로운 STM32 Core v2.0.0 및 이전 STM32 Core v1.9.0을 모두 지원합니다.
Arduino IDE 1.8.19+ .Arduino Core for STM32 v2.3.0+ . 가장 좋은 방법은 Arduino Library Manager 사용하는 것입니다. FlashStorage_STM32F1을 검색 한 다음 최신 버전을 선택 / 설치하십시오. 자세한 지침을 위해이 링크를 사용할 수도 있습니다.
설치하는 또 다른 방법은 다음과 같습니다.
FlashStorage_STM32F1-main.zip 다운로드하십시오.FlashStorage_STM32F1-main 디렉토리로 추출하십시오FlashStorage_STM32F1-main 폴더를 ~/Arduino/libraries/ 와 같은 Arduino 라이브러리 디렉토리에 복사하십시오. LAN8720 사용하여 STM32F407VE 와 같은 Generic STM32F4 series 보드의 경우 STM32 Core v2.2.0 사용하여 Core v2.3.0 사용하면 컴파일 오류가 생성됩니다.
일부 STM32 보드에서 LAN8720을 사용합니다
파일 STM32F4XX_HAL_CONF_DEFAULT.H 및 STM32F7XX_HAL_CONF_DEFAULT.H를 STM32 STM32 디렉토리 (~/.arduino15/packages/stm32/stm32/stm32/2.2.0/system)에 복사해야합니다.
STM32 STM32 코어 버전이 2.2.0이라고 가정합니다. 이 파일은 디렉토리에 복사해야합니다.
~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F4xx/stm32f4xx_hal_conf_default.h .~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F7xx/stm32f7xx_hal_conf_default.h새 버전이 설치 될 때 마다이 파일을 새 버전 디렉토리에 복사하십시오. 예를 들어 새 버전은 x.yy.zz 이므로이 파일은 해당 디렉토리에 복사해야합니다.
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F4xx/stm32f4xx_hal_conf_default.hSerial1 정의가없는 일부 STM32 보드에서 Serial1을 사용하려면 (Nucleo-144 Nucleo_F767ZI, Nucleo-64 Nucleo-64 Nucleo_L053R8 등) 보드를 STM32 Variant.h를 STM32 STM32 디렉토리에 복사해야합니다 (~/.arduino15/stm32/hardware/stm32/0.0). 보드에 해당하는 파일을 수정해야합니다. 이것은 단지 수행 방법 일뿐입니다.
STM32 STM32 코어 버전이 2.3.0이라고 가정합니다. 이 파일은 디렉토리에 복사해야합니다.
~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_F767ZI/variant.h 의 경우 nucleo_f767zi.~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_L053R8/variant.h 의 경우 핵.새 버전이 설치 될 때 마다이 파일을 새 버전 디렉토리에 복사하십시오. 예를 들어 새 버전은 x.yy.zz 이므로이 파일은 해당 디렉토리에 복사해야합니다.
~/.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 링커 오류를 수정하는 방법 표준 xyz.cpp 대신 xyz-Impl.h 사용하는 현재 라이브러리 구현은 특정 사용 사례에서 특정 Multiple Definitions 링커 오류를 생성 할 수 있습니다.
이 .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 많은 파일에서. 그러나 Multiple Definitions 링커 오류를 피하기 위해 다른 파일에 포함되지 않아야 하는 .h , .cpp 또는 .ino 파일로 다음 .h 파일을 사용하십시오.
// 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 HOWTO 데모에 대한 새로운 다중 공장 예제를 확인하십시오.
src_cpp 또는 src_h lib #80을 사용하여 다른 행동에서 토론을 살펴보십시오.
플래시 메모리에는 제한된 양의 쓰기주기가 있습니다. 일반적인 플래시 메모리는 "마모"를 시작하기 전에 약 100000을 동일한 플래시 블록에 기록하고 데이터를 유지하는 능력을 잃기 시작할 수 있습니다.
따라서이 라이브러리의 임박한 사용은 마이크로의 플래시 메모리를 빠르고 영구적으로 파괴 할 수 있습니다 . 특히 put() 또는 commit() 기능을 너무 자주 호출하지 않고 Micro의 전체 수명에서 put() 또는 commit() 의 통화 수를 10000의 한계보다 훨씬 낮게 유지해야합니다 (마이크로 보증을 유지하더라도 그 수를 크게 유지하기 위해서는 좋은 규칙을 유지하는 것이 좋습니다.
내부 플래시 메모리와 함께 EEPROM 에뮬레이션을 얻으려면 FlashStorage_STM32F1.h 포함시킵니다.
예를 들어 EmulateEeprom 스케치를 참조하십시오.
API는 잘 알려진 Arduino Eeprom.h API와 매우 유사하지만 4 개의 추가 기능이 있습니다.
bool isValid() Emulated-Eyprom의 데이터가 유효한 경우 true 반환합니다 ( EEPROM.commit() 또는 EEPROM.put() 에 의해 적어도 한 번은 플래시에 기록 된 데이터). 그렇지 않으면 에뮬레이션 된 -eeprom 데이터는 "정의되지 않은"상태이며 함수는 false 반환합니다.void commit() eeprom 데이터를 플래시로 저장합니다. 신중하게 사용하십시오 : 모든 통화는 전체 에뮬레이션 된 가파른 데이터를 플래시하기 위해 작성합니다. 이렇게하면 나머지 플래시-쓰레기 사이클이 줄어 듭니다. 이 방법을 루프로 호출하지 마십시오. 그렇지 않으면 곧 플래시를 죽일 것입니다.void setCommitASAP(bool value = true) _commitASAP 개인 변수를 설정하거나 지우려면 (기본값은 안전 true ). _commitasap이 false 인 경우 EEPROM.put() 에 대한 호출은 EEPROM.commit() 플래시 수명을 연장하도록 강요하지 않습니다. 에뮬레이션 된 -eeprom 데이터를 플래시로 저장하려면 EEPROM.commit() 에게 수동으로 호출해야합니다. 그렇지 않으면 데이터가 손실됩니다.bool getCommitASAP() _commitASAP 의 현재 값을 반환합니다.FlashStorage_stm32f1/examples/FlashStoreAndrecreve/FlashStoreAndretrieve.ino
CB76B66의 26 ~ 81 행
다음은 STM32F1에서 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 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!
===============다음은 STM32F1에서 FlashStoreAndrecreve 예제를 실행할 때의 샘플 터미널 출력입니다.
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 now다음은 128KB 플래시를 사용하여 STM32F1 BLUEPILL_F103C8에서 EEPROM_WRITE 예제를 실행할 때의 샘플 터미널 출력입니다.
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) = 0다음은 128KB 플래시를 사용하여 STM32F1 BLUEPILL_F103C8에서 EMPERMAPROM 예제를 실행할 때의 샘플 터미널 출력입니다.
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 now다음은 STM32F1 Generic_F103RCTX에서 2564KB Flash에서 FlashStoreAndrecreve 예제를 실행할 때의 샘플 터미널 출력입니다.

| stlink | <---> | generic_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 예, 더 많은 필드가있는 struct 선언하고 전체 구조를 저장하기 위해 EEPROM.put() 호출 할 수 있습니다. 어떻게하는 방법에 대해서는 StorenameAndsurname을 참조하십시오.
STM32F1/F3이 아닙니다.
아니요. 보드가 통합 가프 그롬을 제공하는 경우 EEPROM이 수명이 길고, 쓰기주기 수 등이 있기 때문에 사용하는 것이 좋습니다).
통합 가프 그롬이 없거나 크기가 너무 작지 않는 경우, 제한된 수의 쓰기로 제한을 명심하면이 라이브러리를 사용하여 작은 부분 플래시 메모리를 에뮬레이션 된 가파른 메모리로 사용할 수 있습니다.
컴파일 오류가 발생하면 종종 아르두노 보드 용 코어 버전을 설치해야 할 수도 있습니다.
때로는 새로 추가 된 기능을 사용하고 있기 때문에 보드 코어를 최신 버전으로 업데이트하는 경우에만 라이브러리가 작동합니다.
다음과 같은 문제를 제출하십시오 : FlashStorage_STM32F1 문제
EEPROM.put() 및 EEPROM.get() 함수를 추가하여 Emulated-Eyprom에서 전체 구조물을 읽고 쓰십시오.multiple-definitions 링커 오류를 수정하십시오.버그보고, 새로운 기능 제안, 테스트 및이 라이브러리 개발에 대한 모든 분들께 감사드립니다.
![]() 크리스티안 마그리 |
이 프로젝트에 기여하려면 :
저작권 (C) 2021- 코이 호랑