メインコンテンツ

生成されたコードでのランタイム エラーとコーディング ルール違反として検出されたモデル設計の問題の修正

Simulink® モデルの標準への準拠と設計エラーをテストしたら、モデルからコードを生成できます。展開の前に、Polyspace® を使用して、生成されたコードに対してエラー チェックの最後の層を実行できます。このチェックでは、モデルをテストしたにもかかわらず残っている可能性のある、デッド ロジックや不適切なコード生成オプションなどの問題を検出します。

前提条件

Simulink から Polyspace を実行する前に、Polyspace インストールと MATLAB® インストールをリンクしなければなりません。MATLAB や Simulink との Polyspace の統合を参照してください。

この例で使用されるモデルを開くには、MATLAB コマンド ウィンドウで以下を実行します。

openExample('polyspace_code_prover/FixIssuesInGeneratedCodeFoundWithPolyspaceCodeProverExample')

モデルを開く

モデル CruiseControl_RP には、設計の問題のある Stateflow チャートが含まれています。この問題は、生成されたコード内の潜在的なランタイム エラーや到達不能分岐にあたります。

ランタイム エラーの検出と修正

ランタイム エラーの検出

[Polyspace] タブで、キャンバスの任意の場所をクリックします。[次のコードの解析] フィールドにモデル名が表示されます。Embedded Coder® を使用している場合は、[解析の実行] をクリックします。他のコード生成ツールを使用している場合は、Polyspace 解析を開始する前にコードを手動で生成します。

詳細については、Embedded Coder によって生成されたコードに対する Polyspace 解析の実行を参照してください。

解析が完了すると、Code Prover の結果が Polyspace ユーザー インターフェイスで開きます。結果にはグレー チェック (到達不能コード) とオレンジ チェック (潜在的なランタイム エラー) が含まれています。

グレー チェックの修正

2 つの [到達不能コード] チェックのうちの 1 つを選択します。到達不能なコードをレビューします。

            if ((CoastSetSw_prev != CruiseControl_RP_DW.CoastSetSw_start) &&
                CruiseControl_RP_DW.CoastSetSw_start &&
                (CruiseControl_RP_Y.tspeed > (real_T)mintspeed)) {
              /* Transition: '<S1>:74' */
              CruiseControl_RP_DW.is_ON = CruiseControl_RP_IN_Coast;
              CruiseControl_RP_DW.temporalCounter_i1 = 0U;

              /* Entry 'Coast': '<S1>:73' */
              CruiseControl_RP_Y.tspeed -= (real_T)incdec;
            }

if ブロックの Transition:'<S1>:74' リンクをクリックします。モデル内で遷移が強調表示されます。

Stateflow transition related to the unreachable code is highlighted in the Stateflow chart.

設計の欠陥に注目します。外向きの遷移 3 の条件は、外向きの遷移 2 の条件も真でない限り、真になりません。したがって、後で実行される遷移 3 には決して到達しません。このチャートの設計の欠陥は、生成されたコード内の到達不能な if ブロックにあたります。

この問題の解決方法の 1 つは、遷移 2 と 3 の実行順序を入れ替えることです。開始するには、遷移 3 を右クリックします。

実行順序を入れ替えてから、コードを再生成して再解析します。グレーの [到達不能コード] チェックは表示されなくなります。

オレンジ チェックの修正

2 つの [ゼロ除算] チェックのうちの 1 つを選択します。コードをレビューします。

if (CruiseControl_RP_DW.temporalCounter_i1 >= (uint32_T)(incdec /
               holdrate * 10.0F))
変数 holdrate の上にカーソルを置きます。0 の値を取ることのできるグローバル変数であることがわかります。

holdrate がグローバル変数であるという事実は、この変数がモデル外部で定義できることを示唆しています。モデル エクスプローラー ウィンドウを開きます。モデルの階層構造で、ベース ワークスペースを選択します。パラメーターのリストで holdrate を探します。holdrate の値は 5 ですが、0 ~ 10 の範囲の値を取れることがわかります。Code Prover 解析では、この範囲を使用して、ゼロ除算を検出します。

次のように生成されたコードまたは解析構成を変更できます。

  • コードの変更:

    モデル エクスプローラー ウィンドウで、holdrate のストレージ クラスを [グローバル] から [定義] に変更します。生成されたコードでは、holdrate の値が 5 になるようにプリプロセッサ命令が定義されます。

    #define holdrate 5

  • 解析構成の変更:

    [Polyspace] タブで [設定] を選択します。キャリブレーション データを使用するようにオプション [調整可能なパラメーター] を変更します。Code Prover 解析では、holdrate に対して 0 ~ 10 の範囲内の別の値の代わりに値 5 を使用します。

コードを再生成して再解析すると、オレンジの [ゼロ除算] チェック、および同じ根本原因による他のオレンジ チェックは表示されなくなります。[ダッシュボード] ペインにチェックがグリーンであることが示されます。

Check distribution pie chart on the Dashboard pane showing that all checks are green.

コーディング ルール違反の検出と修正

MISRA C:2012 違反の検出

MISRA C™ 違反を検出するには、以下を行います。

  1. [Polyspace] タブの [モード] セクションで [Bug Finder] を選択します。

  2. [設定] を選択し、Simulink の [コンフィギュレーション パラメーター] ウィンドウを開きます。[検証設定] メニューで、[プロジェクト構成および MISRA C 2012 のチェック] を選択します。

  3. [解析の実行] をクリックして解析を開始します。

MISRA C:2012 違反の修正

Bug Finder 解析の実行後、Polyspace により、生成されたコードの MISRA C:2012 の違反がレポートされます。これらの一部の違反の修正には、モデルの変更が必要になる場合があります。ルール 3.1 の違反について考えます。

The character sequences /* and // shall not be used within a comment.
2 つの違反は、このコードの RES および SET の宣言の場所にあります。
typedef struct {
  uint8_T CC_Mode;                     /* '<Root>/CC_Mode' */
  boolean_T RES;                       /* '<Root>/RES//+' */  
  boolean_T SET;                       /* '<Root>/SET//-' */
  real_T SpeedSet;                     /* '<Root>/Speed_Set' */
  real_T SpeedAct;                     /* '<Root>/Speed_Act' */
  boolean_T Break;                     /* '<Root>/Break' */
} ExtU_CruiseControl_RP_T;
これらのステートメントには、構造体定義のコード コメントに 2 つの // のインスタンスがあります。

モデル内の対応する場所に移動するには、コード コメント内の '<Root>/RES//+' をクリックします。このコメントが、/ 文字を含む入力変数 RES/+ に由来することがわかります。

Input block related to MISRA C:2012 violations is highlighted in the model.

変数名に / 文字を使用しないように、変数 RES/+SET/- の名前を変更します。コードを再解析すると、ルール 3.1 の違反が表示されなくなります。

参考

トピック