"関数配列"の書き込みがあったので、以前に気になっていた事を思い出しました。
関数をポインタで呼び出す場合のスタックサイズの確認はどのようにされているのでしょうか?
私は、ポインタで呼び出しを使わないので単純に計算できます。今は、CallWalkerを使ってます。
以前に、ポインタ呼び出しの下に#ifdef stack_check ・・・・#endifでテーブルの関数をすべて列挙しているのを見たことがあります。ちょっと、違うような気がします。
kijo さん
関数をポインタで呼び出す場合とはどんな方法なんですか、例えば
void sub(void){}
void _main(void)
{
void (*psub)(void) =⊂
psub();
}
こんなことでしょうか?
この場合はsub();とpsub();はスタック使用量は同じじゃないでしょうか。
スタックをある程度マイナスしてそこからレジスタpushしてという具合に
ポインタも実アドレスも同じことで関数パラメータをオバーライドして変更しない限りは同じでは?
普段、使わないので、自信が無いのですが、こんな感じですかね?IKUZOさんのと同じだとは思います。問題は、mainがsubを呼び出していることをツールでは知りようがない、コーディンした人以外に分かり辛いのではと思うのです。
void sub0(void){};
void sub1(void){};
void sub2(void){};
void sub3(void){};
typedef void (*funcptr)(void);
void main4(int i)
funcptr EventRoutine[] = {sub0,sub1,sub2,sub3};
if(i<sizeof(EventRoutine)){
(*EventRoutine[i])();
main4がsub0,sub1,sub2,sub3を呼んでいることはCall Wolkerでは分からず、プログラマが手計算するしかないように思えます。何かうまい手があるのでしょうか?
私なら、
switch i {
case 0: sub0();break;
case 1: sub1();break;
case 2: sub2();break;
case 3: sub3();break;
default: break;
と書くと思います。分岐があるので処理は遅くなるとは思いますが、Call Wolkerで最大のスタックサイズを計算してくれます。
(チャックしたつもりですが、コンパイルはしていないので、文法エラー等があるかもしれません。ご愛嬌と言うことでお許しください。)
CallWorkerですか、聞いたことがなかったのですが、コンパイラツールに含まれるのですか、
できたら利用してみたいのですが、これはルネサスのコンパイラ等に利用可能ですか?
この手のツールですが、普段使用していないのですが、ちょっとぐぐってみると
http://tool-support.renesas.com/autoupdate/support/jpn/cs_plus/List.html > スタック見積りツール> スタック見積もりツール
https://www.renesas.com/ja-jp/doc/products/tool/doc/005/r20ut3854jj0100-csrn.pdf > スタック見積もりツール(CallWalker含む)
https://www.renesas.com/ja-jp/doc/products/tool/apn/rjj06j0073_callwlkr_ap.pdf > スタック情報解析ツール「Call Walker」
http://resource.renesas.com/lib/jpn/e-learning/h8s/20/index.html > スタック解析ツールはコールウォーカーといいます。
なんか表記のぶれが酷いですね。それぞれ別のものを指してるのか、CallWalker(さすがに「Call Walker(空白入る)」「コールウォーカー(カタカナ表記)」は同じものだろう)がルネサスの唯一で共通の製品なのかもよくわかりません。何とかしてもらいたいものです。
fujita nozomu さん
ありがとうございました、普段使用しているHEWからCall Walkerが使用できたのですね、
灯台元暮らしでした、早速使用してみたいと思います、
ポインタでも実アドレスでもパラメータが変わらなければアドレスサイズがlongなのでmain4がsub0,sub1,sub2,sub3を呼び出すのと
}で呼び出すのと全く同じという解釈ですが、間違いですかね?ポインタを復帰させるのはmain4そのものだと思うのですが
ポインタの場合にツールが値を返せないのはどのアドレスを使用するのか確定できないからでしょう。
申し訳ありません。二番目の書き込みは焦ったのとコードに注意が向いてしまい、LとRを間違えてしまいました。みっともないので修正してしまいました。懲りずに40~50分で作文して投稿してます。
:
IKUZOさん。
CS+にもCall Wolkerはついてきます。
switch文が無駄な事をしていると言われそうですが、全く同じで良いと思います。
ここで問題なのはスタックサイズの確認方法です。Call Wolkerリリース前は、ソースコードや設計書から呼び出しの関係を、コンパイルリストとマニュアルからサイズを下のようにリストアップして必要なスタックサイズをチェックされていたと思ってます。
main4 ---+ 4
+--- sub0 4+8=12
+--- sub1 4+8=12
+--- sub2 4+4=8
+--- sub3 4+8=12
私はSHでこの作業に一週間かかりきりになった事があります。やはりツールに限界がありそうですし、手作業も大変になりそうなので、関数配列を私は使いません。皆さんは、どのようにされているのかが私の疑問です。上手い手があれば解禁しようと思ってます。
言い訳です。
指摘があったので、確認してみました。
ルネサスの複数のドキュメントでもドキュメント内でCall WalkerとCallWalkerのブランク有り無しが混在してます。
私は、あまり気にしてませんでした。皆様も同じものと言うことでお願いします。
ルネサスさん、よろしく統一をお願いします。
Call Walkerについて詳しくありがとうございます、
このツール使用して自分のソフトを検証してみたいと思います。
kijoさん
シェルティです、こんにちは。
私もCallWalkerを使ってスタック確認しています。
私は関数ポインタのあるソフトの場合は別途目視確認するようにしています。
関数ポインタ呼び出しはなるべく1モジュールに集約するとかでどうにかしていますが、
やはり人手が必要なところは計算ミスが混じったり、チェック実施自体が漏れたりなど問題の元になっています。
上手い手があれば私も知りたいですね。CallWalkerが便利であることには間違いないです。
あと、アセンブラで最適化したところも、CallWalkerでうまく拾ってくれないという問題がありますが、
これはアセンブラの疑似命令の .stack というのを使えば、CallWalkerが情報を拾ってくれるようになります。
以上です
シェルティさん、情報をありがとうございます。
アセンブラは滅多に使わないのと使っても最後の最後に少しだけなので、手作業で対応か、安全率でカバーしてしまいます。シェルティさんからの情報を使えばより正確に開発ができそうです。
弊社では計測が多いようです。実行時間は私も計測に頼ってますが、メモリーはぎりぎりも多く、統合テスト前にお手軽なCallWalkerで確認してます。実制御対象を使って計測するのを見ているとヒヤヒヤします。