C言語ライブラリーモージュルだけをROMにするのは可能でしょうか?

現在CS+でRX63Nでソフトを作成しております

なにぶんRAMが128K Byteのようで、これをまだまだ先になりそうですが

SDカードやLANやUSBからファームを転送してRAM上で動作させるといいんじゃないかと

その場合ROMは大容量なのでC言語ライブラリーモージュルだけをROMにもたせることができれば

いいのじゃないかと素人考えで、そんなことは可能なんでしょうか?

Parents
  • わわいです
    可能です。
    お使いのツールチェインのライブラリ生成ツールのオプションにライブラリのセクションの指定をして、そのセクションをリンカのオプションにてROMのアドレスに割り当て、そして、ビルドした生成物からROMのアドレスのモジュールを抜き出し、それをROMに書き込む、という手順になります。
  • わわいさん
    高度な技術を教えてください
    1.ライブラリ生成ツールのオプションとは「ライブラリ・ジェネレート・オプション」タブの内容のことでしょうか?
    2.リンカのオプションにてROMのアドレスに割り当て
    これは「リンク・オプション」のタブの中であると思いますが
    3.ビルドした生成物からROMのアドレスのモジュールを抜き出し
    これはコピー用のファームを別途用意して
    RAM実行用のファームを後で使用というような内容なんでしょうか?
  • わわいです
    >1.ライブラリ生成ツールのオプションとは「ライブラリ・ジェネレート・オプション」タブの内容のことでしょうか?
    RXのツールチェーンのマニュアルを見てるわけでないのでちとアレですが、おそらくそうだと思います。マニュアルになんか記述はないでしょうか。
    >3.ビルドした生成物からROMのアドレスのモジュールを抜き出し
    SH+HEWの場合だと、リンカオプション>出力>出力ファイルの分割、という項目があり、アドレス範囲あるいはセクション名指定で、バイナリファイルで分割出力できるようになってます。RXの場合でも、それに類似するようなオプションが有ると思われますんで、そこら辺調べてみてください。
    まー、LANやUSBメモリからブートアップさせるためには、そこからブートコードを読み出すスタートアップコードもROMに配置しておく必要があるので、それをするつもりがあるなら、そこら辺は必須となりますんで、これができないと話にはなりませんね
  • わわいさん
    「リンカオプション>出力>出力ファイルの分割」教えていただきありがとうございます、なるほどそれについてはこれまでHewについては長く使用してきましたがやったことがありません、最近はHewではデバックとリリースに区分けして別のメモリマッピングでデバッグをROMに割り当て、リリースでSDRAMに割り当てるというようなことをやっていました、今回まさかライブラリが別出力できるなんて想像できませんでした、ちゃんと用意がしてあったんですね、うーん深い。
  • たいていリンカでライブラリをモジュールにリンクして使用します、パソコンの場合はライブラリDLL等をリンクして使用します、これをRXで実現するためには、ライブラリとジャンプテーブルのようなものをROMに書き込んで置き、RAMのC言語のモジュールからこれを呼び出すような方式ではないかと思います、一昔前ににも似たようなことをしている人を見かけました、あれはどうしてたのかなと思います、もしやって見たことのある人がおられましたらご教授いただけませんか、これが出来ると画期的だと思うのは自分だけでしょうか?
  • 今少し思い出しました、DLLのように別に扱うのではなく
    ROM:ブートモジュール
    ROM:ファンクションテーブル
    ROM:コマンドラインモジュール(ここから一時実行ファイルを起動する)
    ROM:ライブラリモジュール
    RAM:ワーキングRAM
    RAM:一時実行ファイル(これは別ビルドでブートモジュールやコマンドラインでロードする)
    のようなやり方なら実現できそうです、一時実行ファイルはファンクションテーブルを
    参照してライブラリ機能を呼び出す
    これが一昔前のやりかたでしたね、ただこれではファンクションテーブルを作るのがたいへんそう。
  • >もしやって見たことのある人がおられましたらご教授いただけませんか

    一度書いたんだけど、書いている途中で横幅が狭くなり、ついに1行の幅になった。
    Replyボタンを押したけど投稿できなかった。
    2度も書くのは大変だから、簡潔に書きます。
    アセンブラで次のように書きます。

    .GLB _isalnum ; 3-1 アルファベット又は数字かを判定
    .GLB _isalpha ; 3-2 アルファベットかを判定

    .LWORD _isalnum ; 3-1 アルファベット又は数字かを判定
    .LWORD _isalpha ; 3-2 アルファベットかを判定

    ROMに書いた後でLWORDの中身を見て、コピーして次のヘッダーに貼り付けます。

    #define _3_1_ 0xFFFE11A5
    #define _3_2_ 0xFFFE11B5

    #define isalnum ((long (*)(long )) _3_1_ ) // 英字または10進数字かどうか判定
    #define isalpha ((long (*)(long )) _3_2_ ) // 英字かどうか判定


     懇切丁寧に説明している暇は無いから、これだけでは分からないと思います。
     どうしてもやりたい人は、読み解いてください。
