自戒、点検、内省

終わらない反省会をしよう

MacのDockerコンテナからR2P2-ESP32のflashやmonitorは成功に至らなかった現状まとめ

Macをやめるかかなあ。いやはやでした。

背景・目的

ESP32(ATOM Matrix)の開発において、VS CodeのDev Container環境で統一された開発体験を実現したいと考えました。具体的には以下のような要件がありました。

  • 開発環境の一貫性 チーム開発での環境差異を排除したい
  • ESP-IDFの統合 IntelliSense、ビルド、flash、monitorの一元化
  • 依存関係の管理 コンテナによる環境の再現性確保
  • 開発体験の向上 ネイティブ環境と同等のワークフローを実現したい

しかし、macのDockerではUSBデバイスの直接パススルーができないため、TCP経由でのシリアル通信転送が必要になりました。Dev Container環境でこの制約をどこまで技術的に克服できるかを検証しました。

技術仕様

  • 開発環境 macOS + Docker for Mac + VS Code Dev Container
  • ターゲット ESP32 (ATOM Matrix)
  • シリアル接続 /dev/tty.usbserial-5D5A501DF0
  • 開発手法 Dev Container(devcontainer.json設定)
  • 要件 flash書き込みとシリアルモニター機能の統合

試行した解決策と結果

1. socatによる基本的なTCP転送

アプローチ

# mac側
socat TCP-LISTEN:4000,reuseaddr,fork /dev/tty.usbserial-5D5A501DF0,raw,echo=0

# Docker側
socat pty,link=/tmp/ttyD0,raw,echo=0 TCP:host.docker.internal:4000

結果 - ✅ 基本的なデータ転送は成功しました - ❌ RTS/DTR制御信号が転送されませんでした - ❌ ESP32ブートローダーがboot/resetモードに入りませんでした

エラー Failed to connect to ESP32: No serial data received

2. ser2netによるRFC2217対応

アプローチ

# mac側 RFC2217プロトコルで制御信号も転送
ser2net -n -d -Y "connection: &con01
  accepter: telnet(rfc2217),tcp,4000
  connector: serialdev,/dev/tty.usbserial-5D5A501DF0,115200n81,local"

# Docker側
socat pty,link=/tmp/ttyD0,raw,echo=0 TCP:host.docker.internal:4000

結果 - ✅ RTS/DTR制御信号の転送に対応できました - ❌ telnetプロトコルエスケープシーケンスがデータに混入しました - ❌ esptoolがバイナリデータとして認識できませんでした

エラー Failed to connect to ESP32: Invalid head of packet (0x1B): Possible serial noise or corruption

3. 2段階socat転送

アプローチ

# 1段目:TCP→UNIXソケット
socat TCP:host.docker.internal:4000 UNIX-LISTEN:/tmp/serial.sock &

# 2段目:UNIXソケット→PTY
socat UNIX-CONNECT:/tmp/serial.sock PTY,link=/tmp/ttyD0,raw,echo=0 &

結果 根本的な制約は解決されず、同様の問題が継続しました。

4. esptoolによる直接RFC2217接続

アプローチ

# esptoolがRFC2217をサポートしているため直接接続を試行
esptool.py --chip esp32 -p rfc2217://host.docker.internal:4000 chip_id

結果 - ❌ idf.pyがrfc2217://スキームをサポートしていませんでした - ❌ 統合開発環境として利用できませんでした

技術的制約の分析

PTY(疑似端末)の根本的制限

PTYデバイスの特性 - 疑似端末デバイス/dev/pts/Xへのシンボリックリンク)です - ハードウェア制御信号(RTS/DTR/DSR/CTS)の完全サポートがありません - ioctl操作の多くがENOTTYエラーを返します

ESP32ブートローダーの要件 - GPIO0制御(ブートモード選択)でDTR信号連動が必要です - ENピン制御(リセット)でRTS信号連動が必要です - これらの物理制御信号が自動flash書き込みに必須です

プロトコルオーバーヘッドの問題

RFC2217/telnetプロトコル - 制御信号転送のためのバンド内シグナリングを使用します - エスケープシーケンス(0x1B)がバイナリデータに混入します - esptoolの期待する純粋なシリアルストリームと非互換です

データ整合性の問題

期待値: [0x07 0x07 0x12 0x20] (esptoolハンドシェイク)
実際値: [0x1B 0xFF 0xFD 0x07] (telnetエスケープ + データ)

学んだこと・技術的知見

Dev Container環境における組み込み開発の制約

仮想化の根本的限界 - ハードウェア制御信号は仮想化技術では完全再現が困難です - 特に組み込み開発では物理制御が開発フローに不可欠です - Docker for Macの追加制約(Linux Dockerとは異なるアーキテクチャ)があります

