電源起動の高速化

お世話になっております。entakeと申します。

R8C/1Bシリーズで、
電源ONからメイン処理が動き出すまでの時間を最速で行いたい場合、どのような方法が考えられますでしょうか?

FAQを探っていて、「スタートアップファイル(ncrt0.a30)ではRAMの初期化も行っています。リセット解除後のCPUクロックは低速オンチップオシレータの8分周のため、RAMの初期化に数十ms程度かかる場合があります。」という記述を見つけたので、RAMの初期化をメインクロックに切り替えた後に行うようにすれば良いのでは、等と考えていますが、そんなことは可能なのでしょうか??
他に何かアイデアなどありましたら是非お願い致します。

XINには、TCXO20MHzを接続し、メインクロック切り替え時の発振安定待ち時間を無くすことで、ある程度は早く動くようになりましたが、さらに高速起動を目指しています。
  • entakeさん

    スタートアップファイル(ncrt0.a30)の内容を修正して、
    ファイルの先頭にメインクロックを切り替える処理を追加すればRAMの初期化をメインで行うことができます。(アセンブラですけど)

    ちなみにメインクロックの発振安定時間を待たずに切り替えてしまうとノイズで発振が途中で止まってしまうことがあるので注意してくださいね。


    ということで、
    スタートアップの先頭でCM13ビットを“1”(XIN-XOUT端子)、CM05ビットを“0”(メインクロック発振)にしておき
    RAMの初期化を低速オンチップオシレータで行うと
    ある程度の発振安定時間が確保できるので、RAM初期化後におもむろにOCD2レジスタでメインに切り替えるのが良いと思います。
  • entakeさん

    Kirinさんの回答で問題ないのですが、実際に使用した高速立ち上げの実績が有るので参考程度に説明します。

    5年位前の話ですが、高速立ち上げが必要になった事がありました。
    高速立ち上げが必要になった背景ですが、R8C2Bを使用していて有機ELディスプレイが接続されたオーディオ用PCMレコーダーを製作していた時の話です。

    使用した有機ELディスプレイが、なんと電源投入でノイズが表示されてしまう代物でした。
    内蔵VRAMの初期化処理を行なっていないのとモード設定しなくても表示が始まってしまうらしい。(^_^;)

    R8Cの初期化に30ms位と表示データを転送するのに約20ms(5MBpsのSPI接続で、画面データは一筆書き)です。結果、電源入れると適当にノイズだったり、電源OFFの画面だったりします。
    いろいろ調べた結果、R8CのRAMを3.5kバイト殆ど使用していましたので、クリアに時間が必要だった見たいですね。
    そこで、いろいろやったのですが、結果的に高速クロックに切り替えてからしか早い起動が出来ませんでした。


    実際に使っている方法ですが、スタック等を設定した後に高速オンチップオシレータに切り替え(発振動作確認必要)、内臓RAMの0クリアと初期値設定を行ないMainルーチンでハードウェア初期化処理を行なっています。
    高速オンチップオシレータに切り替えは、Cのサブルーチンをコールして使っています。

    Kirinさんの回答から、メインクロックの停止が問題ならば、Mainルーチンで切り替えされたら安定発振していると思われます。

    以上、SSでした。
  • >Kirinさま
    早々のコメントありがとうございます。
    Kirinさまの言葉に勇気付けられ、スタートアップファイル(ncrt0.a30)の内容を修正して、狙い通りの成果を上げることができました。
    メインクロックへの切替えは、startセクションの最初(ISP設定よりも前)で行うようにしても正しく動作する様子なので、とりあえずこれで使っていますが、絶対にスタックポインタとプロセッサモードは最初に設定しないと危ない!などの情報をお持ちでしたら、ご指摘いただけると助かります。

    後半に書いてくださった方法は、発振子で発振回路を構成している場合には最も効率的かと思います。良いアイデアを開示していただき感謝致します。
    今回はTCXOによって外部でクロックを生成するため、TCXO自体のスペックが支配的になるかと思います。マイコンのスタートアップが走るのは、Vdd=1.9V以上になってから約1.7ms程度と聞いていますので、それ以下でTCXOが安定していれば安心して発振安定待ちを省略できる見込みです。
    間違いなどありましたら、ご指摘いただけると助かります。
  • >SSさま
    背景を含む実例のご提示ありがとうございます。
    私も似たようなきっかけで、高速化が必要になったので、非常に参考になります。
    最終的には、高速オンチップオシレータを使ってRAM初期化を30ms程まで早められたという理解で良いでしょうか?
    私の環境でもリセット直後から20MHz動作に切り替え、RAM初期化を経由してメインルーチンまで、なんとか約28msまで短縮できました。
    RAMの使用量に応じて初期化時間に影響があるのであれば、RAMを節約するように再設計するのも手ですね。
    設計のヒントを与えてくださり感謝いたします。
  • entakeさん

    失礼しましたTCXOでしたね。水晶振動子だと思い込んでました。

    高速化のためならば、RAMの初期化をしないという手もあります。
    BSS空間が0クリアされていないくても問題なさそうですし
    初期値付きのstatic変数を使わなければ、
    ROMからRAMに初期値を転送する必要もないので
    かなり高速化できそうです。


    試しにRAMコピー部分を全部コメントアウトしちゃったら早くなりそうですよ。
    ;-----------------------------------------
    ; bss zero clear
    ;-----------------------------------------
    ;N_BZERO bss_SE_top\,bss_SE
    ;N_BZERO bss_SO_top\,bss_SO
    ;N_BZERO bss_NE_top\,bss_NE
    ;N_BZERO bss_NO_top\,bss_NO
    ;------------------------------------------
    ; initialize data section
    ;------------------------------------------
    ;N_BCOPY data_SEI_top\,data_SE_top\,data_SE
    ;N_BCOPY data_SOI_top\,data_SO_top\,data_SO
    ;N_BCOPY data_NEI_top\,data_NE_top\,data_NE
    ;N_BCOPY data_NOI_top\,data_NO_top\,data_NO
  • >Kirinさま

    再度コメントありがとうございます。
    ご指示いただいたコード部分全体の実行時間を計ってみると、47msでした。これが無くなればかなり高速化になりますが、動作への影響が読めないために、とりあえず見送ります。
    せっかくテストポート出力を入れたので、リセット解除から20MHzに切り替えた場合と、通常の場合(低速オンチップオシレータ×8分周)とで、速度を比較してみました。
    動作クロックの違いから、1280倍は早くなる計算ですが、実際に1175倍(RAM初期化時間=0.04ms)まで高速化できていました。40usでRAM初期化ができれば十分ですので、このまま運用したいと思っています。
    それにしても、リセット解除直後からSP設定よりも先に外部クロックに切り替えるなんてことをして、何かMCUの動作に悪影響がなければ良いのですが。。
  • entakeさん

    > それにしても、リセット解除直後からSP設定よりも先に外部クロックに切り替えるなんてことをして、何かMCUの動作に悪影響がなければ良いのですが。。

    SPはサブルーチンコールやPOP\,PUSHでしか使わないので
    そういった操作をする直前までにやればいいので、
    SP未初期化のまま、リセット直後にレジスタ操作やメモリ操作を行ってもなんら問題ありませんよ。
  • entake さん、 Kirin さん

    こんにちは ramoth です

    R8CのC/C++ コンパイラのスタートアップルーチンのソースは
    未見ですが、Resしています。

    よくあるミスとして、RAMの初期値設定
    部分を実現するために、ライブラリ内の関数(サブルーチン)
    呼び出しが行われていたりする場合があるので、
    スタートアップルーチンのソースをアセンブラレベル
    でよくチェックしておく必要があります。

    また、I/Oの初期化(クロック設定)を追加
    したときに勢い余って割り込みを許可してしまうと、
    想定外のスタックアクセスが発生してしまいます。





  • すと@konです。

    補足です。


    R8C/M16Cコンパイラでの初期化(Bセクション、Dセクション)はSMOVF、SSTRのアセンブラ言語による転送命令を使用しているはずです。

    こちらはスタックを利用しませんので、RAM初期化はSPの初期化タイミングに依存しません。
  • >Kirinさま

    コメントありがとうございます。
    確かにSP未初期化でも問題ないようです。
    ちょうどルネサスのアプリケーションノートでスタートアップに関する記述を見つけましたので、この記事を読んでくださっている方々のためにも、少々引用させていただきます。
    (コードをそのまま貼り付けようと思いましたが、何か著作上問題あるかもしれないので、出典だけ最後に示します)
    この資料によると、
     1.プロセッサ動作モードの設定
     2.スタックポインタの初期化
     3.FB\,SBレジスタ初期化
     4.INTBレジスタ初期化
     5.データのnear領域の初期化
     6.データのfar領域の初期化
     7.heap領域の初期化
     8.標準入出力関数ライブラリの初期化
     9.main関数の呼び出し
    のような構成で説明されており、上記1.のコード例の中でシステムクロックの設定を一緒に行っているのを見つけました。
    どうやら、割と一般的なのかもしれません。
    上記を参考に、システムクロックをXINに切り替えるのは、1.と2.の間で行うようにします。
    おぼろげな不安が解消されました、ありがとうございます。

    参考資料:「M16C/60 シリーズ\,M16C/20 シリーズ プログラム作成の手引き< C 言語編 >」rjj05b0118_m16cap.pdf