Arduino – ESP32 WiFiClientSecure ライブラリのハングアップ問題がついに解決!

ESP32 ( ESP-WROOM-32 )
GitHub の Arduino core for ESP32 が大幅アップデートされました。
よって、以下の記事にあるような、libmbedtls.a ファイルも修正され、main.cpp のスタックサイズも修正され、フリーズ(ハングアップ)しなくなりました。
そのことを踏まえて以下の記事をご覧ください
(2017/8/2時点) 

こんばんは。

アマチュア電子工作家の私としては、今回は一歩も二歩も踏み込んで問題を解決してみました。
おかげで疲労困ぱい状態でございます。

GitHub にある、Arduino core for ESP32 WiFi chip の WiFiClientSecure ライブラリを使って、Web上の SSL ( https )サイトを GET していると、200回以下で必ずフリーズ(ハングアップ)して、 ESP32 ( ESP-WROOM-32 )が一切動かなくなってしまう症状がありました。

最近はデュアルコア(マルチタスク)も試していますが、そのうちの 1core だけが動かなくなってしまいます。

これには長らく悩まされていましたが、今回、ついに解決しました!!!

結論は、mbedtls ライブラリの MPI ハードウェアアクセラレーションが有効になっていたことが原因です。

ただ、mbedtls ライブラリの設定は、ESP-IDF では簡単に変えることができるのですが、Arduino core for ESP32 では変えられないんです。
Web上のどこにもその手順は無く、自分で解決せざるを得ませんでした。
要は、GitHub 上のライブラリでバグ修正してくれれば話は早いのですが、今、issue で問題点を投げかけている最中です(解決済み)
ですが、何とか自力で解決できましたので私的には満足です。
本家のライブラリがアップデートされるまでの間の対処方法として、十分使えると思いますよ。

実は、以下に述べる方法は、私としてはとても画期的で、目から鱗のようなノウハウが沢山ありました。
これらは、Arduino IDE で ESP32 をデュアルコア(マルチタスク)で動かすことの参考にもなりますし、豊富な機能の ESP-IDF と Arduino IDE を連携させることにも役立つ方法です。

このノウハウを身に付けることによって、ESP32 の開発が飛躍的に伸びる可能性大です。

では、方法を説明しますが、その前に、Twitter でもいろいろ情報を頂戴している けりさん ( @Ryokeri14 )の以下のブログ記事からは、大変良いヒントを頂きました。

ESP32でデュアルコアを使おう!

この記事は WiFiClientSecure ライブラリと関係ないと思うかもしれませんが、実は後でジワジワと効いてきますので、合わせてご覧ください。

最近では、また新たなことが分かりました。
以下の記事を参照してください。
ESP32 および M5Stack で数時間後に Web 記事取得失敗する問題について

また、WiFiClientSecure ライブラリのセキュリティについて新たなことが分かりました。
以下の記事を参照してください。
WiFiClientSecure ライブラリの SSL 証明書有効期限の検証等、セキュリティ問題を探ってみた
2018/11時点の WiFiClientSecure ライブラリは、相手サーバー証明書の有効期限チェックや失効リストの検証(Verify)はしてくれないので、それを十分了承の上使用してください。
(2018/11/15)

 

スポンサーリンク

ハングアップ原因の特定方法

Arduino core for ESP32 の WiFiClientSecure ライブラリを使って、SSL ( https )ページから定期的に記事を取得していると、ある時フリーズ(ハングアップ)します。

プログラムがストップしている個所を詳細に知るためには、下図の様に デバッグを最高レベルの Verbose にしておきます。

すると、シリアルモニターでこんな感じに表示されます。

私の場合、いつも ssl_client.cpp ファイルの 153行目でフリーズ(ハングアップ)してしまい、固まって動かなくなっていました。

ssl_client.cpp ファイルは Windows10 の場合、以下のパスにあります。

C:\Users\User-name\Documents\Arduino\hardware\espressif\esp32\libraries\WiFiClientSecure\src

ssl_client.cpp ファイルをテキストエディタで開いてみます。
すると、下図のようになっていて、153行目はデバッグログの出力です。
よって、その後の while ループで固まっていることが分かりました。

そこで、whileループ内に独自にタイムアウト制御を作って置いてみましたが、一向にタイムアウトしてくれません。

ということは、mbedtls_ssl_handshake 関数でフリーズしていることが断定できます。

では、mbedtls_ssl_handshake 関数はどこで定義されているのか?

