Cソースから直接AVR EEPROMをプログラム


11

AVR Cソースに以下のコードを含めると、追加のコマンドや.hexファイルを必要とせずに、ヒューズを直接プログラムすることができます。

#include <avr/io.h>

FUSES = {
        .low =          LFUSE_DEFAULT ,
        .high =         HFUSE_DEFAULT ,
        .extended =     EFUSE_DEFAULT ,
};

EEPROMに値をプログラムする同様のトリックはありますか?

/usr/lib/avr/include/avr/fuse.hマクロに関するコメントが見つかる場所を確認しましたが、で同様のコメントが見つからず/usr/lib/avr/include/avr/eeprom.h、プリプロセッサの解釈が私のリーグから少し外れています。

CのソースコードにデフォルトのEEPROM値を含めることができれば、とても便利です。誰でもそれを達成する方法を知っていますか?

edit1:

このFUSESトリックはISP時間にのみ実行され、RUN時間には実行されません。そのため、コントローラーの結果のアセンブリコードにはヒューズがプログラムされていません。代わりに、プログラマーは追加のFUSESプログラミングサイクルを自動的に繰り返します。

edit2:

Linuxではavr-gccおよびavrdudeツールチェーンを使用しています。


これはISPをプログラミングするときだけですか?ほとんどのブートローダーでは、ヒューズをプログラムすることはできませんよね?
angelatlarge 2013年

2
現時点で完全な回答を書く時間はありませんが、ヒントとしてEEMEMディレクティブで検索してみてください。さらに、プログラマーが使用する別の.EPPファイルを作成するには、リンカー設定を変更する必要がある場合があります。
PeterJ 2013年

@angelatlarge ISPプログラミングのみ。このセットアップにはブートローダーはありません。
ジッピー2013年

2
これに対する答えは、ツールチェーンがその出力に記録しようとするもの、およびプログラマーが解析しようとするものに完全に依存することに注意してください。ほとんどのツールチェーンは、特別なセクションを作成する(または架空のアドレスにデータを配置する)ように構成できるため、最終的には、プログラマーがそれを抽出できるか、それを行うカスタムスクリプトで駆動できるかがプログラマにかかっています。
Chris Stratton 2013年

回答:


7

avr-gccをEEMEM使用すると、変数の定義でマクロを使用できます。libcドキュメントと例を参照してください

#include <avr/eeprom.h>
char myEepromString[] EEMEM = "Hello World!";

文字の配列が「.eeprom」という名前のセクションに存在することを宣言します。このセクションは、コンパイル後に、このデータがEEPROMにプログラムされることをプログラマーに伝えます。プログラマーソフトウェアによっては、ビルドプロセス中に作成された「.eep」ファイルの名前を明示的にプログラマーに提供する必要がある場合があります。


私は「になって」私は私よりもわずかに異なるファイル名を使用するが、これらは、私はプログラムのコマンドラインからEEPROM(とメイクファイル)に含まれるコマンドです:
jippie

1
プログラマが使用するインテルHEXデータを含むファイルを作成しますavr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ihex $(src).elf $(src).eeprom.hex
jippie

1
:実際のプログラミングをすることによって行われavrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
jippie

7

はい、デフォルトのデータをソースコードのEEPROMに手動で書き込むことができます。まず、AVRを備えたEEPROMに関するこの素晴らしいガイドをチェックしてください:DeanのAVR EEPROMチュートリアル。また、ソースコードと共にデバイスにプログラムされるメイクファイルを使用して、EEPROMデータを含む.eepファイルを作成することをお勧めします。ただし、さまざまなメイクファイルやリンカーの操作に慣れていない場合でも、ソースコードファイル内から実行できます。これは、回路に電源が投入されるとすぐに発生し、初期プログラム操作が停止します。

プログラムの最初(メインループの前)では、次のようなことができます。

#include <avr/eeprom.h>

#define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_2 52  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_3 68  // This could be anything from 0 to the highest EEPROM address

uint8_t dataByte1 = 0x7F;  // Data for address 1
uint8_t dataByte2 = 0x33;  // Data for address 2
uint8_t dataByte3 = 0xCE;  // Data for address 3

eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);

「更新」機能は、最初にその値がすでに存在するかどうかを確認し、不要な書き込みを節約して、EEPROMの寿命を維持します。ただし、非常に多くの場所でこれを行うには、かなりの時間がかかる場合があります。1つの場所を確認することをお勧めします。必要な値であれば、残りの更新は完全にスキップできます。例えば:

if(eeprom_read_byte((uint8_t*)SOME_LOCATION) != DESIRED_VALUE){
  eeprom_write_byte((uint8_t*)SOME_LOCATION, DESIRED_VALUE);
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
  eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
  eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);
}

大量のデータを更新する場合は、などの他の関数を使用してみてくださいeeprom_update_block(...)。そして、間違いなくそのチュートリアルを読んでください。よく書かれています。

すべてのEEPROM更新ステートメントを1つのプリプロセッサー条件ステートメントに入れることができます。これは非常に簡単です。

#if defined _UPDATE_EEPROM_
  #define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
  uint8_t dataByte = 0x7F;  // Data for address 1
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
#endif // _UPDATE_EEPROM_

このコードは、次のことを行わない限りコンパイルされません。

#define _UPDATE_EEPROM_

これをコメントとして残し、デフォルトのEEPROM値を変更する必要がある場合はコメントを外します。Cプリプロセッサの詳細については、このオンラインマニュアルをご覧ください。マクロと条件文のセクションに最も興味があると思います。


正解はリンクされたPDFの最後の段落にあるようです。Ch. 7 Setting Initial Values
ジッピー2013年

はい。それで合っています。最初の段落でそのことを述べましたが、.eepファイルとmakefileのリンカーに慣れていない場合に備えて続けました!
カートE.クロティエ2013年

1
静的EEPROMアドレスを使用することは悪い習慣です。代わりにEEMEM属性を使用し、コンパイラーにアドレス分布を管理させる方が良いでしょう。また、各セクションでCRCチェックを実装/実行することをお勧めします。CRCが失敗した場合、対応するセクションには、初期化されていないデータまたは破損したデータが含まれます。このように、データが破損した場合に備えて、以前の構成にフォールバックメカニズムを実装することもできます。
Rev1.0 2013年

「スタティックEEPROMアドレスを使用することは悪い習慣です。」どうして?
angelatlarge

1
EEMEM変数を使用する場合、コンパイラーは、EEPROMのどこにどの変数が存在するかを管理します。この方法では、データにアクセスするときに、変数への(定数によって生成された)ポインターを操作するだけです。一方、各変数が存在するアドレスを明示的に定義する場合は、それらのアドレスを自分で管理する必要があります。たとえば、変数が誤って同じアドレスを使用して、互いに上書きしないようにする必要があります。場合または再計算したすべてのアドレス将来的には、変数のストレージサイズの変更など
JimmyB
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.