とっておきの「夜食」教えて下さい

マイコンのプログラムを書いております。
やりたい事はC言語でフラッシュメモリの物理アドレスを直接指定してそのアドレスの値を1バイト読むことです。例えば0xF000番地のアドレスから1バイト読む場合、以下のソースコードで問題ありますでしょうか?なおアドレスは2バイトで表現されます。

unsigned char *p_value;
unsigned char value;

p_value=&value;
p_value=0xF000;

この時点で変数valueには0xF000番地の値が正確に代入されてますでしょうか?

よろしくお願いします。

A 回答 (4件)

> この時点で変数valueには0xF000番地の値が正確に代入されてますでしょうか?



根本的に間違っています。

やりたいことは、
value ← (0xf000)
でいいんですね。
だとすれば、次のようにします。

const unsigned char *p_value = (const unsigned char*)0xf000;
unsigned char value = *p_value;

p_value = 0xf000;とした場合、p_valueというポインタ変数に0xf000番地を格納することになり、valueの中身には影響を与えません。

ところで、フラッシュメモリとのことですが、普通にアドレス空間にマッピングされていますか?
そのフラッシュメモリ特有の手順で読み込まないといけない(例えばコンパクトフラッシュのような)場合には、こんなに単純にはいきません。

> 正確に代入されてますでしょうか?

「正確」かどうかは状況によります。上でも書いたように、特別な手順がある場合、フラッシュメモリの書き換え直後の場合、ハード的な不確定要素がある場合など、「正確」にならない可能性はいくらでも考えらます。
    • good
    • 0

#3です。



一点見落としがありました。

> フラッシュメモリの物理アドレスを直接指定して

とのことですので、そのフラッシュメモリがどこにアサインされているかで、ポインタに格納すべき値が変わります(正確には、ポインタの値==CPUアドレスとは限りませんが、現実問題としては等価と考えてよいでしょう)。
例えば、フラッシュメモリが0x100000番地にアサインされているなら、物理アドレスが0xf000の値を読み込むには、p_valueに格納するのは0x10f000でなければなりません。また、MMUやバンク切り替えなどがある場合、そのハードウェアに応じたアドレス変換が必要になります。
    • good
    • 0

p_value=&value;


p_valueに valueという変数のアドレスを代入しています。

p_value=0xF000; 
p_valueに 0xF000を代入していますが、unsignedcharを超える分は切り捨てられるので結局 0x00が入ります。

というわけで、全然目的とは関係のないことをこの2行のプログラムでは行っています。C言語をもう一度ちゃんと勉強し直すことをお勧めします。

0xF000に格納されたデータをvalueという変数に入れるには次のようにします。
p_value= (unsigned char *)0xF000;
value= *p_value;

ポインタ変数を使わずに
value= *(unsigned char *)0xF000;
とする方法もあります。

なお、割り込みハンドラなどが書換えある可能性のあるメモリ領域やI/Oポートのアクセスには volatileをつける必要があります。
    • good
    • 0

K&Rを隅から隅まで読んでいるか、組み込み関係の本を眺めたことが有るならば知っているとおもいますが・・・


ただの unsigned char だと、コンパイラが行う最適化の気分で、(演算されない)変数の宣言が無視される場合がありえます。
そこで、I/Oなどで実アドレスを指す必要のある場合は volatile で修飾してコンパイラの最適化を抑止します。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報