RXシリーズのデータのアクセス幅について

こんにちはryoです。

タイトル通りですが、RXシリーズのデータのアクセス幅は何Bitになるのでしょうか?

プログラム内で24Bitデータを扱う必要があり、プログラム内のデータのアクセス幅によってByte配列のデータの取扱いが変わるため、知りたいと考えています。

ご存知の方がいましたら教えていただけると幸いです。

よろしくお願いします。

  • ryoさん、こんにちは。NoMaYと申します。

    > RXシリーズのデータのアクセス幅は何Bitになるのでしょうか?

    他のマイコンでも同じなのですけれども、データアクセス命令には命令としてのアクセス幅を指定することが出来るようになっていて、8、16、32、のビット幅から1つ選択出来るようになっています。

    ただ、命令としてのアクセス幅、と書いたのは、外部メモリでは、そもそもメモリのバス幅が、8ビットだったり、16ビットだったり、ということもありますので、そのような場合、マイコンのハードウエアが自動的に、32ビットアクセスを8ビットアクセス4回に振り分けたり、32ビットアクセスを16ビットアクセス2回に振り分けたり、といったこともします。

    通常、命令としてのアクセス幅が何ビットになるかは、C言語であれば、アクセスする変数の型に合わせてコンパイラが自動的にアクセス幅を選択します。

    ただ、コンパイラの最適化機能しだいでは、例えば、32ビットの変数の上位16ビットしか書き換える必要が無いと判断された場合にアクセス幅が16ビットのアクセス命令が使用される場合などもあります。そのようなコンパイラの挙動は、CC-RXなら、仕様上は__evenaccess拡張キーワードで抑止出来るようになっていますけれども、メモリに対しては通常そのような挙動でも特に問題は起きませんので、メモリに対して__evenaccess拡張キーワードを使う必要は滅多に無いと思います。


    ということではありますけれども、何か以下の文面は、上記の通常の話と異なる何かがあるような、ちょっと気掛かりなものだったりしますので、もう少し詳細を教えて欲しいです。例えば、ある程度は具体的なコード、とか、です。正直なところ、後半の「データのアクセス幅によってByte配列のデータの取扱いが変わる」というのが示唆することが思い浮かばないです。

    > プログラム内で24Bitデータを扱う必要があり、
    > プログラム内のデータのアクセス幅によってByte配列のデータの取扱いが変わるため、

  • こんにちはryoです。

    回答ありがとうございました。

    説明が難しいのですが、以前私の方で使用したTIのマイコンでは内部メモリのバス幅?が16Bit幅でメモリの1アドレス毎に16Bit割り当てられている構成になっていました。

    そのため、char型変数でも内部アクセス的には16Bitだったり、使用している領域をSizeof関数で取得した際でも、char : 1,short : 1 ,long :2 のように内部メモリのバス幅?が16Bitだったことでプログラムの制作に苦労した経験があったため、先に確認をしておきたかった次第です。

    24Bitデータについては蛇足になってしまうのですが、上で話したTIのマイコンでは内部メモリのバス幅?が16Bitだったため、char型配列から指定アドレスをキャストして16Bit以上のデータの変換をすることがバス幅?の関係で出来ず、毎回関数を一度挟んで変換を行っていましたが、バス幅?が8Bitならキャストでうまいことデータの変換ができないかなぁと思った次第です。

    長くなってしまいましたが、よろしくお願いします。

     

  • ryoさん、こんにちは。NoMaYです。

    32ビットRISCプロセッサが台頭してきた頃だったと思いますけれども、char型変数のアクセスでも32ビットアラインされていないとミスアラインアクセス例外が発生するとか、そもそも32ビット幅アクセス命令しかないとか、といったような話もプロセッサによっては見掛けたような気もしますけれども、そういう話なのかなぁ、と思ったりしました。

    RXマイコンでは(RL78でもRH850でも同じですけれども)、以下のようなコードも動作します。(という話かなぁ、と思ったりしました。)

        uint8_t *p = メモリアドレス初期値;
        uint32_t data;

        for(ループ条件)
        {
            data = (*(p+2) << 16) | (*(p+1) << 8) | *p;
            p += 3;

            あれこれ
        }

     

  • ryoさん、こんにちは。NoMaYです。

    じわじわと来たのですけれども、さすがに、これは困惑しますね、、、

    > 使用している領域をSizeof関数で取得した際でも、char : 1,short : 1 ,long :2 のように内部メモリのバス幅?が16Bitだったことで

  • イメージとしては以下の通りで

    addr 0x00 | 0x01

    data xx xx | xx xx

    のようなデータ構造になっていたため、char型の場合は16Bit読み取って上位8Bitを切り捨てる構造になっていたため、プログラム間の16Bitデータの受け渡しには問題ないのですが、各種通信を行う際に変数データをバイナリで送る際には8Bitごとに分けてデータを作る必要がありました。

    そのため、データシートのRAMやROMについても1MB (512KW)などのように記載されています。

    今までソフトウェアのみ開発していたため、このことに意識することがなくデバッグでとても苦労しました…

    マイコン自体はさわり程度ではやっていましたが本格的な開発はTIのマイコンが初めてだったため、今回のRXマイコンで開発するにあたってメモリのバス幅について分かっておかないとまずいなと思った次第です。

  • ryoさん、こんにちは。NoMaYです。

    そういうマイコンを使っていたことでの、今回の質問だったのですね。実は、RXマイコン内部のハードウェア的な本当のバス幅というものについての話もあるのですけれども、RXマイコンでは(RL78でもRH850でも)パソコンのx86プロセッサと何ら変わらない感覚/発想で普通にメモリに関する操作が出来ますよ。

  • こんにちは。NoMaYです。

    > RXマイコンでは(RL78でもRH850でも)パソコンのx86プロセッサと何ら変わらない感覚/発想で普通にメモリに関する操作が出来ますよ。

    すみません、ちょっと脱線しますけれども、RL78の場合そうはいかないことが1つあった、ということを思い出しました。

    ● RL78では奇数アドレスからのワードデータ(16bit)アクセスが出来ない(やってしまった場合の挙動は咄嗟に思い出せません)

    (1) ポインタ以外の場合にはコンパイラが良きに計らってくれる(というかリンカがエラーチェックしてくれる)
    (2) uint16_t * などへ直接的に変数アドレスをキャストする場合もコンパイラが良きに計らってくれる(というかリンカがエラーチェックしてくれる)
    (3) uint16_t * などへ uint8_t * や void * からキャストした場合にはコンパイラがワーニングを出すようになっている(CC-RLコンパイラ)
    → 手作業でソースを修正して該当箇所ではバイトアクセス2回でワードデータ(16bit)を操作するようにする
    or プログラム全体としてコード効率は低下するけれどもコンパイル時に -unaligned_pointer_for_ca78k0r オプションを指定する(CC-RLコンパイラ V1.06以降(詳細はヘルプ参照のこと))

  • こんにちはryoです。

    回答と補足説明ありがとうございました。

    通常のメモリ操作ができるということで安心しました。

    まだC言語で理解してない部分にもあるので試しながらやっていこうと思います。

    ありがとうございました。