はじめまして、GAと申します。表題の通り、RX660シリーズ向けのソフトを作成しております。その際に、どうしても自力で解決出来ないことがあり、こちらに投稿させていただきました。
◎状況取引先様から頂いた、元々H8Sシリーズにて使用されていたソフトを、CPU変更に伴い、RX660シリーズで作り直しています。その際に、移植前に__asmで宣言されていたインラインアセンブラをRXコンパイラに合わせて、#pragma inline_asmで書き直しています。しかし、書き換え後のソースにて、外部参照で別のファイルから参照することが出来ません。(エラー文が「Undefined external symbol」となり、ビルドに失敗します)何が原因で参照できず、何を変えれば解決するのか、お知恵をお借りできれば幸いです。今まで簡単なC言語しか取り扱ったことが無く、特にインラインアセンブラは初めて扱うレベルです。お力添えいただけますと幸いです。
◎開発環境
・使用マイコン移植前:HD64F2145B移植先:R5F56609EDFP
・開発環境 CS+(移植前の開発環境は不明ですが、恐らくHEWだと思われます)
◎該当箇所(社外秘の為、詳細な内容を書くことが出来ないことをご了承ください)
・sorce1old.c(書き換え前の関数実体のファイル)//その他の処理void AsmCode(void){ #pragma asm //アセンブラのコード #pragma endasm}//その他の処理
・sorce1new.c(書き換え後の関数実体のファイル)//その他の処理#pragma inline_asm AsmCodestatic void AsmCode(void){ //アセンブラのコード}//その他の処理
・sorce2.c(呼び出し先のファイル)void hoge(void){ //その他の処理 AsmCode(); //その他の処理}
・protype.h(プロトタイプ宣言のファイル)//その他の宣言void AsmCode(void);//その他の宣言
◎エラー内容
(E)E0562310 E0562310:Undefined external symbol "_AsmCode" referenced in "DefaultBuild\sorce1new.obj"test.mtpj
以上です。宜しくお願い致します。
追伸:申し訳ありません、どうしても頂いたコメントに直接返信が出来ないので、編集でご返信させていただきます。
わわいさん
GAです。早速のご回答ありがとうございます。
>ってことで、このstaticを外す、あるいは、externに書き換えてしまう、ってのをやってみてください。→この件につきまして、staticを外す、externに書き換えるの双方で確認しました。どちらも以下のようなエラーに変化しました。(E)E0552111 C:\document\test\sorce1new.c(1614):E0552111:Symbol is undefined sorce1new.c 1614 test.mtpj(E)E0552006 C:\document\test\sorce1new.c(1614):E0552006:Size specifier is not appropriate sorce1new.c 1614 test.mtpj(E)E0552001 C:\document\test\sorce1new.c(1614):E0552001:',' is missing sorce1new.c 1614 test.mtpj(E)E0552052 C:\document\test\sorce1new.c(1614):E0552052:Addressing mode specifier is not appropriate sorce1new.c 1614 test.mtpj(E)E0552004 C:\document\test\sorce1new.c(1614):E0552004:Invalid operand(s) exist in instruction sorce1new.c 1614 test.mtpj(E)E0552113 C:\document\test\sorce1new.c(1614):E0552113:Symbol definition is not appropriate sorce1new.c 1614 test.mtpj(エラーに出ている1614行目は、#pragma inline_asm AsmCodeの直前の行になります)その後、一旦今のアセンブラのコードをコメントアウトして、ごく簡単な(NOPのみ)のコードに差し替えたところ、無事ビルドが通りました。元々のアセンブラコードをそのまま使用していたので、今のCPU向けにアセンブラを書き換えていきます。お忙しい中、ご対応いただきありがとうございました。
この件とは直接関係が無いかもしれませんが、ルネサスのドキュメント内にて、#pragma inline_asmで宣言している関数には、必ずstaticで呼び出されているように思えます。これには何かしら(ハード的、ソフト的等の)意味があるのでしょうか。今回のようなプロトタイプ宣言で他ファイルからの呼び出すような使い方は避けるべきなのでしょうか。もしご存じでしたら、お教えいただけますと幸いです。
大変申し訳ございません、再度上手く返信が出来ない為、こちらに追加させていただきます。
GAです。ご回答ありがとうございます。
>エラーメッセージというのは、なぜそのエラーが出ているのか、を解説してくれています。それを読まないというのは非常にもったいないことです。→ご指摘ありがとうございます。 現状、エラーメッセージを参考にして、何が良くないかを探り始めたところでございます。
>たんに他のソースファイルから参照しないからstaticをつけている、だけでしょう>ここでそれを説明するってのはちとつらいので、static inline で、検索してみてください。→ご教授いただきありがとうございます。 今回取り扱っているソフトでは、ソースファイルに記述しているものですので、単にstaticを外すだけで問題なさそうです。 後学の為に、static inlineについては、勉強させていただきます。 お教えいただき、ありがとうございます。
わわいです
> static void AsmCode(void)
staticをつけてしまうと、その関数の有効範囲はそのファイルの中だけ、になってしまい、他のファイルからの参照はできなくなります
ってことで、このstaticを外す、あるいは、externに書き換えてしまう、ってのをやってみてください。
エラーメッセージから想像するにメモリアドレス範囲が問題になるニーモニックが使われていることが原因でしょうね。「static」で書いてあるというドキュメントはどれか知りませんが、この資料の225ページの例ではそんなことはないです。www.renesas.com/.../high-performance-embedded-workshop-rx-family-cc-compiler-package-v101-users-manual-includes-v102
Shoji Yamamoto さん
GAです。ご回答ありがとうございます。>エラーメッセージから想像するにメモリアドレス範囲が問題になるニーモニックが使われていることが原因でしょうね。→ご教授ありがとうございます。 現状、内容を読み解いている段階ですが、メモリアドレス範囲は注視してみます。>「static」で書いてあるというドキュメントはどれか知りませんが、この資料の225ページの例ではそんなことはないです。→こちらに関しても、ありがとうございます。 内容確認しましたが、確かにこの資料だとstatic宣言されていませんね。であれば、あまり関係はないと考えておくことにします。
> どちらも以下のようなエラーに変化しました。
ってことで、当初のエラーはこの対処で解消され、他のエラーが見えるようになった、ということですね。
エラーメッセージというのは、なぜそのエラーが出ているのか、を解説してくれています。それを読まないというのは非常にもったいないことです。
> #pragma inline_asmで宣言している関数には、必ずstaticで呼び出されているように思えます。
たんに他のソースファイルから参照しないからstaticをつけている、だけでしょう
グローバルな関数にしない理由はないと思います。
> たんに他のソースファイルから参照しないからstaticをつけている、だけでしょう
と書きましたが、ソースファイルで記述してる、ってならこのとおりですが、ヘッダファイルでstatic inline で関数自体を記述して、他のソースファイルからインクルードさせる、というのはまた別の意味を持ちます。
ここでそれを説明するってのはちとつらいので、static inline で、検索してみてください。解説の記事が出てくるかと思います
GAさま
オリジナルのH8Sのプログラムでアセンブラが使われていたのは、タイミングをシビアに決めたかったから等、アセンブラの方が都合が良い理由があったのだと思いますが、単に速度的な問題(高速化のためにアセンブラを使用した)のであれば、RX660(120MHz)であれば普通にC言語で書いても良いかも知れません。
…などと、ちょっと思いました。
tfさん
GAです。ご教授いただきありがとうございます。今回のアセンブラコードについては、恐らくアセンブラで実行することに意味があるようなのです。(どうやらセルフチェックとして、アセンブラの命令がちゃんと動いているかを見ているようです)確かに、今回のRX660でしたらC言語でも十分な速度がありますので、速度という観点であれば、無理にアセンブラを使用する必要はないという点は理解出来ました。今後の検討の参考にさせていただきます。
GAです。
上記の件につきまして、アセンブラコードのエラー修正と一部コメントアウトを行い、先ほど無事動くことを確認致しました。ありがとうございました。アセンブラコードで一件解決していない問題があり、そちらは別スレッドにて改めて質問させていただきます。一部投稿が上手くいかず、返信が滞ってしまってしまい、申し訳ありませんでした。追加事項が無ければ、本件クローズとさせていただきます。