Dev Container理想と現実のギャップ - 統合開発環境の魅力vs物理制御の要件という対立があります - 環境の一貫性vs開発効率のトレードオフが存在します - 理論的可能性vs実用的制約のジレンマがあります

ESP32開発における不可避的制約

esptoolの厳格な要件 - シリアル通信プロトコルの完全性要求があります - ハードウェア制御信号への強い依存があります - バイナリデータの完全性保証が必須です

Dev Container環境との本質的非互換性 - 仮想シリアルデバイス(PTY)の機能的制限があります - TCP転送による制御信号の損失が発生します - プロトコル変換によるデータ破損リスクがあります

結論

macのDocker for Mac環境におけるESP32開発では、Dev Container環境での完全な統合開発環境の実現は技術的に困難であることが判明しました。

根本的問題 - PTYデバイスの制約によりハードウェア制御信号が失われます - プロトコル変換によるデータ整合性の問題があります - これらは標準的なツールでは解決困難です

現時点での結論 macでのESP32開発においては、Dev Containerの使用を避け、ネイティブ環境での開発を推奨します。

理想的な統合開発環境の追求よりも、確実に動作する開発環境の構築を優先すべきです。Docker for Macの仮想化アーキテクチャと組み込み開発の要件は、現時点では相性が良くありません。

今後の展望

  • Docker for MacのUSB制御機能の改善
  • ESP32ブートローダーの制御信号依存度軽減
  • 代替開発フローの確立(OTA開発等)

これらの技術進歩により、将来的にはDev Container環境でのESP32開発が実現される可能性があります

あんちぽさんにオススメいただいた『生きのびるための事務』を読んだ

今日の仕事帰りに一気読みしました。

芸術家でも誰でも、事務作業を疎かにしては
何も成し遂げられない。
夢を現実にするたった一つの技術、
それが《事務》です。

以下スクショをとっていったところの一部です。

  • 《事務》は「冒険」のための道具なんです。「冒険」を始めない限り、事務なんて存在しないんです。
  • 《事務》は分らないものを明らかにするのではなく、分らないまま仕事を延々と継続するためにあるんです。
  • 自分を褒めるな、自分の《事務》を徹底して褒めろ。逆もまた然り。自分を批判するな、自分の《事務》を徹底的に批判しろ。
  • 能力のある大工さんはみんな《段取り》能力、つまり《事務》の能力が半端ないですからね。

いや、ビジネスの軸のひとつは事務ですわ。自分の脳みその範囲を超えること成し遂げようとするときには事務としてビルドする力が必要になるんだなというのを感じました。

そして、これをプロジェクトマネジメントやスコープコントロールトレードオフスライダーなど、変数にして制御することを学んで実践してこれたことは、自分が生き延びる大きな武器になってくれたんだなあという自覚を得ました。

そして、ちょうど GMOペパボで活躍中の id:antipop を訪問 | はてな卒業生訪問企画 [#16] - Hatena Developer Blog で読んだこのくだりを思い出すなどしていました。

社会人って、期限までにやらなければいけないことや、クオリティコントロールの仕方を心得ていますよね 。もちろん100点は取れればいいですが、この期限では無理なので、合格点が60点だとしたら65点、ギリギリで取るにはどうしたらいいかというようなのが上手になるじゃないですか 。なので、社会人スキルをフル活用できるので、そういう意味ではそんなに大変ではありませんでしたね 。100点取ろうと思ったら大変だと思いますが、合格点ギリギリ取ればいいという感じなので 。

これもまた事務であり、とても広い概念で、だからこそ《事務》と本の中では強調されてるのかもしれません。

ところで事務処理というと、THE 事務な仕事に携わってない人はよく苦手を表明しがちですが、たとえば今日のソフトウェアエンジニアリングは事務処理を事務と思わずでも事務の専門家以上に研ぎ澄ましてきた歴史ではないかと思います。issueマネジメントもプルリクのレビューもLLMのルールファイル作りもビルドパイプラインを流すのも《事務》なんですよね。

ただこういう系の仕事はエンジニアリングの当事者は事務と思っていないので事務スキルとして伝達できないし、他の専門家やTHE 事務の人にとっても他専門領域の仕事とみえるので自らの領域に転用しにくいし、そんな溝をなんとかできんものかと考えている今日この頃です。

ATOM MatrixでPicoRuby(ESP32)でGrove接続での外部センサーからUARTで値を取り出す初期化メモ

docs.m5stack.com

M5Stack用ASRユニット - オフライン音声認識モジュール (CI-03T)www.switch-science.com

require 'uart'
UART_TX = 26  # Grove SDA → UART TX  
UART_RX = 32  # Grove SCL → UART RX

# 初期化
uart = UART.new(unit: :ESP32_UART1, baudrate: 115200, txd_pin: UART_TX, rxd_pin: UART_RX)

作りかけのコード

led_asr.rb · GitHub