1. Тема дня

Сегодня разбираем питание как часть архитектуры прошивки:

text
источник питания
→ DC/DC или LDO
→ локальные конденсаторы
→ power-good / voltage monitor
→ ESP32, STM32, EC25 и периферия
→ brownout detection
→ controlled degraded mode
→ безопасная остановка записи Flash
→ reset или отключение

Главная мысль: Brownout detector не исправляет плохое питание. Он лишь останавливает процессор до того, как тот начнёт исполнять код при небезопасном напряжении.

2. Зачем это нужно в твоих проектах

EC25 даёт всплески тока при регистрации, передаче данных, поиске сети и TLS/MQTT/HTTP- трафике. Поэтому источник питания должен выдерживать пиковые нагрузки, а напряжение нужно измерять непосредственно на выводах модуля, не только на входе платы. ESP32 brownout detector по умолчанию включён. Если он срабатывает, отключение detector — не решение, а маскировка проблемы. STM32 часто имеет POR/PDR, BOR, PVD и может использовать внешний supervisor для раннего предупреждения.

3. Теория

10.3.1 3.1. Brownout reset и early warning

Brownout reset происходит, когда напряжение уже слишком низкое. В этот момент поздно начинать MQTT publish, NVS save или штатное выключение модема. Early warning должен приходить раньше:

text
VIN начал снижаться
→ supervisor/PVD сформировал сигнал
→ power_task запрещает Flash-записи
→ safe outputs
→ минимум диагностики

Порог предупреждения должен быть выше reset threshold:

text
V_WARN > V_BOR

10.3.2 3.2. Hold-up capacitor

Упрощённо:

text
C ≥ I × Δt / ΔV

Для ESP32 100 мА, 10 мс, падение 0.3 В:

text
C ≥ 0.1 × 0.010 / 0.3 ≈ 3300 мкФ

Для EC25 2 А, 10 мс, падение 0.4 В:

text
C ≥ 2 × 0.010 / 0.4 = 50 000 мкФ

Вывод: конденсатор помогает с быстрыми импульсами, но не заменяет нормальный DC/DC и разводку.

10.3.3 3.3. Bulk и ceramic capacitors

text
Ceramic 100 нФ - несколько мкФ:
  быстрые фронты, локальный ток у pin.
Bulk 100-1000 мкФ:
  RF burst, пуск, реакция DC/DC, длинная линия питания.

10.3.4 3.4. ESR

text
ΔV_ESR = I_STEP × ESR

2 А и ESR 100 мОм дают 0.2 В мгновенной просадки.

10.3.5 3.5. Power domains

text
основной источник
├── DC/DC EC25 3.8 В
├── DC/DC/LDO 3.3 В ESP32
├── питание датчиков/оптопар
└── управляемые вторичные нагрузки

Так импульс EC25 меньше влияет на ESP32, а модем можно отключать отдельно.

10.3.6 3.6. Load shedding

c
typedef enum {
    POWER_STATE_NORMAL = 0,
    POWER_STATE_WARN,
    POWER_STATE_SHEDDING,
    POWER_STATE_CRITICAL,
    POWER_STATE_RECOVERING,
} power_state_t;

При WARN запрещаем новые Flash-записи, уменьшаем телеметрию, отключаем некритичные нагрузки. При CRITICAL — safe outputs и ожидание reset. 10.3.7 3.7. EC25 нельзя просто обесточивать

Штатно модем нужно выключать через PWRKEY или AT-команду, если есть время. Но при быстром исчезновении питания аппаратная часть должна быть устойчива сама.

10.3.8 3.8. Flash/NVS и power fail

После warning нельзя начинать новую запись:

c
if (!power_service_flash_write_allowed()) {
    return ESP_ERR_INVALID_STATE;
}

Для конфигурации нужны A/B, CRC, generation. Для OTA — два слота и rollback.

10.3.9 3.9. Staged startup

Чтобы избежать boot-loop:

text
reset
→ старт только MCU
→ измерить питание
→ stable interval
→ input path
→ I2C/CAN
→ EC25
→ high-current outputs

Если много power-related resets за короткий период — не включать EC25 автоматически, а войти в degraded startup.

