1. Тема дня
GPIO-ограничения ESP32/ESP32-C3 и правила выбора пинов: strapping pins, UART0, flash/PSRAM- пины, JTAG/SWD, input-only GPIO, ADC2 при Wi-Fi, оформление board_pins.h. Главная мысль: В embedded нельзя выбирать GPIO только по принципу “свободная ножка”. У каждой ножки есть история: загрузка, flash, отладка, аналоговые ограничения, подтяжки, sleep/wakeup и периферийные функции.
2. Зачем это нужно
В проектах важны:
- UART2 для EC25: TX17/RX16 на ESP32-WROOM-32U;
- UART0 для CLI/прошивки;
- входы светофора;
- GPIO для PWRKEY/RESET EC25;
- GPIO для питания камеры/радара/Jetson;
- 1-Wire DS18B20;
- синхросигналы PPS/20 Гц;
- HIL через Raspberry Pi;
- перенос на STM32.
Ошибки выбора GPIO дают странные симптомы:
- плата иногда не стартует;
- прошивка не заливается;
- ESP32 уходит в download mode;
- UART лог молчит;
- Wi-Fi ломает ADC;
- JTAG/SWD не работает;
- внешний вход влияет на режим загрузки.
3. Strapping pins
Strapping pins - пины, которые микроконтроллер считывает при reset/startup, чтобы выбрать параметры загрузки. Для классического ESP32:
GPIO0
GPIO2
GPIO5
GPIO12 / MTDI
GPIO15 / MTDOДля ESP32-C3:
GPIO2
GPIO8
GPIO9После старта они могут работать как обычные GPIO, но уровень на reset уже повлиял на загрузку.
4. GPIO0
GPIO0 = LOW при reset -> serial bootloader / download mode
GPIO0 = HIGH при reset -> normal execution from flashПрактический вывод: GPIO0 нельзя бездумно вешать на внешний сигнал, который при включении может оказаться LOW. Если повесить на GPIO0 вход от оптопары, ESP32 может уйти в bootloader вместо запуска прошивки.
5. GPIO2
Для прошивки GPIO2 должен быть в корректном состоянии. Его лучше не использовать для входа, который при reset может быть жёстко подтянут к неправильному уровню.
6. GPIO12 / MTDI
GPIO12 особенно опасен: он связан с выбором напряжения flash VDD_SDIO. Если GPIO12 high при reset, ESP32 может выбрать неподходящее напряжение flash. Практический вывод: GPIO12 лучше не использовать для внешних сигналов, которые могут быть HIGH на старте.
7. GPIO15 / MTDO
GPIO15 может влиять на boot log. Если он в неправильном состоянии, может казаться, что UART лог молчит.
8. Flash/PSRAM-пины
Для ESP32:
GPIO6-GPIO11 - обычно SPI flash, не использовать
GPIO16/GPIO17 - могут быть заняты PSRAM на некоторых модуляхДля ESP32-WROOM-32U без PSRAM GPIO16/GPIO17 часто доступны, поэтому UART2 TX17/RX16 может быть допустим. Но при смене модуля на WROVER/PSRAM нужно перепроверить. Для ESP32-C3 GPIO12-GPIO17 часто связаны с flash.
9. UART0
GPIO1/GPIO3 обычно используются для flashing/debugging. Рекомендуемая политика:
UART0:
прошивка, monitor, CLI, HIL-debug
UART2:
EC25 modem
другие GPIO:
входы, управление питанием, синхросигналы10. Input-only GPIO34-GPIO39
На ESP32 GPIO34-GPIO39 - только входы. У них нет программно включаемых pull-up/pull-down. Хорошо для:
- дискретных входов;
- ADC;
- сигналов состояния.
Плохо для:
- управления реле;
- PWRKEY/RESET EC25;
- LED;
- 1-Wire;
- I2C;
- линий, где нужна внутренняя подтяжка.
11. ADC2 и Wi-Fi
На ESP32 ADC2 конфликтует с Wi-Fi. Если Wi-Fi используется, аналоговые измерения лучше планировать на ADC1. Стартовая политика:
аналоговые измерения + Wi-Fi -> ADC1
ADC2 использовать только при полном понимании ограничения12. STM32-параллель: SWD надо беречь
На STM32 похожая проблема - debug pins:
PA13 / SWDIO
PA14 / SWCLK
NRST
BOOT0Рекомендации:
- не занимать PA13/PA14 на ранней стадии;
- вывести NRST на разъём;
- BOOT0 не оставлять floating;
- SWD-разъём оставить доступным.
13. Типичные ошибки
- повесить внешний вход на GPIO0;
- использовать GPIO12 как обычный вход с внешней подтяжкой вверх;
- занять UART0 под рабочую периферию;
- взять GPIO34-GPIO39 для выхода;
- надеяться на внутреннюю подтяжку в важном сигнале;
- использовать ADC2 вместе с Wi-Fi;
- на STM32 отключить SWD в CubeMX.
14. Практическое задание
Создай PIN_AUDIT.md:
# Pin audit
## Target MCU/module
- MCU: ESP32-WROOM-32U
- Framework: ESP-IDF 6.x
- Board revision: ...
## Reserved / dangerous pins
### ESP32 strapping pins
- GPIO0: BOOT / download mode
- GPIO2: boot mode related
- GPIO5: strapping
- GPIO12 / MTDI: flash voltage strap
- GPIO15 / MTDO: boot log strap
Rule:
Do not connect external uncontrolled signals to strapping pins.
### Flash / PSRAM
- GPIO6-GPIO11: do not use
- GPIO16/GPIO17: check exact module
### UART0
- GPIO1 TX0: console/flashing/debug
- GPIO3 RX0: console/flashing/debug
### Input-only
- GPIO34-GPIO39: input only, no internal pull-up/down
### ADC
- Prefer ADC1 when Wi-Fi is used.
- Avoid ADC2 for measurements that must work during Wi-Fi operation.Таблица:
| Signal | GPIO | Direction | Boot-sensitive? | Pull | Owner component | Risk | Decision |
|---|---:|---|---|---|---|---|---|
| EC25_TXD | 17 | ESP32 TX | check module | external/device | modem_service | PSRAM conflict on some modules | OK for WROOM-32U |
| EC25_RXD | 16 | ESP32 RX | check module | external/device | modem_service | PSRAM conflict on some modules | OK for WROOM-32U |
| CLI_TXD | 1 | TX | UART0 | USB-UART | cli_service | boot/debug conflict | keep |
| CLI_RXD | 3 | RX | UART0 | USB-UART | cli_service | boot/debug conflict | keep |15. Короткий итог
Пины надо проектировать до кода. Базовая политика ESP32:
UART0 GPIO1/GPIO3:
оставить для прошивки, CLI, monitor, HIL recovery.
GPIO0/GPIO2/GPIO5/GPIO12/GPIO15:
не использовать для внешних неопределённых сигналов.
GPIO6-GPIO11:
не использовать, flash.
GPIO34-GPIO39:
только вход, внешние подтяжки обязательны при необходимости.
ADC:
при Wi-Fi предпочитать ADC1.
EC25 UART:
UART2 TX17/RX16 допустим для текущего ESP32-WROOM-32U,
но recheck при смене модуля.Задание
UART2 использует TX17/RX16 на ESP32-WROOM-32U без PSRAM. Проект меняется на PSRAM module. Что перепроверить перед повторным использованием board_pins.h?
Критерии самопроверки: Назовите module-specific memory reservations и boot/debug checks; не переносите pin map без проверки.
Показать ответ автора
Проверьте reservations Flash/PSRAM точного module, доступность GPIO16/GPIO17, boot/strapping behaviour и доступ debugging/flashing. Допустимое назначение старого module не становится автоматически допустимым для нового. Зафиксируйте module и внешние levels при reset в pin audit.