🔧

PIC32MZW1(WFI32-IoT Board)+FreeRTOSのデバイス組込み開発環境構築

2023/07/12に公開

1. はじめに

システムゼウスでIoT開発をしている南坂です。

Microchip社製のWFI32-IoT Board(PIC32MZW1)を用いたFreeRTOSのデバイスの組込みアプリを開発するための環境の構築方法について説明します。

2. 概要

2.1. 物理構成

PCとWFI32-IoT BoardをUSBで接続します。


実際のHW

No. デバイス名 メーカー 型番・品名など 説明
1 WFI32-IoT Board Microchip WFI32-IoT Development Board Microchip製のIoT開発用ボード。MCUはWFI32E01PC(PIC32MZW1)。Wi-Fiモジュールとセキュアエレメント搭載型。

2.2. ソフトウェア一覧

動作確認済みのPC環境はWindows 11 22H2です。

No. ソフトウェア名 バージョン 説明
1 Git >2.39.1.windows.1 ソースコードの管理
2 Python3 >3.10.5 ビルド時に使用(署名の作成など)
3 SRecord >1.64.D001 ビルド時に使用(バイナリの結合など)
4 MPLAB® X IDE v6.00 統合開発環境
5 MPLAB® Harmony 3 Launcher 3.6.4 開発フレームワーク
6 MPLAB® XC32/32++ Complier 2.40 コンパイラ
7 TeraTerm 4.106 UARTターミナルエミュレーター

※バージョンは動作確認がとれているものです

3. セットアップ手順

3.1. ソフトウェアセットアップ

1. Gitのインストール

git for windowsから最新バージョンのgitをインストールします。
インストール完了後、以下のコマンドが実行できるか確認してください。

$ git --version
git version 2.40.1.windows.1

2. Python3のインストール

Pythonから最新バージョンのPythonをインストールします。
インストール時には以下の画像のように「Add python.exe to PATH」にチェックを入れてください。 入れないとインストール先のパスを手動で環境変数に追加する手間が増えます。

pythonインストーラー
pythonインストーラー

インストール完了後、以下のコマンドが実行できるか確認してください。

$ python --version
Python 3.11.3

3. SRecordのインストール

SRecordから最新のSRecordをインストールします。SRecordはインストールを忘れがちで、インストールしなかった場合はビルドに失敗します。
インストール完了後、環境変数のPATHにSRecordを追加します。

環境変数
環境変数

※設定するPATHはSRecordのインストール先のbinフォルダです

インストール完了後、以下のコマンドが実行できるか確認してください。

$ srec_cat --version
srec_cat version 1.65.0 [git hash 5844fa801c]
...

4. MPLAB X IDEのインストール

Microchipからv6.00MPLAB X IDEをインストールします。
これより新しいバージョンは動作確認できていません。

5. Harmony関連のインストール

  1. Harmonyのインストール
    MPLAB X IDEを起動し、Tools > Plugins Downloadを選択します。
    Harmonyを検索し、チェックボックスにチェックを入れてInstallをクリックします。

    Harmony Plugin
    Harmony Plugin

  2. パッケージのインストール
    Tools > Embedded > MPLAB® Harmony 3 Content Managerを開きます。
    ContentManagerから以下のものをダウンロード、バージョンを合わせてください。

    • cryptoauthlib: v3.3.2
    • csp: v3.10.0
    • core: v3.10.0
    • wireless_wifi: v3.6.1
    • dev_packs: v3.10.0
    • wolfssl: v4.7.0
    • bsp: v3.10.0
    • crypto: v3.7.1

    Harmony Content Manager
    Harmony Content Manager

  3. amazon-freertos, aws_cloudパッケージの手動インストール

    1. Harmony3のディレクトリ(通常は C:\User\{ユーザー名}\Harmony3)に移動します
    2. ここでコマンドプロンプトなどから以下のコマンドを実行し、amazon-freertosを取得します
      $ git clone https://github.com/MicrochipTech/amazon-freertos.git
      $ cd amazon-freertos
      amazon-freertos$ git checkout mchpdev_20210700
      amazon-freertos$ git submodule update --init --recursive
      
    3. ここからaws_cloud.zipを取得し、Harmony3/下に展開します

    以上で次のような構成になっているはずです。

    C:\
    └ Users/
       └ user_name/
          └ Harmony3/
             ├ amazon-freertos/
             ├ aws_cloud/
             ├ bsp/
             └...
    

