2

富士通 16 ビット マイクロコントローラの EEPROM にデータを格納する際に問題があります。EEPROM へのバイトの書き込みは問題ではありません。問題なくバイト単位でデータを読み書きできます。

s の列挙型を使用してdwordさまざまな変数を EEPROM に格納していますが、それらはすべて 4 バイト長です。変数ごとに、最大 4 バイトのスペースを格納したいと考えています。フラグ (1 ビット) または長さが 1 バイトしかない変数のみを格納したい場合でも、4 バイトを使用するため、これはあまり良くありません。

この 4 バイト手法を使用する理由は、アクセスしたい変数が格納されているアドレスを知るためです。これは問題なく機能しますが、かなりの欠点があります。

1 つは無駄なスペースで、もう 1 つは構造体を扱うときに発生する問題です。

たとえば、次のような構造体があります

typedef struct {
    attenuator_whichone_t attenuator;
    char*                 attenuatorname;
    servo_whichone_t     associated_servo;
    ad_ad7683_whichone_t associated_adconverter;
    word                 item_control;
    word                 item_mode;
    word                 item_position;

} attenuator_info_t;

そしてそれを次のように初期化します:

static attenuator_info_t constinfo[_NUM_ATTENUATOR_WHICHONE_] = {...}

現在使用しているコードでは、すべての値を個別に保存する必要があります。したがって、構造をバラバラに壊します。その構造をそのまま保存したいのです。(そして、コードにさらにいくつかあります)。

私の理解では、そのためにはファイルシステムが必要です。Google で検索すると、 microFAT​​ などの例がいくつか見つかりました。これは、私の意見では、やり過ぎです。

sizeof を使用して構造体を保存し、すべてのバイトを反復処理することは問題ありませんが、構造体が EEPROM のどこにあるかを知るという問題をどのように処理すればよいでしょうか? そのため、何らかのファイル システムが必要になる可能性があります。もっと小さいのはないの?それとも何かのトリック?とにかく変数は固定長です。そのため、これらの構造体を格納するための素晴らしく簡単な方法があるかどうか疑問に思っていました。

私の問題を十分に詳しく説明できれば幸いです。

4

2 に答える 2

1

構造体の配列がある場合、データを EEPROM に書き込んで、後でかなり簡単に読み取ることができるはずです。ここで重要なのは、データが格納されている EEPROM の場所を正確に把握することです。

これは、さまざまな方法で行うことができます。単純なプロジェクトの場合、テーブルが格納されているメモリ範囲の開始アドレスを表す定数を定義するだけです。

#define ATTENUATOR_INFO_START 0x0100 // Indicates table starts at address 256
#define ATTENUATOR_INFO_SIZE (sizeof(constinfo)/sizeof(*constinfo))

// Store table in EEPROM
memcpy(EEPROM_START + ATTENUATOR_INFO_START, constinfo, ATTENUATOR_INFO_SIZE);

// Load table from EEPROM
memcpy(constinfo, EEPROM_START + ATTENUATOR_INFO_START, ATTENUATOR_INFO_SIZE);

上記は、EEPROM がメモリにマップされ、定数EEPROM_STARTが EEPROM オフセット 0 にマップされたメモリ アドレスを表すと仮定しています。プロジェクトで EEPROM がメモリにマップされていない場合、手順は少し異なりますが、一般的な考え方は同じです。

テーブルを固定オフセットに保存したくない場合は、テーブルのオフセットを EEPROM にも記録することもできます。プロセスは通常同じです。

// Offset/length information is stored in the first few bytes of the EEPROM
#define TABLE_INFO_LOCATION 0x0000

struct table_info {
    unsigned int offset;
    unsigned int num_entries;
} table_info;

// Retrieve table offset
memcpy(&table_info, EEPROM_START + TABLE_INFO_LOCATION, sizeof(table_info));

// Load table from EEPROM
memcpy(constinfo,
       EEPROM_START + table_info.offset,
       table_info.num_entries * sizeof(*constinfo));

この方法では、テーブルを EEPROM のどこにでも配置できるため柔軟性が高くなりますが、テーブル情報を格納する既知の場所が必要です。

あらかじめ決められたオフセットに何も格納できない場合は、データ構造をラップするヘッダー/フッター署名を作成できます。ほとんどのメモリ デバイスでは、未使用のバイトが0x00デフォルトで使用されます。0xFFテーブルの直前に32 バイトのパターン0xBE(「前」) を書き込み、テーブルの直後に0xAF(「後」) の 32 バイトのパターンを書き込むことができます。これにより、EEPROM のメモリをスキャンして、テーブルの最初と最後を見つけることができます。欠点は、そのメモリ パターンが EEPROM の他の場所にある場合、間違った場所を探すリスクがあることです。そのため、ヘッダー/フッターのパターンとサイズを慎重に選択してください。

于 2012-07-18T22:03:14.610 に答える
1

私の理解では、そのためにはファイルシステムが必要です。Google で検索すると、microFAT​​ などの例がいくつか見つかりました。これは、私の意見では、やり過ぎです。

いいえ、ファイル システムは、説明したタスクとは無関係です。ファイル システムは、任意に作成、アクセス、削除、サイズ変更できるファイルファイル間のマッピングを定義します。実行時の変更の名前や要件については言及していません。ファイルシステムを定義する重要なサービスは必要のないものであるため、やり過ぎのように思えます。

s の列挙型を使用してdwordさまざまな変数を EEPROM に格納していますが、それらはすべて 4 バイト長です。

sの配列を意味していると思いますdword

これが問題を引き起こしている場合は、変更を検討してみませんか?

フォームの定義でEEPROMを初期化する方法しか知らないようです

static attenuator_info_t constinfo[_NUM_ATTENUATOR_WHICHONE_] = {...}

EEPROM を実行する必要がある技術的な制限はありません。Astructは のようなバイトのシーケンスですarray。ほとんどの組み込みコンパイラでは、一連のstruct、配列、およびその他の定義を、適切な#pragma.

EEPROM について、またはconstinfoプログラムをビルドした後に変更されるかどうかについて何も知らないので、書き込み方法を教えることはできません。しかし、実際には一連の名前付き変数を一連のバイトにマップしたいようです。これにはファイル形式が必要になる場合がありますが、ファイル システムは必要ありません。

EEPROM がメモリ マップされている場合は、ポインタをコンパイルするだけです。

extern struct foo_info_type foo_info;
extern struct bar_info_type bar_info;

/* EEPROM table of contents */
struct foo_info_type *foo_ptr = & foo_info;
struct bar_info_type *bar_ptr = & bar_info;
/* ... more pointers ... */

/* Actual data in EEPROM, pointers point here */
struct foo_info_type foo_info;
struct bar_info_type bar_info;
于 2012-05-26T03:48:43.243 に答える