MISPOさんのNORTiをRX SmartConfiguratorと一緒に使いたい場合の課題と対策を考察してみるスレッド

こんにちは。NoMaYです。

ひとつ立てても良さそうな気がしましたので立ててみました。

もっとも、その前に気になる問い掛け、が無いわけでは無いですけれども、、、

● マイコンベンダ提供のソフトウェア開発フレームワークと共存させることが苦痛な実装のRTOSを今後も新規プロジェクトで使う予定がありますかね

[関連スレッド]

スマートコンフィグレータの自動生成をカスタマイズしたい
japan.renesasrulz.com/cafe_rene/f/forum5/8248/thread

FITの割込みハンドラの実装について
japan.renesasrulz.com/cafe_rene/f/forum5/8212/fit

RX72Nで簡易I2C通信をしたい。DATAは出力されているがCLKが何故か正しく出力されない。。
japan.renesasrulz.com/cafe_rene/f/forum5/7129/rx72n-i2c-data-clk

FITでのSCI使用時に文字を1文字送信すると、プログラムが固まります。
japan.renesasrulz.com/cafe_rene/f/forum5/7071/fit-sci-pc-1
 


RX SmartConfiguratorで気になった点とか改善する案とか報告してみるスレッド
japan.renesasrulz.com/cafe_rene/f/forum5/7536/rx-smartconfigurator/42599#42599
 

