Multiple Definitions鏈接器錯誤請查看如何修復Multiple Definitions鏈接器錯誤
FlashStorage_stm32f1庫受到Cristian Maglie的FlashStorage的啟發,它提供了一種便利的方法,可以從STM32F1/F3的非揮發性閃存中使用模擬 - EPROM存儲和檢索用戶的數據,包括非生機的ch32f103xx,CS32F103XX,CS32F103XX,等等。
通常用於存儲固件代碼的閃存也可以用來存儲 /檢索用戶的數據更多,並且比EEPROM更快。得益於緩衝的數據編寫和閱讀,閃光訪問時間大大減少以增加閃光燈的壽命。
目前,該庫支持新的STM32 Core v2.0.0和先前的STM32 Core v1.9.0
Arduino IDE 1.8.19+ for Arduino。Arduino Core for STM32 v2.3.0+ 。 最好和最簡單的方法是使用Arduino Library Manager 。搜索flashstorage_stm32f1 ,然後選擇 /安裝最新版本。您也可以使用此鏈接以獲取更詳細的說明。
安裝的另一種方法是:
FlashStorage_STM32F1-main.zip 。FlashStorage_STM32F1-main目錄FlashStorage_STM32F1-main文件夾複製到arduino庫的目錄,例如~/Arduino/libraries/ 。對於使用LAN8720的Generic STM32F4 series板,例如STM32F407VE ,請使用STM32 Core v2.2.0作為Breaking Core v2.3.0會產生編譯錯誤。
在某些STM32板上使用LAN8720
您必須將文件STM32F4XX_HAL_CONF_DEFAULT.H和STM32F7XX_HAL_HAL_CONF_DEFAULT.H複製到STM32 STM32 Directory(〜/.arduino15/packages/stm32/stm32/hardware/hardware/stm32/2.2.0/systep)中,以覆蓋舊文件。
假設STM32 STM32核心版本為2.2.0。這些文件必須複製到目錄中:
~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F4xx/stm32f4xx_hal_conf_default.h for stm32f4。~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F7xx/stm32f7xx_hal_conf_default.h用於nucleo-144 stm32f7。每當安裝新版本時,請記住將此文件複製到新版本目錄中。例如,新版本是x.yy.zz,這些文件必須複製到相應的目錄中:
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F4xx/stm32f4xx_hal_conf_default.hTo use Serial1 on some STM32 boards without Serial1 definition (Nucleo-144 NUCLEO_F767ZI, Nucleo-64 NUCLEO_L053R8, etc.) boards , you have to copy the files STM32 variant.h into STM32 stm32 directory (~/.arduino15/packages/STM32/hardware/stm32/2.3.0).您必須修改與董事會相對應的文件,這只是一個插圖。
假設STM32 STM32核心版本為2.3.0。這些文件必須複製到目錄中:
~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_F767ZI/variant.h用於nucleo-144 nucleo_f767zi。~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_L053R8/variant.h用於nucleo-64 nucleo_l053r8。每當安裝新版本時,請記住將此文件複製到新版本目錄中。例如,新版本是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-Impl.h而不是標準xyz.cpp的當前庫實現可能會在某些用例中創建某些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在許多文件中。但是,請確保僅在1 .h , .cpp或.ino文件中使用以下.h文件(不得包含在任何其他文件中),以避免Multiple Definitions鏈接器錯誤
// 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來查看不同行為的討論
閃存的寫週期數量有限。典型的閃光記憶可以在開始“磨損”之前,可以將大約10000個循環寫入同一閃存塊,並開始失去保留數據的能力。
因此,請當心:不當使用該庫可以迅速而永久破壞您的微觀的閃存,特別是您應該避免撥打put()或commit()函數,並確保在微觀的一生中確保put()或commits()或commit()的次數()保持在10000的限制以下(即使是較大的數量,也可以保持較大的數量,以確保較大的數量。
包括FlashStorage_STM32F1.h ,以獲得內部閃存的EEPROM仿真。
有關一個示例,請參見EmulateEprom草圖。
API與眾所周知的Arduino eeprom.h API非常相似,但具有4個其他功能:
EEPROM.commit()或EEPROM.put() )編寫給flash一次的數據,則bool isValid()將返回true 。否則,模擬 - EPROM數據是“未定義的”,並且該函數返回false 。void commit()將EEPROM數據存儲在Flash中。小心地使用此功能:每個呼叫都將完整的模擬 - EPROM數據寫入閃存。這將減少剩餘的閃光燈循環。不要以循環方式調用此方法,否則您會盡快殺死閃光燈。void setCommitASAP(bool value = true)設置或清除_commitASAP private變量(默認是true )。如果_commitasap為false,則呼叫EEPROM.put()不會迫使EEPROM.commit()延長閃存壽命。您必須記住要手動調用EEPROM.commit()以將模擬 - EPROM數據保存到閃存中,否則將丟失數據。bool getCommitASAP()返回_commitASAP的當前值。flashstorage_stm32f1/示例/flashstoreandretrieve/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 BluePill_F103C8上運行示例flashstoreanDretrieve時的樣本終端輸出
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以下是運行示例示例eprom_write在stm32f1 bluepill_f103c8上使用128kb flash上的示例終端輸出
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以下是在運行示例啟用STM32F1 BLUEPILL_F103C8上的樣本終端輸出,帶有128KB閃存
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上運行示例flashstoreandretrieve時的示例終端輸出

| 靜止 | <---> | 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。
否。如果您的董事會提供了一個集成的EPROM,則建議使用它,因為EEPROM的壽命更長,寫週期數等)。
在沒有集成的EPROM或其大小太小的情況下,對於您的用例來說,您可以使用此庫將較小的閃存作為模擬EPROM,前提
如果您遇到彙編錯誤,則通常需要安裝Arduino Board的核心版本的較新版本。
有時,只有在您使用新添加的功能時,只有將板核更新為最新版本時,庫才能正常工作。
提交問題:flashstorage_stm32f1問題
EEPROM.put()和EEPROM.get()函數以讀取/寫入仿真 - eprommultiple-definitions鏈接器錯誤。非常感謝大家的錯誤報告,新功能建議,測試和為該庫的開發做出貢獻。
![]() 克里斯蒂安·瑪格麗(Cristian Maglie) |
如果您想為這個項目做出貢獻:
版權(C)2021- Khoi Hoang