ModusToolbox 2.0 を使用した PSoC 6 MCU の基本的な DFU アプリケーションの設定方法 - Community Translated (JA)
- RSS フィードを購読する
- 新着としてマーク
- 既読としてマーク
- ブックマーク
- 購読
- 印刷用ページ
- 不適切なコンテンツを報告
Community Translated by MoTa_728816 Version: **
このドキュメントは読者が 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: プロジェクトの準備
- CY8CKIT-WIFI-BT 用のプロジェクトを “Hello_World” アプリケーションを使用して作成して、
“DFU_App0_I2C” という名前にしてください。これは DFU のローダーアプリケーションとして使用します。
2. 同様にして DFU ローダブルアプリケーションを作成して、“DFU_App1_Hello_World” という名前にしてください。
3. ModusToolbox Library Manager を使用して、それぞれのプロジェクトに DFU ミドルウェアを追加してください。
ライブラリを追加するのには、ターゲットプロジェクトを右クリックして、ModusToolbox > Library Manager を選択します。
また、手動で GitHub からダウンロードして、プロジェクトにコピーすることも可能です。
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.
ステップ 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
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
正常にプログラムが終了すると “DFU_App1_Hello_World” アプリケーションが起動します。Hello_World アプリケーションのデフォルト設定では赤い LED が点滅します。基板上の SW2 を押して App0 と App1 を切り替えてください