2 Replies Latest reply on Apr 20, 2020 6:35 PM by JuyoungJ_06

    Community Translation - Set Up a Basic DFU Application in ModusToolbox 2.0 for PSoC 6 MCU Device – KBA229130

    MoTa_728816

      Hi,

       

      I'd like to try translating this KBA229130 into Japanese.

       

      moto

       

      Original KBA: KBA229130

      Set Up a Basic DFU Application in ModusToolbox 2.0 for PSoC 6 MCU Device – KBA229130

       

      Translated by: MoTa_728816

      ===============================

      タイトル:ModusToolbox 2.0 を使用した PSoC 6 MCU の基本的な DFU アプリケーションの設定方法

       

      このドキュメントは読者が ModusToolbox™ の使用方法と デバイスファームウェアアップデート (DFU) についての知識があることを前提としています。以降は ModusToolbox 2.0 を使用して PSoC® 6 MCU の基本的な DFU ローダーとローダブルアプリケーションを設定してビルドする手順です。使用する基板は CY8CKIT-062-WIFI-BT DVK で通信プロトコルには I2C を使用します。詳細についてはキットのユーザーガイドをご参照ください。デバイスファームウェアアップデートのプロセスに関する詳細についてはAN213924 - PSoC 6 MCU Device Firmware Update Software Development Kit Guide をご参照ください。

      注意:使用する基板のデバッガが KitProg3 になっていることをご確認ください。もしお使いの基板のデバッガが KitProg2 の場合、KitProg2 を KitProg3 にアップデートする方法については KitProg3 User Guide の Chapter 6 をご参照ください。

       

      ステップ 1: プロジェクトの準備

       

       1. CY8CKIT-WIFI-BT 用のプロジェクトを “Hello_World” アプリケーションを使用して作成して、

        “DFU_App0_I2C” という名前にしてください。これは DFU のローダーアプリケーションとして使用します。

       2. 同様にして DFU ローダブルアプリケーションを作成して、“DFU_App1_Hello_World” という名前にしてください。

       3. ModusToolbox Library Manager を使用して、それぞれのプロジェクトに DFU ミドルウェアを追加してください。

        ライブラリを追加するのには、ターゲットプロジェクトを右クリックして、ModusToolbox > Library Manager を選択します。

        また、手動で GitHub からダウンロードして、プロジェクトにコピーすることも可能です。

      001-pastedImage_7.png

       4. DFU ライブラリの API を使用する為に、main.c に DFU ヘッダーをインクルードします。

           include "cycfg.h"
           include "cy_dfu.h"

       

      ステップ 2: ローダーアプリケーションの設定 (DFU_App0_I2C)

       

       1. コンフィグレーションファイル dfu_user.c と dfu_user.h を libs\dfu\config ディレクトリから、

         コピーしてプロジェクトディレクトリに置きます。

       2. トランスポートファイルを \config ディレクトリから、コピーしてプロジェクトディレクトリに置きます。

         今回の場合、I2C には transport_i2c.h と transport_i2c.c が必要です。

       3. app0 のリンカスクリプトファイルを libs\dfu\linker_scripts\TOOLCHAIN_<COMPILER>\ からプロジェクトのルートにコピーしてください。

         GCC ARM コンパイラ用には、libs\dfu\linker_scripts\TOOLCHAIN_GCC_ARM\dfu_cm4_app0.ldコピーしてください。

       4. ModusToolbox Device Configurator を使用して、シリアルコミュニケーションブロック (SCB) を I2C コミュニケーション用に

         設定してください。CY8CKIT-062-WIFI-BT では、KitProg3 インターフェースに接続されている SCB3 を使用してください。

         SCB3 の設定方法は図 1をご参照ください。

       

      図 1.

      002-pastedImage_10.png

       

      ステップ 3: ローダー DFU_App0_I2C の main.c をアップデートする

       1. main.c のオリジナルコードを消して、main() 内の空ループだけを残します。

       2. リセット後に適切なアプリケーションを起動するために、main.c に DFU リセットハンドラを追加します。

      /*******************************************************************************

      * Function Name: Cy_OnResetUser

      ********************************************************************************

      *

      *  This function is called at the start of Reset_Handler().

      *  DFU requires it to call Cy_DFU_OnResetApp0() in app#0.

      *

      *******************************************************************************/

      void Cy_OnResetUser(void)

      {

          Cy_DFU_OnResetApp0();

      }

       3. 変数を初期化して、DFU の初期化関数を main() から呼ぶように、下記のコードを main.c に追加します。

      /*

      * Used to count seconds

      */

      uint32_t count = 0;

      /* Status codes for DFU API */

      cy_en_dfu_status_t status;

      /*

      * DFU state, one of the:

      * - CY_DFU_STATE_NONE

      * - CY_DFU_STATE_UPDATING

      * - CY_DFU_STATE_FINISHED

      * - CY_DFU_STATE_FAILED

      */

      uint32_t state;

      /* Timeout for Cy_DFU_Continue(), in milliseconds */

      const uint32_t paramsTimeout = 20u;

       

      /* Buffer to store DFU commands */

      CY_ALIGN(4) static uint8_t buffer[CY_DFU_SIZEOF_DATA_BUFFER];

      /* Buffer for DFU data packets for transport API */

      CY_ALIGN(4) static uint8_t packet[CY_DFU_SIZEOF_CMD_BUFFER ];

      /* DFU params, used to configure DFU */

      cy_stc_dfu_params_t dfuParams;

      /* Initialize dfuParams structure */

             dfuParams.timeout          = paramsTimeout;

             dfuParams.dataBuffer       = &buffer[0];

             dfuParams.packetBuffer     = &packet[0];

      status = Cy_DFU_Init(&state, &dfuParams);

      /* Set up the device based on configurator selections */

      init_cycfg_all();

      /* enable interrupts */

      __enable_irq();

       

      /* Initialize DFU communication */

       

      Cy_DFU_TransportStart();

       

       4. main() 内で DFU トランスポートレイヤーを初期化するように下記のコードを main.c に追加します。

      /* Initialize DFU communication */

      Cy_DFU_TransportStart();

       

       5. メインループを Host Common/Response プロトコル処理でアップデートするように下記のコードを main.c に追加します。

      status = Cy_DFU_Continue(&state, &dfuParams);

      ++count;

      if (state == CY_DFU_STATE_FINISHED)

      {

      /* Finished loading the application image */

      /* Validate DFU application, if it is valid then switch to it */

      status = Cy_DFU_ValidateApp(1u, &dfuParams);

      if (status == CY_DFU_SUCCESS)

      {

      Cy_DFU_TransportStop();

      Cy_DFU_ExecuteApp(1u);

      }

      else if (status == CY_DFU_ERROR_VERIFY)

      {

      /*

      * Restarts loading, an alternatives are to Halt MCU here

      * or switch to the other app if it is valid.

      * Error code may be handled here, i.e. print to debug UART.

      */

      status = Cy_DFU_Init(&state, &dfuParams);

      Cy_DFU_TransportReset();

      }

      }

      else if (state == CY_DFU_STATE_FAILED)

      {

      /* An error has happened during the loading process */

      /* Handle it here */

      /* In this Code Example just restart loading process */

      status = Cy_DFU_Init(&state, &dfuParams);

      Cy_DFU_TransportReset();

      }

      else if (state == CY_DFU_STATE_UPDATING)

      {

      uint32_t passed5seconds = (count >= (5000ul/paramsTimeout)) ? 1u : 0u;

      /*

      * if no command has been received during 5 seconds when the loading

      * has started then restart loading.

      */

      if (status == CY_DFU_SUCCESS)

      {

      count = 0u;

      }

      else if (status == CY_DFU_ERROR_TIMEOUT)

      {

      if (passed5seconds != 0u)

      {

      count = 0u;

      Cy_DFU_Init(&state, &dfuParams);

      Cy_DFU_TransportReset();

      }

      }

      else

      {

      count = 0u;

      /* Delay because Transport still may be sending error response to a host */

      Cy_SysLib_Delay(paramsTimeout);

      Cy_DFU_Init(&state, &dfuParams);

      Cy_DFU_TransportReset();

      }

       

      }

       6. メインループを DFU_App1_Hello_World アプリケーションにスイッチするルーチンで変更します。

         例えば CY8CKIT-062-WIFI-BT の SW2 ボタンを押すとアプリケーションを切り替えます。

         このピンは基板上の SW2 に接続されています。

       

         a. Device Configurator で Pin P0[4] を有効にして、名前を “PIN_SW2” にします。

       

         b. 図2のようにピンの設定を行います:

       

      図2

      003-pastedImage_17.png

         c. メインループに以下のルーチンを追加します:

       

      /* If Button clicked - Switch to App1 if it is valid */

      if (Cy_GPIO_Read(PIN_SW2_PORT, PIN_SW2_PIN) == 0u)

      {

      /* 50 ms delay for button debounce on button press */

      Cy_SysLib_Delay(50u);

      if (Cy_GPIO_Read(PIN_SW2_PORT, PIN_SW2_PIN) == 0u)

      {

      while (Cy_GPIO_Read(PIN_SW2_PORT, PIN_SW2_PIN) == 0u)

      {   /* 50 ms delay for button debounce on button release */

      Cy_SysLib_Delay(50u);

      }

      /* Validate and switch to App1 */

      status = Cy_DFU_ValidateApp(1u, &dfuParams);

      if (status == CY_DFU_SUCCESS)

      {

      Cy_DFU_TransportStop();

      Cy_DFU_ExecuteApp(1u);

      }

      }

       

      }

      ステップ 4: ローダー DFU_App0_I2C をビルドしてプログラムします。

       

       1. プロジェクトの makefile を dfu_cm4_app0 の適切なツールチェーンで DFU リンカスクリプトを使用するように変更します。

        LINKER_SCRIPT をプロジェクトのルートにコピーされたリンカースクリプトを指すようにします。

       

      LINKER_SCRIPT=dfu_cm4_app0.ld

       

       2. ELF ファイルにサインを行う post-build ステップを追加するか、ビルド後に手作業でサインを行ってください。

       

           <MCUELFTOOL> –sign <app>.elf –output <app_signed>.elf –hex <app_signed>.hex.

       

        macOS/Linux プラットフォーム:

       

           POSTBUILD=$(CY_MCUELFTOOL_DIR)/bin/cymcuelftool --sign $(CY_CONFIG_DIR)/$(APPNAME).elf --hex      $(CY_CONFIG_DIR)/$(APPNAME).hex

       

        Windows プラットフォーム:

       

                POSTBUILD="$(CY_MCUELFTOOL_DIR)/bin/cymcuelftool.exe" --sign $(CY_CONFIG_DIR)/$(APPNAME).elf --hex      $(CY_CONFIG_DIR)/$(APPNAME).hex

       

       3. ビルドしてデバイスにプログラムします。

       

      ステップ 5: ローダブル DFU_App1_Hello_World の設定

       

       1. コンフィグレーションファイル dfu_user.h を libs\dfu\config ディレクトリからコピーしてプロジェクトルートの main.c の付近に置きます。

       

        注意:メタデータストラクチャーの重複を避けるために dfu_user.c はコピーしないでください

       

       2. app1 のリンカスクリプトを \libs\dfu\linker_scripts\TOOLCHAIN_<COMPILER>\ からプロジェクトのルートのコピーします。

        GCC ARM コンパイラの場合、\libs\df\linker_scripts\TOOLCHAIN_GCC_ARM\dfu_cm4_app1.ld をコピーします。

       

      ステップ 6: ローダブル DFU_App1_Hello_World の main.c を変更する。

       

       1. main.c に .cy_app_signature セクションを追加します。その他の既存のコードは変更しません。

       

           CY_SECTION(".cy_app_signature") __USED static const uint32_t cy_dfu_appSignature[1];

       

       2. main 関数の中でペリフェラルの初期化を行います。

       

           init_cycfg_all();

       

       3. メインループにローダーアプリケーション DFU_App0_I2C に他のアプリケーションをロードするように変更します。

        例えば、CY8CKIT-062-WIFI-BT 上の SW2 ボタンを押すとアプリケーションを切り替えます。

       

        a. Device Configurator でピン P0[4] を有効にして、名前を "PIN_SW2" に変更します。

       

        b. ピンのコンフィグレーションを App0 の P0[4] と同様に設定します。

       

        c. メインループに以下のルーチンを追加します。

       

      /* If Button clicked and switch to App0 */

      if (Cy_GPIO_Read(PIN_SW2_PORT, PIN_SW2_PIN) == 0u)

      {

      /* 50 ms delay for button debounce on button press */

      Cy_SysLib_Delay(50u);

      if (Cy_GPIO_Read(PIN_SW2_PORT, PIN_SW2_PIN) == 0u)

      {

      while (Cy_GPIO_Read(PIN_SW2_PORT, PIN_SW2_PIN) == 0u)

      {   /* 50 ms delay for button debounce on button release */

      Cy_SysLib_Delay(50u);

      }

      Cy_DFU_ExecuteApp(0u);

      }

       

      }

       

      ステップ 7:  ビルドとパッチのプログラム

       

       1. プロジェクトの makefile を dfu_cm4_app1 の適切なツールチェーンで DFU リンカスクリプトを使用するように変更します。

        LINKER_SCRIPT をコピーされたリンカースクリプトを指すようにします。

       

         LINKER_SCRIPT=dfu_cm4_app1.ld

       

       2.  パッチファイルを *.cyacd2 フォーマットで生成するように CyMCUElfTool を実行するpost-build ステップを追加します。

        ( CyMCUElfTool User Guide 参照).

       

         macOS/Linux プラットフォーム:

       

           POSTBUILD=$(CY_MCUELFTOOL_DIR)/bin/cymcuelftool --sign $(CY_CONFIG_DIR)/$(APPNAME).elf CRC --output      $(APPNAME)_crc.elf && \ $(CY_MCUELFTOOL_DIR)/bin/cymcuelftool -P $(APPNAME)_crc.elf --output      $(APPNAME)_crc.cyacd2

       

         Windows プラットフォーム:

       

         POSTBUILD="$(CY_MCUELFTOOL_DIR)/bin/cymcuelftool.exe" --sign $(CY_CONFIG_DIR)/$(APPNAME).elf CRC --output $(APPNAME)_crc.elf && \ "$(CY_MCUELFTOOL_DIR)/bin/cymcuelftool.exe" -P $(APPNAME)_crc.elf --output $(APPNAME)_crc.cyacd2

       

       

       3. プロジェクトをビルドします。

       

       4. Device Firmware Update Tool を起動します。(ModusToolbox 内のターゲットプロジェクトを右クリックして、 ModusToolbox > Device Firmware Update Tool を選択)。 デバイスに接続。プロジェクトルートにある生成された .cyacd2 ファイルを選択して、デバイスのプログラムします。

       

        このツールの詳細な使用方法については Help > View Help をクリックして ModusToolbox Device Firmware Update Host Tool ドキュメントを開いてください。

       

      図3

      004-pastedImage_45.png

       

       

      正常にプログラムが終了すると “DFU_App1_Hello_World” アプリケーションが起動します。Hello_World アプリケーションのデフォルト設定では赤い LED が点滅します。基板上の SW2 を押して App0 と App1 を切り替えてください。

      ===============================

      30-Mar-2020

      moto