Parents
  • ふぐりんです
    NoMaYさんこんにちは。


    以下のスレッドでNoMaYさんに作っていただいたプログラムで
    NORTiをRX SmartConfiguratorと一緒に使えるようになったようです。
    NORTiユーザとしてFITとの同居という念願がかないました。(共存させることが苦痛な実装のRTOSじゃなくなった?w
    NoMaYさんありがとうございました!

    スマートコンフィグレータの自動生成をカスタマイズしたい
    japan.renesasrulz.com/.../thread

    ソース追いかけたり実験したりしてたので遅くなりましたが確認が取れました。
    詳しいやりかたなどは私のGitHUB(github.com/mkogax)に上げたいと思っていますが、NoMaYさんのソースを転載してもよろしいでしょうか?許可いただければ、ファイルとしてそのまま収録したいと思います。
    以下簡単なご報告です。

    ----------
    セットアップ
    ----------
    NoMaYさんの NORTi_interrupt.c (20220629_2版) をそのまま改変なしで使用しました。
    ただし、NORTi_interrupt.h で全て NORTiタイプを指定し、INTBにはNORTi管理のベクタテーブル(RAM)を登録します。
    NORTi側は初期化時に呼ばれる intini() (利用者が作るヘルパ関数のようなもの)を改造するだけです。

    ----------
    効果
    ----------
    ・FIT/CGは改変なしでそのままNORTiを利用できます。(コールバックでNORTi利用可)
    ・NORTiの割込みハンドラ(def_inh())をそのまま利用できます。
    ・NORTiの割込みサービスルーチン(cre_isr())をそのまま利用できます。(最初におまじない必要)
    ・FIT/CGの割込み処理はNORTi対応で少しオーバヘッドが増えますが、NORTiを使わないで高速に処理したい場合(nonOS)はdef_inh()で対応できます。

    ----------
    実験(Target Board for RX130,CS+)
    ----------
    ・r_cmt_rx(FIT)の10msec周期コールバックからNORTiのチックタイム通知(isig_tim())
    ・TMR0(CG)で#pragma interrupt の割込みルーチンからタスク起床(wup_tsk())
    ・TMR1(CG)の改造でdef_inh() のNORTi割込みハンドラからタスク起床(wup_tsk())
    ・TMR2(CG)の改造でcre_isr() のNORTi割込みサービスルーチンからタスク起床(wup_tsk())
    ・TMR3(CG)で#pragma interrupt の割込みルーチンを非NORTiとして再登録(def_inh())してカウンタ変数更新を確認

  • ふぐりん さん、こんにちは。NoMaYです。

    どうもありがとうございました。新たな技も開発されたみたいですね。そして、以下の件、もちろん転載して構わないです。

    > 詳しいやりかたなどは私のGitHUB(github.com/mkogax)に上げたいと思っていますが、NoMaYさんのソースを転載してもよろしいでしょうか?許可いただければ、ファイルとしてそのまま収録したいと思います。

  • NoMaYさんありがとうございます!
    できたらここにご報告します。

  • ふぐりんさん、 NoMayさん、こんにちは

    こんな事できないかなぁ、と思って投稿させていただいた事から話か進んで

    より良い方向に向かう事ができました。

    改めて、かふぇルネ、皆さんの力、偉大だなぁと思っています。

    ありがとうございます。

    ふぐりんさんのGitHUBも拝見させていただき、使用してみたいと思っています。

  • NoMaYさんka.makiharaさんこんばんは。

    いやー遅くなってしまいました・・w
    なんせ初めてなもんで、いろいろだいじょうぶかなと心配なんですがとりあえず書き上げましたのでご覧ください。

    「NORTi を RX Smartconfigurator と一緒に使う方法」
    https://github.com/mkogax/How-to-use-NORTi-with-RX-Smartconfigurator

    NoMaYさん考案のプログラムによって、NORTiとスマートコンフィグレータを一緒に使うことができるようになりました。スマートコンフィグレータ(FIT/CG)の自動生成コードは何も改変せずに、ユーザコードエリアやコールバックからNORTiの機能を使えます。またNORTi方式の割り込みもそのまま併用できます。

    何かまずい点などお気づきでしたらお知らせください。すぐに修正します。
    (2022.07.14 説明加筆)

  • ふぐりんです

    先日また古川制御さんと雑談してて未定義命令例外とかどうしてんの?って話が出ました。

    INT/BRK(ベクタ番号=0..15)はnonOSにしています。
    また例外ベクタテーブル(EXTB)の割込みはいじってないのでそのまま(nonOSと同じ)です。
    このあたり利用する人はいろいろ理解してるだろうからこれで良いと思ってるんですが解説には注意書きを追加しました。

    自分はあんまりこの辺を使ったことないので、ちょっと試そうかなって思ったら、RX130ってEXTBレジスタもFPUも付いてないんですねw
    TargetBoardのRX65N引っ張り出しました。
    試しにFPUでゼロ割させて浮動小数点例外の中で何もしないと無限割り込みするんで、やっぱnonOSで発生時のPCが分かるようにしといた方が良いだろうと思いました。(このへんの実装の正解ってどっかあるんでしたっけ?)

    あと、試しにRX65Nを120MHzで動かしたら、実験2でwup_tsk()から起床まで32MHzのRX130で5.9usecかかってたのが1.7usecになってました。MHzの倍率にならないのはROMのウェイトですね。r_bspでちゃんとセットされてました。

    (いろいろ実験して楽しかったので書きましたw)
    (それにしてもNoMaYさんのルーチンはさすがですね。nonOSはまるで無かったかのように割込みルーチンに影響しません)
    (BASERRはNORTi対応です。ちょっと迷ったんですが・・最悪def_inh()で変更できるしそのままにしてます)
    (うーんNORTiの人口は少ないのかな。NoMaYさんのアイデアすごい画期的なのに反応が薄いw)

Reply
  • ふぐりんです

    先日また古川制御さんと雑談してて未定義命令例外とかどうしてんの?って話が出ました。

    INT/BRK(ベクタ番号=0..15)はnonOSにしています。
    また例外ベクタテーブル(EXTB)の割込みはいじってないのでそのまま(nonOSと同じ)です。
    このあたり利用する人はいろいろ理解してるだろうからこれで良いと思ってるんですが解説には注意書きを追加しました。

    自分はあんまりこの辺を使ったことないので、ちょっと試そうかなって思ったら、RX130ってEXTBレジスタもFPUも付いてないんですねw
    TargetBoardのRX65N引っ張り出しました。
    試しにFPUでゼロ割させて浮動小数点例外の中で何もしないと無限割り込みするんで、やっぱnonOSで発生時のPCが分かるようにしといた方が良いだろうと思いました。(このへんの実装の正解ってどっかあるんでしたっけ?)

    あと、試しにRX65Nを120MHzで動かしたら、実験2でwup_tsk()から起床まで32MHzのRX130で5.9usecかかってたのが1.7usecになってました。MHzの倍率にならないのはROMのウェイトですね。r_bspでちゃんとセットされてました。

    (いろいろ実験して楽しかったので書きましたw)
    (それにしてもNoMaYさんのルーチンはさすがですね。nonOSはまるで無かったかのように割込みルーチンに影響しません)
    (BASERRはNORTi対応です。ちょっと迷ったんですが・・最悪def_inh()で変更できるしそのままにしてます)
    (うーんNORTiの人口は少ないのかな。NoMaYさんのアイデアすごい画期的なのに反応が薄いw)

Children
  • ちょっと調べものしてて手持ちのTargetBoard見てたらRX66Nは120MHzでもROMのウェイトが不要らしいですね。
    実験2を試したら1.33usecでした。
    あれ?速すぎるw
    ROMキャッシュが効いてる?
    あ、でも65Nもキャッシュはあるんだけど・・66Nのキャッシュは8Kバイトで、65Nは256バイトだからヒットしないのかも

  • やっぱりBUSERRでトラブりました・・(勘は当たってしまいましたw)
    ご報告です。

    【前提】
    BUSERR(バスエラー割り込み,ベクタ番号16)は不正なアドレスをアクセスする等で発生します。
    スマートコンフィグレータでr_bspを入れてると割り込みレベル15で割込み許可になるようです。
    そのままでも、BUSERRの割込み処理 bus_error_isr() で BERCLRレジスタを使って割込み状態がクリアされるので、万一BUSERRが発生しても処理は続行できるようになってました。

    【発生現象】
    しかし、「NORTi を RX Smartconfigurator と一緒に使う方法」の手順でNORTi対応すると bus_error_isr() が呼ばれる前に v3_ent_int() をコールするため、v3_ent_int() の中で再度BUSERR割込みが発生して暴走します。(NORTiの許容割り込みレベルより高い割り込みレベルで、しかも割込みと同時に割り込み状態がクリアされないタイプの割り込みのため)

    【対策】
    NORTi_interrupt.h の INTERRUPT__16 を nonOS にします。
    これでv3_ent_int() が呼ばれなくなるので暴走しません。(ただし、BUSERR割込みのコールバックでNORTi のAPIは使えません)

    いやー半年以上前のことなんで、すっかり忘れてました。
    どうせまた忘れるのでw、もう「NORTi を RX Smartconfigurator と一緒に使う方法」の NORTi_interrupt.h を修正しちゃいます。

  • ふぐりん さん、こんにちは。NoMaYです。

    お久しぶりです。すみません、ちょっと知りたいです。再度BUSERR割込みが発生するカラクリが腑に落ちなかったのです。r_bspで割り込みレベル15になっていたとのことですが、自分の認識ですと、その割り込みが発生するとPSW.IPLが15になり、それ以降はその割り込みが終了するまで一切の(多重)割り込みが受け付けられない筈のような気がするのです。

    ひょっとして、v3_ent_int()の中でPSW.IPLの値を下げるようなことが行われていたりするのでしょうか?ちょっと気になるのです。

  • NoMaYさんおひさしぶりです!(半年ROMってましたw)

    割込み発生時 v3_ent_int() コール直前では PSW.IPL が 15 で、PSW.I は 0(割り込み禁止)でした。
    その後、v3_ent_int() のはじめあたりで PSW.IPL が カーネルレベル(KNL_LEVEL、defaultは6)になると同時に PSW.I が 0(割り込み許可)になってるようです。

    これは、NORTiのカーネル処理中であってもカーネルレベルを越える割り込みは受け付けるようにするためだと思います。

    以下はNoMaYさんはお判りでしょうから蛇足です。
    (高速とは言えカーネルは重いですからねえ・・)
    (もちろん、カーネル処理中はカーネルレベル以下の割り込み=NOPRTiのAPIが使える割り込みは受け付けません)

  • ふぐりん さん、こんにちは。NoMaYです。

    情報ありがとうございました。やっぱりそういうことなんですね。思ったのは、ベクタ割り込み全般に渡ってNORTiのAPIを使えるよう、くだんのやり方でフックする場合、基本はKNL_LEVEL=15へと設定変更しておくものであるような気がします。

    そして、特殊な高優先度の割り込みが必要となったところで、慎重に諸々の割り込み優先順位を調整しつつ、KNL_LEVEL=14とか13とかへ変更していくものかな、と、、、

    もし、v3_ent_int()の中を弄れるなら、そして、NORTi_interrupt.hをちょこまか変更するのが手間と感じるなら、ちょうど別スレッドで投稿しているコードのように、PSW.IPLとKNL_LEVELを比較し、少なくともPSW.IPLを下げないようにしておくと、多重割り込み全般で今よりも安全になるような気がしました。以下のような感じですけれども。(別スレッドから咄嗟に抜き出して書き換えたものですけれども。)

        if(KNL_LEVEL > (((R_BSP_GET_PSW()) >> 24) & 0xF))
        {
            R_BSP_SET_IPL(KNL_LEVEL);/* MVTIPL #IMM:4*/
        }
        R_BSP_SETPSW_I();

     

  • NoMaYさん、こんにちは!

    KNL_LEVEL=15 や v3_ent_int()の修正もおっしゃるとおりではあるのですが・・

    「NORTi を RX Smartconfigurator と一緒に使う方法」を利用される方は、それぞれいろんな事情をお持ちだと想像すると、あんまりFIT/CGやNORTiのデフォルトをいじりたくないんですよねえ・・

  • ふぐりん さん、こんにちは。NoMaYです。

    いやいやいや、それでもPSW.IPLが小さくなっちゃうのはアカンと思うのです。もしかすると、以下の文面からして、何かそこに誤解があるような気がし始めました。

    > これは、NORTiのカーネル処理中であってもカーネルレベルを越える割り込みは受け付けるようにするためだと思います。

    私は、ミスポさんの前提は以下だと思うのですけれども、マニュアルのどこかに書いてないでしょうかね、、、

    (1) v3_ent_int()を呼ぶことが許されるのは割り込み優先順位がKNL_LEVEL以下の割り込みのみである
    (1') 言い換えると、割り込み優先順位がKNL_LEVELより高い割り込みはv3_ent_int()を呼んではいけない

    (2) その前提でミスポさんはv3_ent_int()の初めでPSW.IPL=KNL_LEVELにしてPSW.I=1に設定している
    (2') つまりミスポさんとしてはPSW.IPLを(たぶん排他制御目的かな?)割り込みの初めで一時的にPSW.IPL=KNL_LEVELへ上げるのみが設計意図である

    (3) ところが、今回はその前提を守らずにv3_ent_int()を呼んでしまっているのでPSW.IPLが小さくなってしまう事態が起きている
    (3') 私は、PSW.IPLを下げるというのはミスポさんの設計意図ではないと思う

    あるいは、こういうように書くと、事態の変さ具合が伝わるでしょうか、、、

    (4) PSW.IPLを下げるということは、高い優先度の割り込み処理中に低い優先度の割り込みを受け付けてしまう、ことになりますよ、、、

  • NoMaYさん、こんにちは!
    お返事ありがとうございます。

    (1)(1')はそのとおりです。MISPOさんの取説に書いてあります。
    KNL_LEVELより高い割り込みからは、v3_ent_intを含むNORTiのすべてのシステムコールを呼んではいけないことになっています。
    (2')の「KNL_LEVELへ上げるのみが設計意図」もそのとおりで、下げることは想定外です。
    ですので、(4)「PSW.IPLを下げる」という想定は成立しない気がしますが・・

  • ふぐりん さん、こんにちは。NoMaYです。

    いや、ですから、今回、割り込み優先度15で受け付けたBUSERR割込みの中でPSW.IPL=6へ下がってますよね、、、

  • NoMaYさん、すいません。なんか行き違いがあったようですね。

    今回、私はBUSERRの割り込みを nonOS に変更しました。(NORTi_interrupt.h)
    KNL_LEVELより高い割り込みのBUSERRでは v3_ent_int() は呼ばれません。
    ですので、(4)の「PSW.IPLを下げる」は発生しません。

    じつは BUSERRの割込みレベルを下げようとしたんですが、Config_BSC(設定)とr_bsp(固定)の2か所でセットしてるみたいで・・
    弱虫なので「あ、これは触らんでおこう・・」と思ってしまったんでしたw