RA2A2でC++の標準出力が使えない

こんにちは。こじこじです。

RAファミリのRA2A2を使用しています。C++言語の標準出力が使用できなくて原因を調査中です。

開発環境は以下の通りです。

IDE:Renesas e² studio (Version: 2024-01.1)

言語:C++

コンパイラ:GNU Tools for ARM Embedded Processors (arm-none-eabi-gcc) (Version:13.2.1.arm-13-7)

FSP:v5.3.0

使用ボード:EK-RA2A2

<iostream>をインクルードしてもcoutを使用しなければ問題なく動作します。

hal_entry.cpp

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

#include "hal_data.h"
#include "main.h"
#include <iostream>

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
void hal_entry(void)
{
    Main main ;
   
    //std::cout << "Hello, World!" << std::endl;

    /* TODO: add your own code here */
    main.Loop() ;    
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ただ、上記コードの std::cout~~を記述すると、hal_entry()前のSystemInit()内でエラーとなってしまいます。

場所は以下です。

SytemInit()内の

__init_array_start[i]()実行時にbsp_common.cの__assert_funcに飛んでしまい、無限ループとなるので、これ以上プログラムが進みません。

C++言語のサンプルプロジェクトの【cpp_ek_ra2a2_ep】で同じことをすると、上記画像部分は問題ないのですが、

coutの行を実行しようとすると”_swiwrite()" に対して使用できるソースがありません ”となります。(その他_swrite()など複数も同様)

自作も【cpp_ek_ra2a2_ep】プロジェクトもGNU Arm Cross C++ Linker設定のMiscellaneousのOther linker flagsに

”--specs=rdimon.specs”を追加しています。

GNU Arm Embedded Toolchainではシステムコールの詳細を実装していない部分があり、実装の必要があると記事で見ました。

https://qiita.com/takahashim/items/120d69a44a80d08b70e7

手動で実装する代わりにrdimonを使うことで解決するとのことで、”--specs=rdimon.specs”を追加しています。

”--specs=rdimon.specs”を追加しないと、別途ビルドエラーが発生してしまいます。

これが何か関係あるのか不明ですが、情報として記載しておきます。

 

以上、手詰まりとなってしまい、ここに投稿させていただきました。

原因と解決策のアドバイスをお願いいたします。

Parents
  • FSPの設定(歯車アイコン,Configuration.xml)を開き、BSPタブのプロパティ

    Heap size(デフォルト0)が0の場合は、上記ハードコピーと同じ場所で止まりました。

    Heap sizeを確保して実行すると、今度はデフォルトハンドラに飛んできました(スタックオーバフロー)。

    そこで、次に、Main stack size(デフォルト0x400)を増やすと、hal_entry()まで飛んできました。

    (手元には、RA2A2のボードは無かったので他のマイコンでの試行です。)

    RA2A2(RAM48kB)ですと、0x4000+0x4000はちょっとメモリを食い過ぎだと思いますが(どこまで削れるかは試していません)、デフォルト設定ですと、ヒープとスタックメモリが足りていないという話なのではないかと思いました。

  • stdio関数、特にprintf系は大き目のヒープを要求するので避けられるものなら避けた方が良いです。
    大規模な関数はスタックも食いますし。
    coutだと更に迂遠な処理になるのでリソースの消費も処理時間も大きくなるはず。
    自前の文字列処理関数を作るか、代償を支払って楽をするかは状況次第ですが。

    rdimon.specs(でリンクされるライブラリ)にはstdioで参照される関数のスタブも含まれるので、指定しないとリンクエラーが出るのは不思議なことではありません。

Reply
  • stdio関数、特にprintf系は大き目のヒープを要求するので避けられるものなら避けた方が良いです。
    大規模な関数はスタックも食いますし。
    coutだと更に迂遠な処理になるのでリソースの消費も処理時間も大きくなるはず。
    自前の文字列処理関数を作るか、代償を支払って楽をするかは状況次第ですが。

    rdimon.specs(でリンクされるライブラリ)にはstdioで参照される関数のスタブも含まれるので、指定しないとリンクエラーが出るのは不思議なことではありません。

Children
No Data