FITのRTOS対応版BSPでレジスタライトプロテクトが解除された状態で他タスクへ遷移出来てしまうのは少し怖いと思うのですが、、、

こんにちは。NoMaYです。

CC-RX用プロジェクトのFITのBSPモジュールとFIT+FreeRTOSを使うアプリケーションノートのRTOS対応版BSPモジュールを比較していて、RTOS対応版ではcpu.cのR_BSP_RegisterProtectDisable()とR_BSP_RegisterProtectEnable()が関数内でプリエンプトによるコンテキスト切り替えが起きた時に誤動作する可能性を排除する為に割り込み禁止にする処理が追加されていたことに気付いていたのですが、追加された処理を見ていて、これらの関数内ではコンテキスト切り替えが発生しないようになったものの、これらの関数でレジスタライトプロテクトを一旦解除してから再度設定するまでの区間でコンテキスト切り替えが起きる可能性が残されていることに気付きました。(印象ですが、設計意図なのだろうという気がします、、、)

そのこと自体により誤動作することは無いと思われますが、ただ、なぜレジスタライトプロテクトという機能がマイコンに組み込まれているのかという観点からすれば、レジスタライトプロテクトが解除された状態でコンテキスト切り替えが起きて他タスクへ遷移してどんどんコードが実行されていくという状況は少し怖いなと思いました、、、

以下、処理を見ていて分かったことです。

たぶん、もともとFITのBSPモジュールは、RTOSを使う場合でも関数の変更や関数の追加をしなくても済むようにすることを狙っていただろうと思います。なぜなら、以前に別スレッド『GUNRX用プロジェクトのスマートコンフィグレータのBSPを見ていて気付いた変な移植コード』で話題にしたR_BSP_SoftwareLock()というRTOSで使われることを想定していると推測される関数が含まれていたりするからです。

そして、今回の件のR_BSP_RegisterProtectDisable()とR_BSP_RegisterProtectEnable()という関数もRTOSを使う場合でも誤動作しないようにする為に(だと思うのですが)、もともと通常版自体が、図1-1と図1-2のソースの通り、カウント変数を使用した少し複雑な設計になっていました。推測ですが、RTOSを使った場合の図1-3のようなコンテキスト切り替えが起きた時でも誤動作しないようにすることを狙っていたのではないかと思います。

図1-1 通常版BSPでのR_BSP_RegisterProtectDisable()の実装


図1-2 通常版BSPでのR_BSP_RegisterProtectEnable()の実装


図1-3 このようなコンテキスト切り替えが起きた時でも誤動作しないようにすることを狙ったのだと思う


しかし、設計に見落としがあった為、図1-4のようなコンテキスト切り替えが起きた時には誤動作します。

図1-4 このようなコンテキスト切り替えが起きた時には誤動作する


そこで、アプリケーションノートを作ったタイミングでRTOS対応版BSPモジュールとして、図2-1と図2-2の青背景色箇所の対処を行ったのではないかと思います。

図2-1 RTOS対応版BSPでのR_BSP_RegisterProtectDisable()の実装


図2-2 RTOS対応版BSPでのR_BSP_RegisterProtectEnable()の実装


ただ、そういう対処が行われたとは言え、そもそも図3-1のようにレジスタライトプロテクトが解除された状態でもコンテキスト切り替えが起きて他タスクへ遷移出来てしまい、レジスタライトプロテクトが解除された状態でどんどんコードが実行されていく可能性があるというのは、少し怖いと思うのですが、、、

図3-1 怖いと思うのは私だけだろうか?


[参考]

RX65Nグループ、RX651グループ ユーザーズマニュアル ハードウェア編からの抜粋
www.renesas.com/ja-jp/doc/products/mpumcu/doc/rx_family/r01uh0590jj0210-rx651.pdf



  • NoMaYさん

    こんにちは、シェルティです。

    本件、関係者にインプットしました。なんらか見解が得られたら書き込みます。
    貴重なご意見に感謝いたします。

    以上です
  • NoMaYさん

    こんにちは、シェルティです。

    本件課題2件あると認識しております。
    ①カウンタ操作に割り込み禁止がない(OS対応コードにはある)
    ②複数タスクにまたがるプロテクト解除が不安

    検討した結果、対策は以下になると思います。(もう少し詳細を内部で検討をします)
    ①通常のBSPにもOS対応コードと同様に割り込み禁止を入れる
    ②これは許容する(特にコード上は対策しない)

    以上です
  • シェルティさん、こんにちは。NoMaYです。

    >①カウンタ操作に割り込み禁止がない(OS対応コードにはある)
    R_BSP_RegisterProtectDisable()とR_BSP_RegisterProtectEnable()の仕様次第(これらの関数を割り込み処理中に呼び出してもよいことになっているか or 割り込み処理中に呼び出すことは不可となっているか)というところもありますが、もし割り込み処理でこれらの関数を呼び出していて、その割り込みが例えば図4-1のタイミングで起きた時には、通常版で誤動作してしまいますね。(調べてみると、これらの関数の仕様はReentrant:Noになっていますので、通常処理と割り込み処理の両方で呼び出すことはハイリスクなことだと認識出来るのですが、上位関数が内部処理としてこれらの関数を呼び出しているコードが多く、それらの上位関数レベルではどの上位関数とどの上位関数が互いにReentrant:Noの関係になっているのかリスクを認識することは困難(というかソースを調べない限り不可能)ではないかという気がしました。)

    図4-1 このような割り込みが起きた時には通常版で誤動してしまう(リスクを認識することは困難かと思う)


    ②複数タスクにまたがるプロテクト解除が不安
    上の①と関連するのですが、これらの関数を呼び出している上位関数は何と何なのかを調べて、その上位関数のレベル(つまり前後)でタスク切り替えだけを禁止/許可するAPI(普通の割り込みは許可したまま)がないかFreeRTOSのAPIを調べてみようかと思い始めました。(うまく情報に辿り着けたら投稿しようと思います。)