6. XC32/32++のインストール

Microchipからv2.40のXC32/32++ Compilerをインストール。
インストール時には以下の画像のように「Add xc32 to the PATH environment variable」にチェックを入れてください。入れないとインストール先のパスを手動で環境変数に追加する手間が増えます。

xc32インストーラー
xc32インストーラー

7. TeraTermのインストール

TeraTermから最新のTeraTermをインストールします。
シリアルポートの設定は以下のように設定します。

  • ボーレート: 115200
  • データ: 8bit
  • パリティ: none
  • ストップビット: 1bit
  • フロー制御: none

8. リポジトリのクローン

  1. amazon-freertosのリポジトリをクローン

    $ git clone https://github.com/MicrochipTech/amazon-freertos.git
    
  2. amazon-freertosのリポジトリでmchpdev_20210700のブランチに移動

    $ cd amazon-freertos
    amazon-freertos$ git checkout mchpdev_20210700
    
  3. submoduleのアップデート

    amazon-freertos$ git submodule update --init --recursive
    

    実行するとfreertos_kernelやライブラリのファイルがダウンロードされます。

9. FreeRTOS関連コードの修正

今回の組込みアプリの内容に合わせてFreeRTOSのソースコードを一部修正する必要があります。
以下の内容に従ってソースコードを修正します。
※見た目をすっきりさせるため、正確なdiff表現ではありません。

  1. uxTaskGetStackHighWaterMark関数の有効化

    メモリの使用量を確認したい場合は有効にします。

    amazon-freertos/vendors/microchip/boards/curiosity_pic32mzw1/aws_demos/config_files/FreeRTOSConfig.h
    #define INCLUDE_xTaskGetCurrentTaskHandle       1 
    -#define INCLUDE_uxTaskGetStackHighWaterMark     0 
    +#define INCLUDE_uxTaskGetStackHighWaterMark     1 
    #define INCLUDE_xTaskGetIdleTaskHandle          0 
    
  2. Wi-Fiへの接続指示に使用する構造体のサイズ変更

    アプリケーションを開発するとデフォルトのサイズのままだとメモリが枯渇し、ハードフォルトしてしまうためサイズを変更します。

    amazon-freertos/vendors/microchip/boards/curiosity_pic32mzw1/aws_demos/config_files/aws_wifi_config.h
    #define _AWS_WIFI_CONFIG_H_
    
    -#define wificonfigMAX_WEPKEYS               (64)
    +#define wificonfigMAX_WEPKEYS               (1)
    #define wificonfigMAX_WEPKEY_LEN             (128)
    
  3. FreeRTOSのヒープサイズ削減とタスク作成時の最小スタックサイズを変更

    アプリケーションを開発するとメモリのグローバル変数領域が不足気味になるためヒープサイズを減少させグローバル変数領域を確保します。
    また最小スタックサイズが大きいと無駄になるメモリが多くなるため最小スタックサイズを削減します。

    amazon-freertos/vendors/microchip/boards/curiosity_pic32mzw1/aws_demos/config_files/FreeRTOSConfig.h
    #define configMAX_PRIORITIES                       (10UL)
    -#define configMINIMAL_STACK_SIZE                   (1024)   /* 512 for OTA demo */
    +#define configMINIMAL_STACK_SIZE                   (512)
    #define configISR_STACK_SIZE                       (512)
    #define configSUPPORT_DYNAMIC_ALLOCATION           1
    #define configSUPPORT_STATIC_ALLOCATION            1
    -#define configTOTAL_HEAP_SIZE                      ( ( size_t ) 180000)
    +#define configTOTAL_HEAP_SIZE                      ( ( size_t ) 160000)
    #define configMAX_TASK_NAME_LEN                    (16 )
    
  4. DHCPのDiscover時にホスト名を付与しないようにコンフィグファイルを修正

    デフォルトではDHCPのホスト名が、aws_clientcredential.h で定義されたAWSIoTのThingNameになるように設定されています。実際のアプリケーションではThingNameはセキュアエレメントなどから個体ごとにユニークに取得したくなるため、 aws_clientcredential.h のThingNameは削除することが多いと思います。このままではThingNameを削除すると副作用でDHCPのホスト名もなくなり、Wi-FiルーターによってはDHCP処理に失敗し、インターネット接続できなくなります。この事象を回避するためにホスト名を付与しない設定にします。

    amazon-freertos/vendors/microchip/boards/curiosity_pic32mzw1/aws_demos/config_files/FreeRTOSIPConfig.h
    #define ipconfigUSE_DHCP                               1
    -#define ipconfigDHCP_REGISTER_HOSTNAME                 1
    +#define ipconfigDHCP_REGISTER_HOSTNAME                 0
    #define ipconfigDHCP_USES_UNICAST                      1 
    
  5. ネットワークインターフェース初期関数の処理順番入れ替え

    デフォルトでは①Wi-Fiドライバの初期化→②Wi-Fiルーターへの接続→③FreeRTOS IPライブラリへMACアドレス登録の順に処理されるが、①→③→②の順番に変更します。
    アプリケーションでWi-Fiルーターの接続に失敗したときに再接続するロジックを補強しようとすると、Wi-Fiルーター接続後にMACアドレスを登録する処理ではリトライ時にもMACアドレスを登録しなくてはいけなくなり、処理が煩雑になるため、処理の順番を入れ替えます。

    amazon-freertos/libraries/freertos_plus/standard/freertos_plus_tcp/portable/NetworkInterface/pic32mzw1_h3/NetworkInterface_wifi.c
    /* Connect to the AP */
    if( WIFI_ConnectAP( &xNetworkParams ) != eWiFiSuccess )
    {
        return pdFAIL;
    }
    -xResult = pdPASS;
    -
    -if ( eWiFiSuccess == WIFI_GetMAC( mac_addr ))
    -{
    -    printf("MAC Addr = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5] );
    -    FreeRTOS_UpdateMACAddress(mac_addr);
    -}
    -else
    -{
    -    printf("Fail to get mac address from wifi module...\r\n");
    -    xResult = pdFAIL;
    -}
    -
    -
    -PIC32_MAC_DbgPrint( "xNetworkInterfaceInitialise: %d %d\r\n", ( int ) xMacInitStatus, ( int ) xResult );
    +if (eWiFiSuccess == WIFI_GetMAC(mac_addr))
    +{
    +    printf("MAC Addr = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
    +    FreeRTOS_UpdateMACAddress(mac_addr);
    +}
    +else
    +{
    +    printf("Fail to get mac address from wifi module...\r\n");
    +    xResult = pdFAIL;
    +}
    +
    +PIC32_MAC_DbgPrint("xNetworkInterfaceInitialise: %d %d\r\n", (int)xMacInitStatus, (int)xResult);
    +
    +/* Connect to the AP */
    +WIFIReturnCode_t xResult2 = WIFI_ConnectAP(&xNetworkParams);
    +if (xResult2 != eWiFiSuccess)
    +{
    +    configPRINTF(("WIFI_ConnectAP fail. Reason %d\r\n", xResult2));
    +    return pdFAIL;
    +}
    +xResult = pdPASS;
    return xResult;
    
  6. Wi-FiのWPA3対応

    WPA3を使う場合、ロジックを追加します。

    amazon-freertos/vendors/microchip/boards/curiosity_pic32mzw1/ports/wifi/iot_wifi.c
    case eWiFiSecurityWPA:
    {
        if (WDRV_PIC32MZW_STATUS_OK != WDRV_PIC32MZW_AuthCtxSetPersonal(&g_wifiConfig.authCtx, pxNetworkParams->xPassword.xWPA.cPassphrase, pxNetworkParams->xPassword.xWPA.ucLength, WDRV_PIC32MZW_AUTH_TYPE_WPAWPA2_PERSONAL))
        {
            WDRV_DBG_ERROR_MESSAGE(("APP: Unable to set authentication to WPAWPA2 MIXED\r\n"));
            return eWiFiFailure;
        }
        break;
    }
    
    +case eWiFiSecurityWPA3:
    +{
    +    if (WDRV_PIC32MZW_STATUS_OK != WDRV_PIC32MZW_AuthCtxSetPersonal(&g_wifiConfig.authCtx, pxNetworkParams->xPassword.xWPA.cPassphrase, pxNetworkParams->xPassword.xWPA.ucLength, WDRV_PIC32MZW_AUTH_TYPE_WPA2WPA3_PERSONAL))
    +    {
    +        WDRV_DBG_ERROR_MESSAGE(("APP: Unable to set authentication to WPA2WPA3 MIXED\r\n"));
    +        return eWiFiFailure;
    +    }
    +    break;
    +}
    
    case eWiFiSecurityWEP:
    

4. 動作確認

ここではソフトウェアが正しくインストールされているか確認するため、ビルド、デバイスへの書き込み、ログの確認を行います。

  1. PCとWFI32-IoT BoardをUSBケーブルで接続します

  2. TeraTermを起動し、シリアルポートを選択します
    COMポートが2つ認識されるのでシリアルデバイス(COMXX)の方を選択してください。
    ※COM番号はCOMポートの使用状況によって異なります
    TeraTerm
    TeraTerm

  3. MPLAB X IDEでFile > Open Project...から projects\microchip\wfi32_iot_pic32mzw1_ecc\mplab\aws_demos\firnware\aws_demos.X を開きます

  4. Clean And Build Main Projectを押しクリーンビルドします

  5. Make And Program Device Main Projectを押しデバイスに書き込みます
    書き込み
    MPLAB X IDE

  6. TeraTermに以下のようなログが表示されれば成功です

    Bootloader start...
    
    Factory reset...
    Bootloader start...
    
    APP verify success...
    =======Boot Descriptor=======
    header signature :0x40 0x41 0x46 0x52
    ucImgFlags       :0xfc
    ulSequenceNum    :0x0
    slot             :0x0
    image size       :901154
    signature        :30 44 2 20 42
    ...
    

5. アプリケーション開発時の修正事項

FreeRTOSではデフォルトでSSID/パスワードがソースに書き込まれており、TCP/IPの初期化とWi-Fiの接続が同時に行われます。スマホアプリから動的にSSID/パスワードを設定する場合は修正する必要があります。スマートロックデモシステムを例に修正内容を説明します。

  1. Wi-FiのSSID/パスワード設定の変更

    デフォルトだとソースコードにSSID/パスワードを埋め込まないと接続できませんが、本デモシステムはスマホからSSIDなどを指定するため、動的に変更できるようにしています。

    amazon-freertos/libraries/freertos_plus/standard/freertos_plus_tcp/portable/NetworkInterface/pic32mzw1_h3/NetworkInterface_wifi.c
    #include "system_config.h"
    
    +#include "tasks/flash/include/flash_task.h"
    +#include "tasks/flash/include/flash_data.h"
    
    #ifdef PIC32_USE_RIO2_WIFI
    
    amazon-freertos/libraries/freertos_plus/standard/freertos_plus_tcp/portable/NetworkInterface/pic32mzw1_h3/NetworkInterface_wifi.c
    WIFINetworkParams_t xNetworkParams;
    
    -memcpy(xNetworkParams.ucSSID, clientcredentialWIFI_SSID, strlen( clientcredentialWIFI_SSID )) ;
    -xNetworkParams.ucSSIDLength = strlen( clientcredentialWIFI_SSID );
    -memcpy(xNetworkParams.xPassword.xWPA.cPassphrase, clientcredentialWIFI_PASSWORD, strlen( clientcredentialWIFI_PASSWORD )) ;
    -xNetworkParams.xPassword.xWPA.ucLength = strlen( clientcredentialWIFI_PASSWORD );
    -xNetworkParams.xSecurity = clientcredentialWIFI_SECURITY;
    -xNetworkParams.ucChannel = 0; /* Scan all channels (255) */
    
    +WiFiInfo_t xWiFiInfo;
    +
    +memset(&xWiFiInfo, 0x00, sizeof(xWiFiInfo));
    +
    +if (eReadFlashInfo(READ_FLASH_TYPE_WIFI_INFO, &xWiFiInfo, sizeof(xWiFiInfo)) != FLASH_TASK_RESULT_SUCCESS)
    +{
    +    return pdFAIL;
    +}
    +
    +memcpy(xNetworkParams.ucSSID, xWiFiInfo.cWifiSSID, strlen(xWiFiInfo.cWifiSSID));
    +xNetworkParams.ucSSIDLength = strlen(xWiFiInfo.cWifiSSID);
    +memcpy(xNetworkParams.xPassword.xWPA.cPassphrase, xWiFiInfo.cWiFiPassword, strlen(xWiFiInfo.cWiFiPassword));
    +xNetworkParams.xPassword.xWPA.ucLength = strlen(xWiFiInfo.cWiFiPassword);
    +xNetworkParams.xSecurity = xWiFiInfo.xWiFiSecurity;
    +xNetworkParams.ucChannel = 0; /* Scan all channels (255) */
    +
    /*Turn  WiFi ON */
    if (WIFI_On() != eWiFiSuccess)
    
  2. TCP/IP層の初期化関数実行と同時にWi-Fi接続しないように修正

    本デモシステムではスマホアプリで指示したときにWi-Fiに接続したいため、TCP/IP層の初期化時にWi-Fi接続しないように修正します。

    amazon-freertos/libraries/freertos_plus/standard/freertos_plus_tcp/FreeRTOS_IP.c
    #include "FreeRTOS_DNS.h"
    
    +#include "common/include/network_operation.h"
    
    /* Used to ensure the structure packing is having the desired effect.  The
     * 'volatile' is used to prevent compiler warnings about comparing a constant with
     * a constant. */
    
    amazon-freertos/libraries/freertos_plus/standard/freertos_plus_tcp/FreeRTOS_IP.c
    /* A possibility to set some additional task properties. */
    iptraceIP_TASK_STARTING();
    
    +#if 1
    +#if ipconfigUSE_DHCP == 0
    +vIPNetworkUpCalls();
    +#endif
    +#else
    /* Generate a dummy message to say that the network connection has gone
    *  down.  This will cause this task to initialise the network interface.  After
    *  this it is the responsibility of the network interface hardware driver to
    *  send this message if a previously connected network is disconnected. */
    FreeRTOS_NetworkDown();
    +#endif
    
    #if ( ipconfigUSE_TCP == 1 )
    
    amazon-freertos/libraries/freertos_plus/standard/freertos_plus_tcp/FreeRTOS_IP.c
    if( xNetworkInterfaceInitialise() != pdPASS )
    {
        /* Ideally the network interface initialisation function will only
        * return when the network is available.  In case this is not the case,
        * wait a while before retrying the initialisation. */
        vTaskDelay( ipINITIALISATION_RETRY_DELAY );
    +#if 0
        FreeRTOS_NetworkDown();
    +#endif
    }
    

6. トラブルシューティング

ビルドが失敗する場合

  • 事象
    ビルド実行時に以下のようなエラーが表示されビルドが成功しない。
    例えば、MPLAB X IDEを開いたままgitでブランチを移動した場合に発生することがある。

    make[2]: Leaving directory 'C:/***/projects/microchip/wfi32_iot_pic32mzw1_ecc/mplab/aws_demos/firmware/aws_demos.X'
    make[1]: *** [nbproject/Makefile-aws_demos.mk:108: .build-conf] Error 2
    make[1]: Leaving directory 'C:/***/projects/microchip/wfi32_iot_pic32mzw1_ecc/mplab/aws_demos/firmware/aws_demos.X'
    make: *** [nbproject/Makefile-impl.mk:39: .build-impl] Error 2
    
  • 解決方法
    ビルド時に使用されるMakefileを再生成する。

    1. MPLAB X IDEは閉じる
    2. エラーとなっているプロジェクトのフォルダを特定する。上記の例だと下記のフォルダのエラー箇所になる      \projects\microchip\wfi32_iot_pic32mzw1_ecc\mplab\aws_demos\firmware\aws_demos.X\nbproject\
    3. このフォルダでconfigurations.xml, project.xml以外のファイルとフォルダを消す
    4. MPLAB X IDEを再度開き、しばらく待つ(上記で消したファイルが再度生成されるのを待つ)
    5. 再度ビルドを実施する

7. ソースコード

https://github.com/SystemzeusInc/SmartLockDemoEmbeddedApp

8. おわりに

本記事ではWFI32-IoT Board(PIC32MZW1)を用いたFreeRTOSのデバイスの組込みアプリを開発するための環境の構築方法について説明しました。
本ブログを読まずに環境構築する場合と比べ、数日分は時間を節約できたのではないでしょうか。

免責事項

作者または著作権者は、本記事に起因または関連して生じる一切の請求、損害、その他の義務について何ら責任を負いません。

株式会社システムゼウス

Discussion