Multiple Definitionsリンカーエラーを修正する方法Multiple Definitionsを修正する方法をご覧くださいリンカーエラー
Cristian MaglieのFlashstorageに触発されたFlashStorage_Stm32F1ライブラリは、非ジェネインCH32F103XX、CS32F103XXなどを含むSTM32F1/F3の非揮発性フラッシュメモリから、エミュレートエプロムを使用してユーザーのデータを保存および取得する便利な方法を提供します。
一般的にファームウェアコードの保存に使用されるフラッシュメモリは、EEPROMよりも多くのユーザーのデータを保存 /取得し、より速く保存 /取得するためにも使用できます。バッファリングされたデータライティングと読み取りのおかげで、フラッシュアクセス時間が大幅に短縮され、フラッシュの寿命が増加します。
現在、ライブラリは新しいSTM32 Core V2.0.0と以前のSTM32 Core V1.9.0の両方をサポートしています
Arduino IDE 1.8.19+ arduinoの場合。Arduino Core for STM32 v2.3.0+ for STM32ボード。 最良かつ最も簡単な方法はArduino Library Manager使用することです。 FlashStorage_stm32F1を検索し、最新バージョンを選択 /インストールします。このリンクをより詳細な指示に使用することもできます。
インストールする別の方法は次のとおりです。
FlashStorage_STM32F1-main.zipをダウンロードします。FlashStorage_STM32F1-mainディレクトリに抽出しますFlashStorage_STM32F1-mainフォルダー全体を~/Arduino/libraries/などのArduinoライブラリのディレクトリにコピーします。LAN8720を使用して、 STM32F407VEなどのGeneric STM32F4 seriesボードの場合、Breaking Core v2.3.0としてSTM32 Core v2.2.0を使用して、コンパイルエラーを作成します。
一部のSTM32ボードでLAN8720を使用します
ファイルSTM32F4XX_HAL_CONF_DEFAULT.HおよびSTM32F7XX_HAL_CONF_DEFAULT.HをSTM32 STM32ディレクトリ(〜/.Arduino15/パッケージ/STM32/ハードウェア/STM32/2.2.0/システム)にコピーする必要があります。
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 for Nucleo-144 STM32F7。新しいバージョンがインストールされているときはいつでも、このファイルを新しいバージョンディレクトリにコピーすることを忘れないでください。たとえば、新しいバージョンは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_L053R8など)ボードを使用するには、STM32 variant.hをSTM32 STM32ディレクトリ(〜/.Arduino15/STM32/STM32/STM32/STM32/STM32/STM32/STM32/STM32)にコピーする必要があります。ボードに対応するファイルを変更する必要があります。これは単なる方法です。
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 for 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.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ファイルを他のファイルに含めてはいけないわずか1 .h 、 .cppまたは.inoファイルで必ず使用してください。
// 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 Demoについては、新しいMultileProjectの例を確認してください。
src_cppまたはsrc_h lib#80を使用して、さまざまな動作の議論をご覧ください
フラッシュメモリの書き込みサイクルは限られています。典型的なフラッシュメモリは、同じフラッシュブロックにサイクルを書き込み、「摩耗」し始め、データを保持する能力を失い始めます。
したがって、このライブラリの不適切な使用は、マイクロのフラッシュメモリを迅速かつ永久に破壊する可能性があります。特に、 put() put() commit() commit()頻繁に呼び出すことを避ける必要があります。
FlashStorage_STM32F1.hを含めて、内部フラッシュメモリでEEPROMエミュレーションを取得します。
例については、emulateeepromスケッチを参照してください。
APIは、よく知られているArduino Eeprom.h APIに非常に似ていますが、4つの追加機能があります。
bool isValid()エミュレートエプロムのデータが有効な場合にtrueを返します( EEPROM.commit()またはEEPROM.put()によって少なくとも1回は点滅するように書かれたデータ)。それ以外の場合は、エミュレートされたEepromデータは「未定義」であり、関数はfalseを返します。void commit() eepromデータをフラッシュに保存します。これを慎重に使用してください。すべてのコールで、完全なエミュレートエプロムデータを書き込み、フラッシュします。これにより、残りのフラッシュワイトサイクルが減少します。この方法をループで呼び出さないでください。そうしないと、すぐにフラッシュを殺します。void setCommitASAP(bool value = true) _commitASAPプライベート変数を設定またはクリアする(デフォルトは安全であることはtrue )。 _commitasapがfalseの場合、 EEPROM.put()への呼び出しはEEPROM.commit()フラッシュ寿命を延長するように強制しません。 EEPROM.commit()を手動で呼び出すことを忘れないでください。エミュレートされたEepromデータをフラッシュに保存するか、データが失われます。bool getCommitASAP() _commitASAPの現在の値を返します。flashstorage_stm32f1/examples/flashstoreandretrieve/flashstoreandretrieve.ino
CB76B66の26〜81行
64kbフラッシュ付きSTM32F1 bluepill_f103c8で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!
===============64kbフラッシュ付き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 now128kbフラッシュ付き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) = 0128kbフラッシュ付きSTM32F1 Bluepill_F103C8でEmulatePromを実行する場合のサンプル端子出力は次のとおりです。
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 now2564kbフラッシュ付きSTM32F1 Generic_F103RCTXでFlashStoreAndRetRieveの例を実行するときのサンプル端子出力は次のとおりです。

| 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の寿命、書き込みサイクルの数などが長いため、それを使用することをお勧めします。
統合されたエリートまたはそのサイズがユースケースには小さすぎる場合、このライブラリを使用して、限られた数の書き込みのような制限に留意してください。
コンピレーションエラーが発生した場合、多くの場合、Arduinoボード用のCoreの新しいバージョンをインストールする必要がある場合があります。
私は新しく追加された機能を使用しているため、ボードコアを最新バージョンに更新する場合にのみライブラリが機能する場合があります。
問題を提出してください:flashstorage_stm32f1の問題
EEPROM.put()およびEEPROM.get()関数を追加して、エミュレートエプロムの構造全体を読み取り/書き込みますmultiple-definitionsリンカーエラーを修正します。このライブラリの開発を提案、テスト、貢献しているバグの報告、新機能、皆さんに感謝します。
![]() クリスティアン・マグリー |
このプロジェクトに貢献したい場合:
Copyright(c)2021- Khoi Hoang