- ベストアンサー
h8 モニタプログラムの改良について
はじめまして、H8初心者です. 現在実務訓練でH8/3048Fを使用して、測定機器を作成しているところです。そこで、モニタプログラムをROMに書き込むまでできているのですが、Htermを利用してRAMに書き込むプログラムの容量が足りないということで、ROMの余っている部分に関数を書き込みRAMの要領を出来るだけ確保しようと考えています。しかし、いろいろなHPで調べているのですが初心者にはよくわからないことが多く、質問させていただきました。 一応使っているコンパイラ、アセンブラ、リンカは付属CDの秋月製のものです。いろいろと試して、ライブラリ関数を宣言してオブジェクトファイル形式にしようとしているのですが作成されたMAPファイルを見てみても関数が含まれておらず、よくわかりません。 方法としてWatoson8さんという方がその方法について解説しているホームページを参考にさせていただこうと思いましたが、その方法が深く理解できないため、足踏みしている状態です。 そのホームページの内容を秋月製のコンパイラなどを使用して作成する方法でも、その他の方法でも何か知っていることがあったら教えていただきたいです。よろしくお願いします。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
--just-symbols についてもう少し説明します。 昔、intel8086向けの純正の環境で publicsonly というリンカーの 命令を使っていました。たぶん同じものだと思います。 通常のオブジェクト同様にシンボルで解決しますから、ヘッダファイルは 分ける必要はないはずです。リンカーは、リンクするファイルの前から順番にシンボルを 解決しますので、ライブラリよりも前に--just-symbolsを書いてやれば ライブラリ側がリンクされないはずです。 リンカー、ロケータの解説 リンカーの動作は、各publicシンボルをつなぎながらコンパイルしたオブジェクト をくっつける動作をします。さらにロケート(番地)が指定されていればロケート を実施します。 リンカーで、--just-symbolsとするとロケート済みオブジェクトからシンボルのアドレス のみ解決します。monitor.coffはリンカーにはオブジェクトは追加されません。 つまり 例)(アドレスは大雑把なので実際にはそうならないと思いますが) ROMの中に 110H番地 に printf() 関数 がある ライブラリに printf()がある。 sprintf()がある ユーザープログラムは 8000H番地からロケートされる モジュール test.c の80行目にprintf()が使われている 場合 8120H番地に JSR 110H ; printf() みたいにリンクでシンボルが解決されます。 sprintfは、 ユーザープログラムの後ろの 8230Hあたりにロケートされます。
その他の回答 (7)
- R32C
- ベストアンサー率39% (115/290)
GDLは、シングルソース限定の環境だそうで、今回の「実務訓練」ではそれを 使わずにすることが必要になるように思います。 ここで他に参考に案内されたURLはたぶんどこもGDLでROMモニタをビルドしていない はずです。 ルネサス標準のものはたぶんバッチになっていたと思うのでバッチファイル とリンカーのリンクファイルを修正(追加)すれば可能かと思います。 ただ、ちょっと感じたのは、多くのいい回答がされていますが、 理解できていないように思います。 2点ほど確認しますが、 1)今お使いのROMモニタが自分でコンパイルビルドしてフラッシュに書いたのですか? 2)ROMモニタのビルドの環境が ・バッチファイル ・GDLなどの統合環境 ・make のいずれですか? またその設定ファイルの内容は確認していますか?
- zwi
- ベストアンサー率56% (730/1282)
#2のzwiですが追記です。 こんなページがありますね。 http://www.wakayama-u.ac.jp/~miw/linux/pukiwiki/pukiwiki.php?SuperRom%A4%CE%BA%EE%A4%EA%CA%FD ただし、「3048用は動作不良のため、削除しました。」とありますので自力で解決する必要があります。たぶん、gccのコンパイラとリンカの仕組みに詳しくないと手出しが難しいと思いますが参考にして挑戦する価値はあるでしょう。 これでは、標準ライブラリのprintfとsscanfをROM化してますが私が難しいといった理由は、標準ライブラリヘッダとROM化した関数のヘッダの衝突を自力で回避できるなら挑戦しても良いと思います。気をつけることはヘッダの順番です。
- R32C
- ベストアンサー率39% (115/290)
自作の関数ではなく、ライブラリ(ファイル)をROMにおきたいという ことなのですか? であれば、ダミーのモジュールを追加して必要関数をダミーモジュール から呼び出すようにすればリンクしてくれると思いますが? これはROMを作るときの話です。 URLの「ユーザープログラムのリンク」を参照ください。 これは、RAMのプログラムがROMのライブラリを使うときのリンク方法です。 まずROM側が優先してリンクされ残りがライブラリからリンクされる そうです。ライブラリを分離しなくていけそうな感じです。
お礼
ありがとうございます。 先週からGDLに環境をうつすことになったので、それでやってみたのですが、一応vsprintf vfprintf関数(とても容量を必要とする)においては、コンパイルに成功しました。あとはどう、モニタと一緒にするかということです。 しかし、モニタと一緒に書き込む場合に、GDLでもう一度モニタをつくるようにしてから、リンクで二つを一緒にしようと考えるのですが、ルネサスさんのモニタをGDLの環境でアセンブル、コンパイル出来なくて、どこをどのように修正したらいいのか悩んでいます(^^; これがわかれば、モニタプログラムを作れる段階にしてあとはリンクだけなのですが・・・
- zwi
- ベストアンサー率56% (730/1282)
#2のzwiです。 >実際にライブラリ関数などをROMに書き込む方法としてはどのようにしたらよいでしょうか。 って事は、C言語の標準ライブラリ(memcpy等)をROMに書き込みたいって事ですか? RAM側のプログラムが参照するC言語の標準ライブラリをROM側に置くのは、色々とややこしい事になるのでお勧めできません(出来ないわけではないです)。 「測定機器プログラム」の一部の関数だけをROMに移すだけなら簡単なので、そちらをお勧めします。 >でも、実際にその関数だけを抜き出す方法をどうするのかがわからなかったりします。 抜き出す方法は、ROMに移す関数のソースコードを分離する必要があります。ROMにリンクする関数を専用ソースコードに移して、モニタと一緒にコンパイル・リンクします。 「測定機器プログラム」のソースコードから、ROMに移した関数たちは削除します。 >その方法がわかれば、モニタとうまく重ならないようにリンクさせMAPファイルからアドレスを探してやろうと思うのですが・・・ 何か勘違いしているような? リンカがアドレスを解決してくれますので、「モニタとうまく重ならないようにリンク」は考えなくて良いです。
お礼
勘違いしていました。リンクでアドレスの配置はやってくれるんですね。現在は、出来るだけ、RAMにおかれるものなどの削減を行うために、関数をかけるかどうか確かめてるので、それで出来たらいいって感じでやってます。 回答ありがとうございます。
- yphkz4063
- ベストアンサー率23% (34/144)
質問内容がよくわからないので、まんま#1様や#2様の回答の延長になるとおもいますが・・・。 経験的に開発環境というものは、たいがいは何かが足りないものなのです。 不足する開発ツールは自前でつくります。 例えば通称mapperといわれるアドレスとシンボルを管理するツールとかです。 よくやるのが一度リンクしたmapファイルからシンボルなど必要な情報を取り出して、リンクに必要なデータを再構築してもう一度リンクし直すなどです。 二回リンクする・・・ひょっとしたらこれが回答だったりするかも知れません。 実際はこれを手でなくツールでやります。 場合によってはincludeファイルを自動的に作り直して、もう一度コンパイルからやり直すとか。 一見バカみたいなやり方ですが、特に組み込み型の開発の場合はこれをやらないと開発できないこともあります。 その他makefileをつくるためのmakefileとか、現場ではとても原始的なことをやってます。 開発工程の何分の一かがツールの開発であるようなことはよくありますよ。 学習のためなら一時的に手動開発(?)も勉強にはなると思います。
お礼
ありがとうございます。参考になります。しかし、まだ、H8を始めて3週間の私にとっては、再構築してもう一度リンクしなおすという方法も良くわかりません。 一気に上級な方法をやりすぎなのでしょうか。
- zwi
- ベストアンサー率56% (730/1282)
H8は使ったことが無いのですが、どのマイコンでも使えそうな一般的な方法を書かせてもらいます。 ROMに書き込むモニタに「測定機器プログラム」の一部の関数をリンクする事でROM側に関数を移して使用するRAM容量を減らしたいという理解でよろしいですね。 次のような手順で作業するのがひとつの方法です。 (1)モニタのオブジェクトファイルに「測定機器プログラム」から抜き出した関数だけのソースをコンパイルしたオブジェクトファイルをリンクする。これをモニタとしてROMに書き込む。 (2)モニタにリンクした関数のアドレスをモニタのmapファイルから自動か手動で取得して関数ヘッダを生成する。 #1のR32Cさんが書かれている2)の方法です。 (3)関数ヘッダを「測定機器プログラム」にインクルードして利用する。 変更の少ない関数をROM側に移動させないとROM書き換えが多く効率的ではありませんので注意してください。
お礼
なるほど、そうすれば、RAMに書き込んだプログラムからROMの関数を使用したいときに場所がわかるようになっているということでしょうか。 現在は、この方法で、サンプルプログラムが動くかどうかテストしたいと考えてるので、変更の少ない関数意外も移動させてしまうかもしれません。 でも、実際にその関数だけを抜き出す方法をどうするのかがわからなかったりします。その方法がわかれば、モニタとうまく重ならないようにリンクさせMAPファイルからアドレスを探してやろうと思うのですが・・・
- R32C
- ベストアンサー率39% (115/290)
やり方は複数あるみたいですね。 一般的にROMにあるシンボルをどのようにリンクするかですが、 1)リンク時にROMのファイルからシンボルのみ参照する方法 --just-symbols=../../monitor-1.2-3069/monitor.coff 2)MAPを見て絶対アドレス #define OUT_STRING (( char * (*)(const char * ))0x00xxxxxx) xをマップをみて埋めるようです。 がネットに掲載されていました。 たぶん後者を参照されているのでしょうか。 さて、 >一応使っているコンパイラ、アセンブラ、リンカは付属CDの秋月製のものです。 >いろいろと試して、ライブラリ関数を宣言してオブジェクトファイル形式にしよう >としているのですが作成されたMAPファイルを見てみても関数が含まれておらず、 >よくわかりません。 これはROMに自作の関数をライブラリとしてリンクしたのでしょうか? それであれば、ROMの他のルーチンから呼び出されていないので、なにも取り込まれなかった だけかもしれませんね。
お礼
ありがとうございます。その方法をイメージしてました、参考になります. ROMに関数を書き込もうとしたときに、ただ、アセンブリ言語でライブラリ関数を宣言しただけのオブジェクトファイルをリンクしただけなので、失敗したのでしょうか。 実際にライブラリ関数などをROMに書き込む方法としてはどのようにしたらよいでしょうか。
お礼
ありがとうございます。 以前からこのページとはにらめっこしてますが(笑)初心者にはむずかしいですね>< ヘッダとの衝突とかも考えなくてはいけないのが難しいですね・・・