1

メモリ マップド デバイスを扱う C コードにはまだ問題があります。現時点では、揮発性ポインターとして書き込むレジスターのアドレス空間を宣言し、以下に示すようにデータを書き込みます。

volatile unsigned int *wr_register = (int *) 0x40000000;
volatile unsigned int *c_register =  (int *) 0x40000100;
...

main{

  *wr_register = 0x01234567;

  *c_register = 0x01234567;    
  *(c_register+1) = 0x89abcdef;  

}

これは多かれ少なかれうまく機能します。ただし、メモリにマップされたレジスタとやり取りする特定の読み取りおよび書き込み関数が必要です。理想的には、次のようになります。

const unsigned int wr_register = 0x40000000;
const unsigned int c_register  = 0x40000100;

function write_REG(unsigned int address, int offset, int data)
{
    (unsigned int*) (address + offset) = data;
}

main{

  *write_REG(0x40000000, 0, 0x01234567);

  *write_REG(0x40000100, 0, 0x01234567);
  *write_REG(0x40000100, 1, 0x89abcdef);  

}

正直なところ、まだ試していませんが、これが適切な方法であるかどうかを誰かに教えてもらえないでしょうか?

編集: 多分それは他の誰かに役立つかもしれません.ここに私の機能があり、それらは機能しているようです. 参考になるコメントをありがとうございます!

void reg_write(unsigned int address, int offset, int data)
{
    *((volatile unsigned int*)address + offset) = data;
}

int reg_read(unsigned int address, int offset)
{
    return(*((volatile unsigned int*)address + offset));
}   

どうもありがとう

4

2 に答える 2

1

コードにはかなりの問題があります。

  1. voidあなたが書いた場所を意味していたと思いますfunction
  2. 関数内のポインターvolatileも同様にする必要があります。
  3. データを書き込む前に、ポインターを逆参照する必要があります。現在の*ように呼び出しサイト ( ) ではなく、関数内にある必要があり*write_REGます。これはコンパイル エラーになります。
  4. アドレスではなく、ポインターにオフセットを追加する必要があります。これは、オフセット 1 がint、たとえば 4 バイト離れた次のオフセットになることを意図しているからですが、それをアドレスに追加しても 1 バイトしか追加されません。

修正された関数は次のようになります。

void write_REG(unsigned int address, int offset, int data)
{
    *((volatile unsigned int*)address + offset) = data;
}

次のように呼び出します。

write_REG(0x40000000, 0, 0x01234567);
于 2010-11-12T15:42:43.473 に答える
0

それは私見で問題ありません。私は時々次のようなマクロを使用します:

#define WR_REG     *(volatile unsigned int*)0x40000000

これにより、レジスタを変数のように使用できます。

WR_REG = 0x12345678;
于 2010-11-12T15:43:08.730 に答える