それは、Windows のエクスプローラーのファイル検索をかけると、意外と簡単に見つけられます。

Windows10 の場合、下図の様にエクスプローラーの詳細オプションをクリックして、ファイルコンテンツにチェックを入れてください。
その後、右側の検索ワード覧に下図の様に mbedtls_ssl_handshake と入力すれば、そのワードが使われているファイルを検索してくれます。

すると、こんな感じで6つのファイルが見つかりました。

ssl_client.cpp ファイル内には、mbedtls_ssl_handshake 関数のソースはありませんでした。
その他はヘッダファイルと、拡張子が a のファイルだけです。
ヘッダファイルには関数の宣言だけしかありません。
ということは、拡張子が a の2つのファイルだけに絞ることができます。

ただ、このファイルは既にコンパイルされたアセンブラ形式のバイナリファイルです。
これを直接編集することはできません。

そこで、ネットで検索したり、GitHub の issue を検索したりしました。

結果、ESP-IDF の issue #630 Bug: mbedtls_ssl_handshake() hangs after several calls にそれらしき解決策がありました。

そこにある答えは、

mbedtls ライブラリの MPI ハードウェアアクセラレーションが原因でハングアップするので、それを解除すれば良いとのこと。

MPI ハードウェアアクセラレーションを使えば、本来は SSL 処理が速くなるらしいです。
ESP-IDF 開発環境では、コンパイルする前に、make menuconfig コマンドで設定できます。

ということは、mbedtls が問題なので、libmbedtls.a ファイルに原因があるとほぼ断定できます。

私は今まで Arduno IDE しか使ったことが無かったので、どうやったら良いか全く分かりませんでした。
よって、Arduino core for ESP32 の issue #481 で質問してみました。
(英語が不得意なので、翻訳機能を使っています。)

すると、現在の ESP-IDF ではデフォルトで MPI ハードウェアアクセラレーションが外されているとのこと。
現段階では、MPI ハードウェアアクセラレーションはバグが多いらしいです。
つまり、ESP-IDF で設定して、SSL ページ取得するプログラムを組めば、全く問題ない動作をするそうなのです。

また、Arduino IDE のハングアップを解決するためには、開発チームの @me-no-dev さんに libmbedtls.a ファイルをコンパイルしてもらうように依頼して下さいとの回答でした。

ちょっと途方に暮れてしまいましたが、もしかしたら、ESP-IDF を使えば libmbedtls.aファイルを自分でコンパイルできるかも知れないと思いつつ実験してみることにした次第です。

ESP-IDF 開発環境のインストール

ESP-IDF 開発環境は、本家 Espressif 社推奨のものです。
私はずっと Arduino IDE しか使ったことが無かったので、これを使い始めたのはほんの2週間前で、かなり出遅れました。

Arduino IDE と違って、かなり取っ付きにくいので、以下の記事に私なりにまとめてみました。
コマンドラインで環境設定やコンパイル書き込みを行います。
理解するまでに少々時間がかかるのは覚悟しておいてください。

ESP-IDF ( ESP32 開発環境 ) の使い方

これは、ESP32 ( ESP-WROOM-32 ) のポテンシャルや機能をフルに使おうとするならば、覚えていて損はありません。
一度覚えてしまえば、それほど難しいことは無いと思われます。

今回は、Arduino core for ESP32 ライブラリの libmbedtls.a をコンパイルし直すために使います。

コメント

  1. カンパニー より:

    素晴らしい記事をありがとうございます。
    ぜひ参考にさせていただきます。

    1つ質問なのですが、私はESP32をスイッチサイエンスさんで販売されている
    “ESP-WROOM-32ブレイクアウトSD+”を使用しています。
    このボードではSDカードを”SDMMC”というライブラリを使うみたいで”ESP32_SD_ShinonomeFNT Beta ver 1.0″が動作しませんでした。

    できればmgo-tecさんのライブラリにSDMMC版が対応していただけるとありがたいです。

    • mgo-tec mgo-tec より:

      カンパニーさん

      今回も当記事をご覧いただき、ありがとうございます。

      私はスイッチサイエンスさんの委託販売ボード “ESP-WROOM-32ブレイクアウトSD+” は持っておりません。
      MMCライブラリしか対応していないので、敬遠していました。

      MMC については私は使ったことが無いので、これから検討してみたいと思います。
      しばらく時間がかかるかも知れませんので、何卒ご容赦くださいませ。

タイトルとURLをコピーしました