Reply
  • >もしやって見たことのある人がおられましたらご教授いただけませんか

    一度書いたんだけど、書いている途中で横幅が狭くなり、ついに1行の幅になった。
    Replyボタンを押したけど投稿できなかった。
    2度も書くのは大変だから、簡潔に書きます。
    アセンブラで次のように書きます。

    .GLB _isalnum ; 3-1 アルファベット又は数字かを判定
    .GLB _isalpha ; 3-2 アルファベットかを判定

    .LWORD _isalnum ; 3-1 アルファベット又は数字かを判定
    .LWORD _isalpha ; 3-2 アルファベットかを判定

    ROMに書いた後でLWORDの中身を見て、コピーして次のヘッダーに貼り付けます。

    #define _3_1_ 0xFFFE11A5
    #define _3_2_ 0xFFFE11B5

    #define isalnum ((long (*)(long )) _3_1_ ) // 英字または10進数字かどうか判定
    #define isalpha ((long (*)(long )) _3_2_ ) // 英字かどうか判定


     懇切丁寧に説明している暇は無いから、これだけでは分からないと思います。
     どうしてもやりたい人は、読み解いてください。
Children
  • リカルドさん
    回答ありがとうございます、たぶんこれはライブラリROMの中身のアドレスを推定するようなことですよね、LWORDは32ビツトの関数のアドレスポインタですよね、それを沢山並べて置き、それを関数オーバーライト再定義して使用するのですね、大体このCS+RXのライブラリの関数ポインタテーブルの位置を作らなくても、持っていると思うのでこれが解れば特に新規に配置する必要もないですね、作り方を教えていただき参考になりました。
  • 2017/3/30 11:38 の書き込みについてもう少し説明します。
     
    .GLB _isalnum ;
     
    で、標準関数を抜き出せます。
     マップファイルを見れば関数のアドレスが分かるのでヘッダファイルに次のように書けば良いのです。
     
    #define isalnum ((long (*)(long )) 0xFFFE11A5 )
     
     しかし全関数に対してそのような作業は大変です。書いた順番では無くアルファベット順に並び替えられたりもします。
     それでROM出力にアドレスの一覧を出力するために、次の命令があります。関数の数だけ有ります。
     自分の好きな順番に並べられます。
     
    .LWORD _isalnum ;
     
     これをHEW、E1で読み出しテキストにコピーします。
     エディタの機能を使ってブロック状に切り出し、次のように貼り付けます。関数の数だけ並びます。
     
    #define _3_1_ 0xFFFE11A5
    #define _3_2_ 0xFFFE11B5
     
     この値を次のようにしてコピーします。
     
    #define isalnum ((long (*)(long )) _3_1_ ) // 英字または10進数字かどうか判定
    #define isalpha ((long (*)(long )) _3_2_ ) // 英字かどうか判定
  • > それでROM出力にアドレスの一覧を出力するために、次の命令があります。関数の数だけ有ります。
    > 自分の好きな順番に並べられます。
    >
    > .LWORD _isalnum ;

    使いたい関数の数だけ BRA.A 命令並べた方が良くないですか?

  • わわいです
    SHのはなしですが、リンカのオプションに「外部シンボル割り付け情報ファイル」ってのがあって、それでシンボルアドレス情報が出力できるんで、それをリンクするとOKOKってのがあります
  • リカルドさん
    「標準関数を抜き出せます。」ということで、なるほどですね。
  • fujita nozomuさん
    私には.LWORD _isalnum ;もBRA.A 命令もよくわからないのですが?
    コンパイラオプションなんですか?
  • > 私には.LWORD _isalnum ;もBRA.A 命令もよくわからないのですが?

    .LWORD はアセンブラの疑似命令、BRA.A は RX の分岐命令なので、どちらもアセンブラの話となります。
  • >SHのはなしですが、リンカのオプションに「外部シンボル割り付け情報ファイル」ってのがあって
    「外部シンボル割り付け情報ファイル」は2度目のコンパイルで最適化に使うための機能で、シンボルのアドレスを出力する機能ではないです
    SHCでは「シンボルアドレスファイル」という機能です
    CC-RXでは「外部定義シンボルをファイル出力するセクション」という機能です
    エクスポートしたい関数があるプロジェクトでこの機能でシンボルファイルを出力して、出力ファイルを関数を利用する側のプロジェクトにソースとして追加してビルドします。
    こうする事でリカルドさんが書いている事がある程度自動で実現可能です。
  • >使いたい関数の数だけ BRA.A 命令並べた方が良くないですか?
     
     全ての標準関数を書くのです。
     最初のIKUZOさんの書き込みに次のように書いてあります。
     
    >ROMは大容量なのでC言語ライブラリーモージュルだけをROMにもたせることができれば
    >いいのじゃないかと素人考えで、そんなことは可能なんでしょうか?
     
     秋月電子のH8/3049基板でプログラムを練習したとき、sprintf は大きくてRAMに入らなかった。
     それで標準関数を全てROMに書く方法を思い付きました。
     後はRAMに書いた学習用の色々なプログラムから呼び出します。
     
     IKUZOさんの質問の答えとしてピッタリの物を既に実践していました。
     
     ヒントを与えただけで、不要な関数を切り捨てたりするのは自由です。
     
     H8/3052だと書き換え回数が100回です。RX621で1000回です。
     ROMライターは書き込んだ後に読み出して照合し、合ってなければリトライで何回か書き込みます。
     規定のリトライ回数を超えたらエラーです。
     H8/3049、3052用の自作のROMライターではリトライ回数を表示し、劣化具合が分かるようにしていました。
     既成のROMライターじゃそんな事は分からない。
     書き換え回数が保証されていても、なるべく回数を少なくしたいと言う心理が働いています。
     
     昔のZ80と言うCPUと紫外線消去のROMを使っていたときは、紫外線消去の回数を減らす為に0x00で上書きしてNOP命令に変え、その後ろに更新したプログラムを書いていました。
     消去と言うのはビットを1にする事で、書き込みは0にする事です。そのためどんなデータでも、0x00にする事は出来ます。
     このようにしてROMが終わりまで来たら、紫外線消去します。
     その後はRAMを使ってROMエミュレータを作り、面倒が無くなりました。
  • >私には.LWORD _isalnum ;もBRA.A 命令もよくわからないのですが?
     
     RX621のアセンブラ命令です。
     最初に全関数を取り出す方法を考えたときは、C言語の main 関数から全ての標準関数を呼びました。
     その後 .GLB _isalnum ; と書くだけで取り出せる事が分かりました。
     C言語で言えば、グローバル変数を置いたようなものです。そのファイル内では使われなくても他のファイルから使われるかも知れないので、最適化で削除される事も無く配置されます。
     
     .LWORD _isalnum ; と書くと .GLB _isalnum の _isalnum の値が書かれます。すなわち関数のアドレスになります。