2

プロセッサレジスタの概念について誤解があります。アドレスのあるレジスタがあります。たとえば、0x0345678です。このレジスタは32ビット幅/長さです(今は関係ありません。どちらのワードが正しいかは関係ありません)。マニュアルに書かれているように、ある種のテーブル/配列があります。

位置の値
 0 111111 ... 10b
 1 111111 ... 11b
 2 7A
 ........................。
 7 3F7C

位置2の値にアクセスする必要があります。最初に行ったことは次のとおりです。

#define REG 0x0345678

void somereadfunction()
{
   volatile unsigned int *pval = (volatile unsigned int *)REG;
   printf("%x", *(pval | 0x02));
}

そして、あなたがすでに推測したように、それは間違った仮定でした。

別の試みはこれでした:

    for(unsigned int i = 0; i < 3; i++)
    {
        printf("i: %d, res: 0x%08X", i, *((volatile unsigned int *)REG));
    } 

そしてそれは動作します。だから、私の質問は、なぜそしてどのように?プロセッサは、別の開発者によって作成された魔法のアルゴリズムを使用してレジスタ値を切り替えるだけですか?私はそれについて少し混乱しています。いくつかの簡単なビット演算を使用してレジスタの3番目のビットにアクセスする方法を知っていますが、レジスタを3回呼び出すだけで、正しい値を取得する方法がわかりません。

よろしくお願いします。

追加:プロセッサはARM7です。i2cデバイスを使用しました。

4

3 に答える 3

3

メモリマップドI/Oレジスタは、読み取りと書き込みに基づいて内容を変更します。彼らはあなたがそれを説明したように少し奇妙ですが、通常は制御レジスタに値を書き込んで、どの内部レジスタにアクセスするかをデバイスに伝えてから、別の場所から値を読み取ります。

于 2012-06-12T16:42:55.993 に答える
3

なぜですか?

ハードウェアデバイス(ARMプロセッサに接続されている)を作成した人は、おそらくデバイスに「属する」アドレスをいくつか宣言しただけだからです。その後、ハードウェアにはレジスタよりも多くのデータがあり、マニュアルを変更するには遅すぎたため、一部のレジスタに複数の値を保持させることにしました。

どのように

ハードウェアには、プロセッサからの読み取りコマンドをカウントする内部カウンタがあります。プロセッサがレジスタから読み取りを行うたびに、ハードウェアは、非表示の内部カウンタによってインデックス付けされた別のデータをプロセッサに送信し、カウンタを増やします。カウンターは3ビットなので、0、1、...、7、0、1、...などをカウントします。

したがって、インデックス2のデータを読み取る場合は、他のすべてのデータ要素(3、4、5、6、および7)も読み取って、非表示のカウンターをリセットする必要があります。

于 2012-06-12T16:59:54.353 に答える
2

*(pval | 0x02)*(pval + 0x2)その配列の2番目の位置にインデックスを付けようとしている場合は、実際にそうなるはずです。

REG + 0x8キャストの前に実行して、位置2の3番目の32ビット値を取得することにより、REGを正しいアドレスに設定することもできます。

これは、このアーキテクチャがバイトアドレス指定を使用する場合に当てはまります。つまり、すべてのアドレスが1バイトのデータを指します。したがって、0x345678、0x345678 + 1、0x345678 + 2などから1バイトのデータを読み取ることができます。32ビットアーキテクチャを使用している場合は、毎回4バイトしか使用できません。したがって、0x345678は位置0、0x345682は位置1というようになります。

アライメントされていないアクセスを行うことはできないため、メモリアライメントも考慮する必要があります。通常、32ビットアーキテクチャでは4バイト境界で整列されます。

于 2012-06-12T16:50:50.963 に答える