Multiple Definitions จำกัดความของตัวเชื่อมโยง โปรดดูวิธีแก้ไข Multiple Definitions จำกัดความของ linker
ไลบรารี FlashStorage_STM32 ซึ่งได้รับแรงบันดาลใจจาก FlashStorage ของ Cristian Maglie เป็นวิธีที่สะดวกในการจัดเก็บและดึงข้อมูลของผู้ใช้โดยใช้ Emulated-EEPROM จากหน่วยความจำแฟลชที่ไม่ระเหยของ STM32F/L/L/H/G/WB/MP1
หน่วยความจำแฟลชโดยทั่วไปใช้ในการจัดเก็บรหัสเฟิร์มแวร์สามารถใช้ในการจัดเก็บ / ดึงข้อมูลของผู้ใช้มากขึ้นและเร็วกว่าจาก EEPROM ต้องขอบคุณ การเขียนและการอ่านข้อมูลบัฟเฟอร์ เวลาการเข้าถึงแฟลชจะลดลงอย่างมากเพื่อ เพิ่มอายุการใช้งานของแฟลช
ปัจจุบันห้องสมุดรองรับทั้ง STM32 CORE V2.0.0+ และก่อนหน้า STM32 CORE V1.9.0- ก่อนหน้า
Arduino IDE 1.8.19+ สำหรับ ArduinoArduino Core for STM32 v2.3.0+ สำหรับบอร์ด STM32 วิธีที่ดีที่สุดและง่ายที่สุดคือใช้ Arduino Library Manager ค้นหา flashstorage_stm32 จากนั้นเลือก / ติดตั้งเวอร์ชันล่าสุด คุณยังสามารถใช้ลิงค์นี้สำหรับคำแนะนำโดยละเอียดเพิ่มเติม
อีกวิธีในการติดตั้งคือ:
FlashStorage_STM32-main.zipFlashStorage_STM32-mainFlashStorage_STM32-main ทั้งหมดไปยังไดเรกทอรี Arduino Libraries 'เช่น ~/Arduino/libraries/ สำหรับบอร์ด Generic STM32F4 series เช่น STM32F407VE โดยใช้ LAN8720 โปรดใช้ STM32 CORE v2.2.0 เป็น Breaking Core v2.3.0 สร้างข้อผิดพลาดในการรวบรวม
เพื่อใช้ LAN8720 บนกระดาน STM32 บางตัว
คุณต้องคัดลอกไฟล์ STM32F4XX_HAL_CONF_DEFAULT.H และ STM32F7XX_HAL_CONF_DEFAULT.H ลงในไดเรกทอรี STM32 STM32 (~/.ARDUINO15/PACKAGES/STM32/ฮาร์ดแวร์/STM32/2.2.0/SYSTEC)
สมมติว่ารุ่น Core STM32 STM32 คือ 2.2.0 ไฟล์เหล่านี้จะต้องถูกคัดลอกลงในไดเรกทอรี:
~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F4xx/stm32f4xx_hal_conf_default.h สำหรับ STM32F4~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F7xx/stm32f7xx_hal_conf_default.h สำหรับนิวเคลียส -144 STM32F7เมื่อใดก็ตามที่ติดตั้งเวอร์ชันใหม่อย่าลืมคัดลอกไฟล์นี้ลงในไดเรกทอรีเวอร์ชันใหม่ ตัวอย่างเช่นเวอร์ชันใหม่คือ x.yy.zz ไฟล์เหล่านี้จะต้องถูกคัดลอกไปยังไดเรกทอรีที่เกี่ยวข้อง:
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F4xx/stm32f4xx_hal_conf_default.hในการใช้ serial1 บนกระดาน STM32 บางตัวโดยไม่มีคำจำกัดความ serial1 (นิวเคลียส -144 nucleo_f767zi, นิวเคลียส -64 nucleo_l053r8, ฯลฯ ) บอร์ด คุณต้องคัดลอกไฟล์ STM32/stm32) คุณต้องแก้ไขไฟล์ที่สอดคล้องกับบอร์ดของคุณนี่เป็นเพียงภาพประกอบวิธีการทำ
สมมติว่ารุ่น Core STM32 STM32 คือ 2.3.0 ไฟล์เหล่านี้จะต้องถูกคัดลอกลงในไดเรกทอรี:
~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_F767ZI/variant.h สำหรับนิวเคลียส -144 NucleO_F767ZI~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/NUCLEO_L053R8/variant.h สำหรับนิวเคลียส -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_STM32.hpp " // https://github.com/khoih-prog/FlashStorage_STM32 ในหลาย ๆ ไฟล์ แต่อย่าลืมใช้ไฟล์ .h ต่อไปนี้ ในไฟล์เพียง 1 .h , .cpp หรือ .ino ซึ่งจะต้อง ไม่รวมอยู่ในไฟล์อื่น Multiple Definitions
// 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 ตรวจสอบตัวอย่าง MultifileProject ใหม่สำหรับการสาธิต HOWTO
ดูการอภิปรายในพฤติกรรมที่แตกต่างกันโดยใช้ src_cpp หรือ src_h lib #80
หน่วยความจำแฟลชมีรอบการเขียนจำนวน จำกัด ความทรงจำของแฟลชทั่วไปสามารถดำเนินการประมาณ 10,000 เขียนวัฏจักรไปยังบล็อกแฟลชเดียวกันก่อนที่จะเริ่ม "เสื่อมสภาพ" และเริ่มสูญเสียความสามารถในการเก็บข้อมูล
ดังนั้น ระวัง: การใช้ห้องสมุดนี้อย่างไม่เหมาะสมสามารถทำลายหน่วยความจำแฟลชของไมโครของคุณได้อย่างรวดเร็วและถาวร โดยเฉพาะอย่างยิ่งคุณควรหลีกเลี่ยงการเรียก put() put() commit() commit() เกินไปและตรวจสอบให้แน่ใจว่าในชีวิตทั้งหมดของไมโครจำนวนการโทร ()
รวม FlashStorage_STM32.h เพื่อรับการจำลอง Eeprom ด้วยหน่วยความจำแฟลชภายใน
ดูตัวอย่าง Emulateeeprom สำหรับตัวอย่าง
API นั้นคล้ายกับ Arduino Eeprom.h API ที่รู้จักกันดีมาก แต่มี 4 ฟังก์ชั่นเพิ่มเติม:
bool isValid() ส่งคืน true ถ้าข้อมูลใน emulated-eEprom นั้นถูกต้อง (ข้อมูลที่เขียนเพื่อแฟลชอย่างน้อยหนึ่งครั้งโดย EEPROM.commit() หรือ EEPROM.put() ) ข้อมูล emulated-eeprom เป็น "ไม่ได้กำหนด" และฟังก์ชั่นส่งคืน falsevoid commit() เก็บข้อมูล EEPROM ใน Flash ใช้สิ่งนี้ด้วยความระมัดระวัง: การโทรทุกครั้งจะเขียนข้อมูลที่สมบูรณ์แบบ-EEPROM เพื่อแฟลช สิ่งนี้จะช่วยลดการเขียนแฟลช-เขียนวารสารที่เหลืออยู่ อย่าเรียกวิธีการนี้ในวงวนหรือคุณจะฆ่าแฟลชของคุณเร็ว ๆ นี้void setCommitASAP(bool value = true) เพื่อตั้งค่าหรือล้างตัวแปรส่วนตัว _commitASAP (ค่าเริ่มต้นเป็น true เพื่อความปลอดภัย) หาก _commitasap เป็นเท็จการเรียกใช้ EEPROM.put() จะไม่บังคับ EEPROM.commit() เพื่อยืดอายุแฟลช คุณจะต้องจำไว้ว่าให้โทร EEPROM.commit() ด้วยตนเองเพื่อบันทึกข้อมูล EMOULD-EEPROM ลงในแฟลชหรือข้อมูลจะหายไปbool getCommitASAP() เพื่อส่งคืนค่าปัจจุบันของ _commitASAPbi_ethernet_blynk
bi_ethernet_blynk_email
bi_ethernet_wm_config
lan8720_ethernet_blynk
lan8720_ethernet_blynk_email
lan8720_ethernet_wm_config
-
และอีกมากมายสำหรับห้องสมุดมา
flashstorage_stm32/ตัวอย่าง/storenameandsurname/storenameandsurname.ino
บรรทัดที่ 15 ถึง 106 ใน BB0DD71
ต่อไปนี้เป็นเอาต์พุตเทอร์มินัลตัวอย่างเมื่อเรียกใช้ตัวอย่าง Ethernet_STM32_LAN8720 บน STM32F4 Black_F407VE กับ LAN8720 Ethernet โดยใช้ไลบรารี STM32Ethernet
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 Hต่อไปนี้เป็นเอาท์พุทเทอร์มินัลตัวอย่างเมื่อเรียกใช้ตัวอย่าง storenameandsurname บน STM32H7 นิวเคลียส -144 นิวเคลียส _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 nowต่อไปนี้เป็นเอาท์พุทเทอร์มินัลตัวอย่างเมื่อเรียกใช้ตัวอย่าง storenameandsurname บน stm32l5 นิวเคลียส -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 nowต่อไปนี้เป็นเอาท์พุทเทอร์มินัลตัวอย่างเมื่อเรียกใช้ตัวอย่าง storenameandsurname บน stm32f7 นิวเคลียส -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 ใช่คุณสามารถประกาศ struct ที่มีฟิลด์เพิ่มเติมและเรียก EEPROM.put() เพื่อจัดเก็บโครงสร้างทั้งหมด ดู storenameandsurname สำหรับวิธีการทำ
ไม่ได้อยู่กับ STM32
ไม่ได้หากคณะกรรมการของคุณมีการรวมเข้าด้วยกันขอแนะนำให้ใช้สิ่งนั้นเนื่องจาก EEPROM มีอายุการใช้งานนานขึ้นจำนวนวัฏจักรการเขียน ฯลฯ )
ในกรณีที่ไม่มีตัวตนแบบรวมหรือขนาดเล็กเกินไปสำหรับกรณีการใช้งานของคุณคุณสามารถใช้ไลบรารีนี้เพื่อใช้หน่วยความจำแฟลชส่วนเล็ก
หากคุณได้รับข้อผิดพลาดในการรวบรวมบ่อยกว่านั้นคุณอาจต้องติดตั้ง Core รุ่นใหม่สำหรับบอร์ด Arduino
บางครั้งไลบรารีจะทำงานได้ก็ต่อเมื่อคุณอัปเดตแกนบอร์ดเป็นเวอร์ชันล่าสุดเพราะฉันใช้ฟังก์ชั่นที่เพิ่มขึ้นใหม่
ส่งปัญหาไปยัง: ปัญหา flashstorage_stm32
multiple-definitionsallman restyle ห้องสมุดขอบคุณมากสำหรับทุกคนสำหรับการรายงานข้อผิดพลาดคุณลักษณะใหม่ที่แนะนำการทดสอบและมีส่วนร่วมในการพัฒนาห้องสมุดนี้
![]() Cristian Maglie |
หากคุณต้องการมีส่วนร่วมในโครงการนี้:
ลิขสิทธิ์ (c) 2021- Khoi Hoang