10.3.10 3.10. ESP32 power management

DFS/Light-sleep могут влиять на latency. Для критичных участков нужен PM lock:

c
esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "timing", &lock);
esp_pm_lock_acquire(lock);
/* critical timing */
esp_pm_lock_release(lock);

4. Типичные ошибки

text
1. Отключить brownout detector.
2. Измерять питание не на выводах EC25.
3. Верить среднему току БП.
4. Ставить один электролит далеко от модуля.
5. Делать NVS-save внутри PVD ISR.
6. Начинать shutdown EC25 слишком поздно.
7. Включать все нагрузки сразу после reset.
8. Не считать reset reason.
9. Использовать vTaskDelay() вместо проверки power-good.
10. Рассчитывать на ADC при быстром провале.
11. Пытаться удержать EC25 supercap без расчёта.
12. Не тестировать повторные короткие провалы.

5. Практическое задание на 30-60 минут

Создай POWER_POLICY.md:

markdown
# Power policy
1. Brownout detector is never disabled in production.
2. Critical Flash writes require power_good.
3. High-current loads start sequentially.
4. EC25 power is controlled independently where possible.
5. Power warning and reset thresholds are different.
6. Power-fail ISR only notifies power_task.
7. Safe outputs are defined in hardware and firmware.
8. Power-related reset loops enter degraded startup.
9. Every power transition is counted and timestamped.
10. Power-fail behavior is tested in HIL.

Добавь power_status_t:

c
typedef enum {
    POWER_QUALITY_UNKNOWN = 0,
    POWER_QUALITY_GOOD,
    POWER_QUALITY_WARN,
    POWER_QUALITY_CRITICAL,
    POWER_QUALITY_RECOVERING,
} power_quality_t;
typedef struct {
    power_quality_t quality;
    uint32_t warning_count;
    uint32_t critical_count;
    uint32_t recovery_count;
    uint32_t brownout_boot_count;
    uint32_t unstable_boot_count;
    uint32_t vin_mv;
    uint32_t rail_3v3_mv;
    uint32_t modem_vbat_mv;
    int64_t last_transition_us;
    int64_t stable_since_us;
    bool flash_write_allowed;
    bool modem_start_allowed;
    bool high_load_allowed;
} power_status_t;

CLI power:

text
power:
quality=GOOD
vin=12180mV
rail_3v3=3294mV
modem_vbat=3790mV
flash_write_allowed=yes
modem_start_allowed=yes
high_load_allowed=yes
warnings=3
critical=1
brownout_boots=1
stable_for=42800ms

HIL: проверить провалы питания во время NVS, OTA, первого boot нового OTA, запуска EC25 и дребезга питания.

6. Что почитать дальше

  • ESP-IDF Fatal Errors, Brownout Detector, Power Management.
  • STM32 PWR/BOR/PVD docs для выбранной серии.
  • Quectel EC25 Hardware Design конкретной ревизии.

Короткий итог

text
power source
→ regulator with transient margin
→ local low-ESR decoupling
→ power-good / early warning
→ power_service
→ load shedding
→ safe outputs
→ transactional storage
→ BOR/brownout reset as last protection

Задание

Reboot loop начинается при EC25 transmission. Определите measurement point и startup policy без маскировки отказа.

Критерии самопроверки: Использовать peak-voltage evidence, а не один average current; не заменять power-good validation произвольным delay.

Показать ответ автора

Измерить voltage на EC25 module pins при peak activity и проверить regulator/layout/transients. Сохранить brownout protection; сначала запускать MCU и essential inputs, требовать stable supply interval и применять degraded startup после повторных power-related resets.

Задание

Спроектируйте low-voltage HIL power-loss test при configuration save. Укажите warning action и evidence valid restart selection.

Критерии самопроверки: Проверить interrupted storage и restart selection на isolated test hardware; отделить warning response от final brownout reset.

Показать ответ автора

Внедрить controlled interruption, наблюдать запрет новых Flash writes при early warning и safe outputs, затем проверить A/B CRC/generation selection после reboot. Сохранить reset reason и storage status; избегать большого позднего save в warning ISR.