ESP8266 ポートに関する一般的なこと

ESP8266 は Espressif Systems 社の人気 WiFi 対応システムオンチップ(SoC)です。

ボードの多様さ

ESP8266 チップを搭載した、さまざまな多数のモジュールとボードがあります。MicroPython はできるだけ多くのボード/モジュール上で動作する汎用ポートを提供しようとしますが、制限があるかもしれません。Adafruit Feather HUZZAH ボードがリファレンスのボードとして使われています(たとえば、テストがこのボードで実行されています)。別のボードを使う場合は、データシート、回路図、およびボードのその他の参考資料を用意して、ボードのさまざまな機能を調べるようにしてください。

一般的な ESP8266 ポートを作成し、可能な限り多くのボードをサポートするには、次の設計と実装の決定が行われました。

  • GPIO ピン番号は ESP8266 のチップ番号に基づいており、特定のボードの「論理的」な番号付けには基づいていません。ボードのピンと実際の ESP8266 ピンの対応を見つけるには、ボードのマニュアル/ピン図を用意してください。また、様々なボードのユーザーに、MicroPython フォーラムを介してこのマッピングを共有することを推奨します。これは、最終的にコミュニティ管理の参照資料を収集するというアイデアです。
  • MicroPython は、サポートするのに適したすべてのピンをサポートしています(たとえば、SPI フラッシュを接続するために使用されるピンは露出していません。他用途で使うには有益でないため、ピンで動作させるとボードの障害につながります)。ただし、特定のボードはピンのサブセットのみを露出させることがあります。ボードリファレンスマニュアルを参照してください。
  • 一部のボードには、ESP8266 ディープスリープモードをサポートするための外部ピン/内部接続がない場合があります。

技術仕様および SoC データシート

ESP8266 チップのデータシートおよびその他の参考資料は、ベンダーのサイト http://bbs.espressif.com/viewtopic.php?f=67&t=225 から入手できます。これらは、チップの技術仕様、機能、動作モード、内部機能などの主要な参考資料となっています。

便宜上、いくつかの技術仕様を以下に示します。

  • アーキテクチャ: Xtensa lx106
  • CPU 周波数: 80MHz、160MHz にオーバークロック可能
  • 使用可能なRAMの合計: 96KB (システムの予約分)
  • ブート ROM: 64KB
  • 内蔵フラッシュROM: なし
  • 外部フラッシュROM: コードとデータ、SPIフラッシュ経由。通常のサイズは 512KB-4MB
  • GPIO: 16 + 1 (GPIO は外部フラッシュROM、UART、ディープスリープ起床など、他の機能と多重化されています)
  • UART: 1つのRX/TX UART (ハードウェアハンドシェイクなし)、1つのTX専用 UART
  • SPI: 2つの SPI インタフェース (1つはフラッシュ ROM に使用)
  • I2C: ネイティブの外部 I2C なし (任意のピンでビットバングの実装が可能)。
  • I2S: 1.
  • プログラミング: UART から BootROM ブートローダーを使用する。外部 FlashROM と常時使用可能な BootROM ブートローダのため、ESP8266 が文鎮化することはありません。

ランタイムリソースの不足

ESP8266 のリソースは非常に控えめです(なによりも、RAMメモリー容量)。したがって、大きすぎるコンテナオブジェクト(リスト、辞書)とバッファの割り当ては避けてください。また、リソースを追跡して自動的にクリーンアップするための本格的な OS はありませんので、それはユーザー/ユーザーアプリケーションのタスクです。使用後できるだけ早くファイル、ソケットなどを閉じてください。

ブートプロセス

起動時、MicroPython EPS8266 ポートは内部のフリーズされたモジュールから _boot.py スクリプトを実行します。FlashROM にファイルシステムをマウントするか、マウントできなければ、モジュールの初回セットアップを実行してファイルシステムを作成します。ブートプロセスのこの部分は固定されていると見なされ、エンドユーザーのカスタマイズには使用できません(たとえソースからビルドしても、変更を控えてください; 初期ブートプロセスのカスタマイズは、上級ユーザーや開発者だけ、標準的なプロセスを変更することによって生じる問題を自分で診断できる方だけが行うようにしてください)。

ファイルシステムがマウントされると、 boot.py がファイルシステムから実行されます。このファイルの標準バージョンは、初めてモジュールをセットアップするときに作成され、WebREPL デーモンを起動するコマンド(デフォルトでは無効、 webrepl_setup モジュールで設定可能)などがあります。このファイルはエンドユーザーがカスタマイズできます(たとえば、いくつかのパラメータを設定するか、モジュールの起動時に実行する必要がある他のサービスを追加します)。しかし、 boot.py を誤って変更すると、ブートループや障害につながる可能性があり、モジュールを最初から再フラッシュすることになるかもしれないことに注意してください。(特に、 webrepl_setup モジュール使用、WebREPL 設定の手編集のどちらかを使用することをお勧めしますが、両方を使用することはお勧めしません)。

