- ベストアンサー
割り込みベクターをC言語で書きたい
皆さん、有難う御座います。時々質問させて頂いています。 今回は、ベクターアドレスをC言語で書く方法について質問します。 ルネサスのH8マイコンを使っています。モニターを使うとRAM上に割り込みの仮想ベクターを作れます。 仮想ベクターには、割り込みのジャンプ先アドレスが書かれます。 現在アセンブラで書いているのですが、C言語で書く方法は無いでしょうか。 二つの方法で書きたいと思っています。 アセンブラで次の二つの方法に相当するC言語命令を知りたい。 (1)ORGとEQU命令を使った方法 (2)ムーブ(Z80ならロード)命令で関数のアドレスをメモリに書く方法 ルネサスにはHEWと言うソフトが有りますが、HEW特有の命令によらず、一般的なコンパイラが持っている機能で実現したい。 以上宜しくお願いします。
- みんなの回答 (19)
- 専門家の回答
質問者が選んだベストアンサー
> *(void **)(0xFE130) = &test ; コンパイラに依存しないという意味では、上記の方法は問題があります。 CPUアドレスをポインタにキャストしても、期待した結果になるかどうかは保証されないからです。 ただ、通常はこれで問題なく動作するでしょうが... > 関数のアドレスを書き込む方法が分からないと配列に出来ません。 これは、 void vector00(); void vector01(); ... void (* const vectors[])() = { &vector00, &vector01, ... }; のようにすれば、配列にできます。
その他の回答 (18)
- zwi
- ベストアンサー率56% (730/1282)
>モニターは、ROM上のプログラムだって動かせます。 >仮想ベクタはRAM上に有ります。 >モニタとユーザが作ったプログラム両方をROMに置けます。 >モニタをそのまま使用するなら、Gコマンドでユーザプログラムを実行すれば良い。 >モニタを改造すれば、リセットスタートでユーザプログラムに飛ばす事も可能です。 そこまでしますか。 プロなら有り得ませんが、アマチュアならまぁやりたければどうぞ。 そもそも仮想ベクタがどうやって実現しているか分かってます? 表面上見えませんが、割り込み処理時に一度モニタに飛んでから更に仮想ベクタを参照して再ジャンプする仕組みになってるんで時間ロスが発生します。 それにRAM上にベクタがあることでメモリ破壊暴走の危険が増します。これもプロとしては許せません。 R32Cさんの書いているベクタの設定もそうですが、モニタを前提とした設計は無駄なことをしていると思います。
お礼
色々有難う御座います。 私の知りたかった事は、回答番号No5に有る様に解決しました。 この辺で締めませんか。 ここは人気が有って、C言語の質問があっと言う間に増えます。 私の方はもう解決したので、他の方の質問の回答に時間を使って頂きたいと思います。 また何か質問した時は、宜しくお願いします。
- R32C
- ベストアンサー率39% (115/290)
単純に、ベクタアドレスを設定する部分だけ、アセンブリ言語のソースとして 分割すればいいだけの話のように思います。 それが、Cなのかアセンブリ言語なのか、どちらでも保守性は変わらないと 思います。どちらかというとリンカの指定を省いてアドレス指定ができる アセンブリ言語で書いたほうが保守しやすいとは思いますが
お礼
色々有難う御座います。 私の知りたかった事は、回答番号No5に有る様に解決しました。 この辺で締めませんか。 ここは人気が有って、C言語の質問があっと言う間に増えます。 私の方はもう解決したので、他の方の質問の回答に時間を使って頂きたいと思います。 また何か質問した時は、宜しくお願いします。
- R32C
- ベストアンサー率39% (115/290)
同じこととしか思えないですね。 >しかし割り込みを使うと、START_Cを個別に変更しアセンブル >し直さなければ成りません。 >C言語だけで記述出来れば、START_Cの変更が入らなくなります。 C言語だけで記述できても、C言語で記述するベクターテーブルはコンパイル しなおさないといけないので同じですね。 補足要求の意味がわからなかったのでしょうか?
- R32C
- ベストアンサー率39% (115/290)
>H8/3052だけです。プログラムによって割り込みを使ったり使わなかったりすると、 >アセンブラのベクターテーブルをその都度変更しなければなりません。 > C言語で処理できれば、アセンブラ部分は変更しないで共通に使えます。 ??? なんかおかしくありませんか? Cで書こうとアセンブリ言語で書こうと、ベクタテーブルの変更が必要なら どちらの言語でも変更が必要ですよね。 確かに、 Cで書けば当然Cで変更が必要で、おっしゃるとおりアセンブリ言語の変更は不要ですが いったいどのような仕組みをお考えなんですか?
お礼
スタックポインタの設定など行うSTART_Cと言うアセンブラ・プログラムが有ります。その中で仮想ベクタの設定を行っています。 不意な割り込みが入ってもいいように、無限ループプログラムのベクタを入れて有ります。 割り込みを使わないC言語プログラムなら、START_Cはどれにでも使えます。 しかし割り込みを使うと、START_Cを個別に変更しアセンブルし直さなければ成りません。 C言語だけで記述出来れば、START_Cの変更が入らなくなります。
- zwi
- ベストアンサー率56% (730/1282)
> ルネサスで無料で提供しているモニタが有ります。 割り込みが入るとモニタに入り、そこからRAMに書いた仮想ベクタのアドレスに飛ぶようになっています。 えーと。伝わっていないかな? 全部のプログラムをROM化して、それをモニタから動かす気ですか? モニタが動かすプログラムってRAM上だし、ベクタもRAM上ですよね。ここで言うROM化とは、ROMに全て焼く&ベクタもROMにあるモニタもない状況です。 最終的にプログラムをROM化せずRAM上でモニタで動かす実験だけの予定であれば今の方針のままで良いですがそのつもりですかと伺っています。回答番号:No.2からROM化とは、そのつもりで言ってました。
お礼
>モニタが動かすプログラムってRAM上だし、ベクタもRAM上ですよね。 モニターは、ROM上のプログラムだって動かせます。 仮想ベクタはRAM上に有ります。 >ここで言うROM化とは、ROMに全て焼く&ベクタもROMにあるモニタもない状況です。 モニタとユーザが作ったプログラム両方をROMに置けます。 モニタをそのまま使用するなら、Gコマンドでユーザプログラムを実行すれば良い。 モニタを改造すれば、リセットスタートでユーザプログラムに飛ばす事も可能です。
- zwi
- ベストアンサー率56% (730/1282)
>1.RAM上で開発してROMに書き込みます。 > printf()などは大きくてRAMに収まりません。 > ROMに書いて、呼び出す実験をした事があります。 > コンパイル後にROMに書き、EQU命令で関数のアドレスを定義し、C言語で呼び出しました。 前にも書きましたがベクタを含めてROM化する場合は今のベクタをプログラムで書き換える方法は使えません。ROMですからね。そこの所はどう考えてますか?
お礼
ルネサスで無料で提供しているモニタが有ります。 割り込みが入るとモニタに入り、そこからRAMに書いた仮想ベクタのアドレスに飛ぶようになっています。
- zwi
- ベストアンサー率56% (730/1282)
richardoさん、はっきりしていないので答えてください。 1.RAMで使う前提である。ROMは考えていない。 2.H8限定。 3.H8アドバンストモード専用 4.C言語だけで全てを行いたい。アセンブラやリンカ・スクリプトでは何もしない。 って事ですよね?
お礼
zwiさん、 1.RAM上で開発してROMに書き込みます。 printf()などは大きくてRAMに収まりません。 ROMに書いて、呼び出す実験をした事があります。 コンパイル後にROMに書き、EQU命令で関数のアドレスを定義し、C言語で呼び出しました。 2.H8/3052用です。 3.そうです。アドバンストモードです。 4.C言語で対処出来るなら、C言語でやりたいという事です。 今までの結果は、回答番号5の「お礼」に書いた通りです。
- R32C
- ベストアンサー率39% (115/290)
> ヘッダ・ファイルは共通に使えるようになっていますよね。 > それと同様にC言語に伴うアセンブラ・ソフト部分も変更せず、 >C言語部分の変更だけで対処出来ないかなという事です。 ??? どれだけのCPUで共通部品にしようとしているのですか? 少なくとも、ベクターテーブルを持たないCPUでは使えないことは お分かりですよね?
お礼
R32Cさん、 >どれだけのCPUで共通部品にしようとしているのですか? H8/3052だけです。プログラムによって割り込みを使ったり使わなかったりすると、アセンブラのベクターテーブルをその都度変更しなければなりません。 C言語で処理できれば、アセンブラ部分は変更しないで共通に使えます。
- zwi
- ベストアンサー率56% (730/1282)
>でも私の質問は、「アセンブラなら実現方法が分かるけど、C言語で実現する方法を知りたい」という事です。 gccとかHEWのCコンパイラは重いから使いたくないって事ですね。しかし、そうするとセクションはC38H.EXEだと機能的に操れない可能性が高い状況ですから無理があります。C38H.EXEを自分で改造しますかって話ですね。 その貫き通したい気持ちは好きですが、そこまでやる気がありますか?
お礼
>C38H.EXEを自分で改造しますかって話ですね。 そんな事はしません。私の知りたかったのは、関数のアドレスを得る方法です。アスタリスクを上手に使うと得られるみたいだけど、その方法が分からなかったのです。 回答番号5のお礼に書いてある様に、その方法は分かりました。 有難う御座いました。
- R32C
- ベストアンサー率39% (115/290)
>そうなんです。C言語の本に載っているような一般性のある方法を探っています。 #1さんも 割り込み機能のないものはちょっと想像つきませんが、いいこと言っています。 割り込みベクタのないものはありますよね。SH3 ルネサスのスーパーH では、 SH1 SH2までベクタありますが、SH3以降上位のものは ベクタテーブルは存在しません。 ベクタテーブルそのものは、アークテクチャ依存なのです。 アークテクチャ依存部分を、一般的方法でC言語で記載しても、貴殿の言う共通部品には ならないですね。 少なくとも、ベクタテーブルの構成が同じアークテクチャのCPU間では共通部品となる 場合はありますが、管理上、共通部品とすると思わぬバグになるほうが危険だと思います。
お礼
R32Cさん、こんにちは ヘッダ・ファイルは共通に使えるようになっていますよね。 それと同様にC言語に伴うアセンブラ・ソフト部分も変更せず、C言語部分の変更だけで対処出来ないかなという事です。
- 1
- 2
お礼
回答有難う御座いました。 この方法で配列に出来ました。 残る課題はセクション指定です。 No.4, No.5 さんの回答にその方法が書いてあると思うのですが、自分の能力不足のためまだ良く分かりません。 これから調べようとしています。 また何か有りましたら、宜しくお願いします。