ブート手順の最終ステップとして、 main.py がファイルシステムから実行されます(存在する場合)。このファイルは、ブート時に毎回(REPL に行くのではなく)ユーザーアプリケーションを起動するためのフックです。小規模なテストアプリケーションでは、モジュールに main.py と直に名前を付けてアップロードすることもできますが、アプリケーションを別々のファイルに保存し、 main.py で次のようにすることをお勧めします。

import my_app
my_app.main()

これにより、アプリケーションの構造を明確に保ち、ボード上に複数のアプリケーションをインストールし、それらの間で切り替えることができます。

既知の問題

リアルタイムクロック

ESP8266 の RTC は非常に精度が悪く、ドリフトは毎分秒になる可能性があります。回避策として、十分な短い間隔を測定する time.time() などの機能を使用できます。また、実時間とするには、含まれている ntptime.py モジュールを使用してネットから同期してください。

ESP8266 チップの制限により、内部リアルタイムクロック (RTC) は 7:45h 毎にオーバフローします。長期の作業で RTC 時間が必要な場合は time() または localtime() を7時間以内に少なくとも1回は呼び出す必要があります。そのようにすると、MicroPython がオーバーフローを処理します。

STA_IF と AP_IF の同時利用

STA_IF と AP_IF インターフェースの同時利用がサポートされています。

ただし、ハードウェアの制限により STA_IF が接続されていない状態で検索を行うと、AP_IF のパフォーマンスに問題が発生する可能性があります。アプリケーションはこのようなインターフェースの挙動を管理する必要があります。たとえば AP_IF のみを使う環境では STA_IF を無効にするなどです。

ソケットと WiFi バッファのオーバーフロー

ソケットインスタンスは、明示的に閉じるまでアクティブのままです。これには2つの影響があります。まず、RAM を占有するため、ソケットを閉じずにソケットを開いていくアプリケーションは、最終的にメモリ不足になる可能性があります。第2に、適切に閉じられていないソケットは、ベンダー WiFi スタックの低レベル部分に Lmac エラーを発生させる可能性があります。これは、データがソケットで受信され、適時に処理されない場合に発生します。これは、WiFiスタックの入力キューをオーバーフローさせ、デッドロックを招く可能性があります。唯一の回復方法は、ハードリセットすることです。

上記は、例外を含む何らかの理由でアプリケーションが終了して REPL を終了した後にも発生する可能性があります。データの後続の到着は、上記のエラーメッセージが繰り返し発行されて失敗を引き起こします。したがって、ソケットは、アプリケーションが正常に終了するかどうかにかかわらず、どんな場合でも閉じなければなりません。たとえば、try/finally を使用します。

sock = socket(...)
try:
    # Use sock
finally:
    sock.close()

SSL/TLS の制限事項

ESP8266 uses axTLS library, which is one of the smallest TLS libraries with compatible licensing. However, it also has some known issues/limitations:

  1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve cryptography (ECC). This means it can't work with sites which require the use of these features (it works ok with the typical sites that use RSA certificates).
  2. 半二重通信の性質。axTLSは、送信と受信の両方に単一のバッファを使用するため、メモリの節約につながり、HTTP などのプロトコルでうまく機能します。しかし、古典的な要求応答モデルにしたがわないプロトコルには問題があるかもしれません。

Besides axTLS's own limitations, the configuration used for MicroPython is highly optimized for code size, which leads to additional limitations (these may be lifted in the future):

  1. 最適化された RSA アルゴリズムが有効になっていないため、SSL ハンドシェイクが遅くなる可能性があります。
  2. Session Reuse is not enabled, which means every connection must undergo the full, expensive SSL handshake.

上記の axTLS 固有の制限の他に、低メモリデバイスでの TLS の使用には別の一般的な制限があります:

  1. The TLS standard specifies the maximum length of the TLS record (unit of TLS communication, the entire record must be buffered before it can be processed) as 16KB. That's almost half of the available ESP8266 memory, and inside a more or less advanced application would be hard to allocate due to memory fragmentation issues. As a compromise, a smaller buffer is used, with the idea that the most interesting usage for SSL would be accessing various REST APIs, which usually require much smaller messages. The buffers size is on the order of 5KB, and is adjusted from time to time, taking as a reference being able to access https://google.com . The smaller buffer however means that some sites can't be accessed using it, and it's not possible to stream large amounts of data. axTLS does have support for TLS's Max Fragment Size extension, but no HTTPS website does, so use of the extension is really only effective for local communication with other devices.

また、AxTLS を基にした MicroPython の ssl のモジュールには実装されていない機能もあります。

  1. Certificates are not validated (this makes connections susceptible to man-in-the-middle attacks).
  2. クライアント証明書はサポートされていません(1.9.4リリースで修正予定)。