Наличие у контроллеров STM32, да и практически любых других, режима энергосбережения STANDBY, который фактически представляет собой полное отключение (работает только RTC и сторожевой таймер, потребление составляет первые микроамперы, а состояние не сохраняется), дает возможность простейшим способом сделать включение и выключение устройства на таком МК нажатием кнопки, в том числе и задействованной под другие функции, без каких-либо дополнительных элементов. Есть, однако, несколько подводных камней, и в этой статье я расскажу, как на них не попасть.
Базовое решение
Итак, мы вешаем кнопку, соединяющую при нажатии вход PA0/WKUP, подтянутый к земле, с питанием. Нажатие этой кнопки будет пробуждать МК, а затем эту линию можно настроить, как вход, и при ее нажатии (лучше длительном) вызывать процедуру перехода в режим STANDBY, если необходимо — с запросом подтверждения, предварительным сохранением данных, выключением вторичных источников питания и прочее. При этом не забудьте про дребезг: если выключиться, пока кнопка нажата, то с некоторой вероятностью все включится обратно в момент отпускания кнопки. Поэтому лучше дождаться отпускания, сделать маленькую паузу и тогда уж в STANDBY.
Обратите внимание: вход WKUP активизируется по нарастающему фронту.
Все это замечательно работает, на первый взгляд. Но если мы попробуем воплотить это в железе, мы встретим ряд граблей.
Первые грабли: сторожевой таймер
Сначала вы обнаружите, что это решение не дружит со сторожевым таймером IWDG. Режим STANDBY для него эквивалентен зависанию процессорного ядра. Код прекратит исполняться, собаку вовремя не покормят и она в заданное время нажмет на RESET. МК запустится с нуля и включит все обратно. Предотвратить это невозможно, IWDG можно только запустить и нельзя остановить. При этом есть определенная сложность в том, чтобы надежно отличить, что у нас произошло — начальный запуск по включению питания, выход из STANDBY — или же сработал сторожевой таймер: во всех случаях процессор стартует с чистого листа, сбросив все*). В том числе, почему‑то иногда оказываются сброшены и флаги причин сброса в RCC_CSR, которые должны использоваться в таких случаях по замыслу разработчиков STM32. Из‑за этого на эти флаги нельзя положиться — рано или поздно устройство, проснувшись от собачьего лая и поглядев во флаги, решит, что надо включаться. Я столкнулся с таким поведением на контроллере STM32L151, прибор на котором раз в несколько дней самопроизвольно включался от IWDG.
На самом деле, решение проблемы простое. Надо просто сразу после старта МК, вместо того, чтобы смотреть во флаги в RCC_CSR, проинициализировать порт PA0, к которому подключена кнопка, как вход, и тут же поглядеть, что там. Если нажали кнопку — вряд ли ту кнопку успеют отпустить за те десятки‑сотни микросекунд, что пройдут от старта МК до запуска функции main(), и мы увидим единицу на PA0. В этом случае продолжаем — все включаем, запускаем и работаем по программе дальше. Если же это IWDG обресетил МК, на порту, очевидно, будет ноль, и в таком случае мы просто сразу уходим обратно в STANDBY.
Будьте осторожны! Если вы самонадеянно посадили BOOT0 на землю на плате прямо под корпусом МК, а от SWD развели только две линии и землю (никогда так не делайте!), косяк при программировании в этом месте приведет к тому, что вы окирпичите контроллер, и чтобы раскирпичить его обратно, вам наверняка придется его выпаивать. Дело в том, что если МК уходит в STANDBY сразу же, как стартует, ST-Link к нему уже не подключится, и единственный способ выйти из этого положения - предотвратить запуск кода, переключив BOOT0. Иногда помогает Connection under reset, но только в случае, если между инициализацией и STANDBY проходит хоть какое-то время.
____________
*) По неизвестной причине и вопреки документации, после сброса по NRST, IWDG и выхода из STANDBY у многих, если не всех, МК семейства STM32 сохраняется содержимое оперативной памяти. Если переписать стартовый код, чтобы он не затирал при старте какую-то часть ОЗУ, это тоже можно использовать для распознавания состояния, записав туда перед засыпанием какой-нибудь 0xDEADBEEF. Но поскольку это недокументированная возможность, рекомендовать ее эксплуатацию нельзя.
Вторые грабли: включение при разряженном аккумуляторе
Представим, что аккумулятор у нас разряжен, а МК - из тех, у которых нет отдельной ноги для литиевой батарейки (STM32L151/152 один из таковых). Поэтому RTC питаются от основного аккумулятора. На аккумуляторе еще 3,3-3,4 В и с учетом мизерного тока потребления в режиме STANDBY, часы и backup-регистры продержатся еще много месяцев, да и здоровью аккумулятора ничего пока что не грозит. И вот не подозревающий ни о чем пользователь устройства нажимает кнопочку, МК просыпается, поднимает основные питания, DC-DC начинают заряжать свои конденсаторы, еще не дай Махадев, включается дисплей с подсветкой, потребляющей 200 мА - ток потребления подскакивает. И аккумулятор моментально просаживается — до срабатывания его платы защиты. И аккумулятору нехорошо, и часы и backup‑регистры — слетели. Oни, разумеется, не слетят, если у контроллера есть отдельный VBAT, запитанный от батарейки, но аккумулятору все равно станет нехорошо.
Решение — сразу же, убедившись, что нас включают, а не IWDG зря шум поднимает, инициализируем АЦП (или иное приспособление для мониторинга батареи, например, компаратор) и проверяем, что с зарядом аккумулятора. Если плохо — не пытаемся ничего поднять и включить и сразу уходим в STANDBY. Можно разве что коротко пискнуть пищалкой, если она есть. И только если все в порядке, батарея способна поработать хотя бы несколько минут — включаемся полностью и работаем. Напряжение, ниже которого запрещен запуск, нужно подобрать экспериментально для той батареи, что вы применили. Ну и момент, когда гасить прибор по разряду батареи, следует выбрать с некоторым запасом, не стараясь вытянуть лишние тридцать секунд работы — а чтобы можно было неспешно завершить все дела в этом мире, сохранить настройки в NVRAM или Backup‑регистры RTC, а результаты последних операций на карту памяти, корректно закрыть файлы — и только тогда выключиться, оставив аккумулятор не высосанным в ноль, а с небольшим запасом энергии, который позволит ему благополучно дотянуть до зарядки под нагрузкой в виде RTC и других источников микропотребления.
Третьи грабли: теряем управление
Вы думали, что перейдя в режим STANDBY, МК сохранит состояние ног? Как бы не так! Он их просто бросает, как блондинка из анекдотов — руль. То есть все они оказываются сконфигурированы по умолчанию — как входы, при этом, разумеется, отваливаются и все сконфигурированные ранее внутренние подтяжки.
Следствий этого два: если вы понадеялись на внутренние подтяжки, то зря, в режиме STANDBY их не будет. Если входы имеющейся на плате периферии имеют высокий импеданс и не подтянуты ни к земле, ни к питанию внешними цепями, их состояние окажется непредсказуемым. Вторичные питания, управляемые от контроллера, начнут хаотически включаться и выключаться. Где‑то потечет сквозной ток из‑за того, что напряжение на входе логического элемента оказалось посередине между нулем и единицей. Где-то в углу платы начнет чернеть и обугливаться какой-нибудь резистор. Результат будет мало походить на поведение выключенного прибора и как минимум, он будет бессмысленно пожирать электричество, как максимум — просто не сможет потом корректно включиться (а то и погорит что‑нибудь).
Со входами самого МК та же картина. Входами станут все 144 ноги! Ну, минус питания, земли и вход‑выход кварца. Питание с их логических элементов не будет снято, и все наводки и помехи будут их переключать туда‑сюда. Результатом окажется то, что МК в режиме STANDBY вместо 5 мкА будет потреблять 5 мА.
Решение — ни одного вывода без внешней подтяжки. Куда тянуть — определяется в соответствии с логикой схемы: например, чтобы источники вторичного питания при потере управления отключались, а периферийные устройства переводились в неактивное состояние.
Как справедливо отметил @zurabob,в новых сериях STM32 (в частности, G0) появилась возможность конфигурации внутренних подтяжек и в режиме STANDBY, и этой возможностью нужно воспользоваться.
In the Standby mode, the I/Os can be configured either with a pull-up (refer to PWR_PUCRxregisters (x=A, B, C, D, F), or with a pull-down (refer to PWR_PDCRx registers (x=A, B, C,D, F)), or can be kept in analog mode.
И даже это еще не все. Вас наверняка подстерегут и
Четвертые грабли: паразитное питание
Допустим, ваш прибор имеет на борту дисплей, подключенный по SPI или I2C. Хотя бы «народный» 0,9 или 1,5" OLED на SSD13xx.
Вроде такого, ага.
Допустим, вы по его питанию поставили какой-нибудь ключик типа p-МОП транзистора и решили, что проблем с управлением его питанием у вас больше нет. Но как только вы переведете вашу конструкцию в режим STANDBY, вы обнаружите, что дисплей не погас, а только потускнел, стал неприятно мерцать и постепенно заполняться каким-то мусором.
Что случилось? А случился эффект, про который еще Хоровиц и Хилл писали: КМОП-микросхемы иногда могут успешно работать, получая питание не через штатный вывод для его подачи, а через какой-нибудь сигнальный, связанный в этом случае с шиной питания через защитный диод. Разорвав цепь питания, мы оставили подтянутыми к питанию (см. «Третьи грабли») все интерфейсные линии, идущие к индикатору. Через них на дисплей поступает достаточно питания, чтобы он пытался работать.
Решение — оставляя часть схемы без питания, не забудьте позаботиться и о том, чтобы в нее в это время не заходили и управляющие сигналы. Кстати, это не только к странному поведению и паразитному потреблению может привести — может и сгореть. Защитные диоды на то и защитные, что стоят на крайний случай, а не для штатного их применения и постоянного пропускания через них тока.
* * *
Столько авторов, которые первый раз открыли документацию на вкладке "First steps" и считают, что немедленно обязаны поделиться своими новыми знаниями с окружающим миром. (@lesskop)
Кто-то может сказать, что написал я об общеизвестных вещах. Но лично мне такая инструкция позволила бы сэкономить в свое время массу времени и сил, да и денег, напарываясь на те или иные вроде бы детские ошибки.
Комментарии (46)
viordash
16.11.2024 19:39Если нажали кнопку — вряд ли ту кнопку успеют отпустить за те десятки‑сотни микросекунд, что пройдут от старта МК до запуска функции main(), и мы увидим единицу на PA0.
а если дребезг контакта?
Вроде же есть какие-то флаги источника сброса? Если есть, то лучше их опросить
Sun-ami
16.11.2024 19:39Более интересно, как при таком подходе выключать девайс по длинному нажатию той же кнопки? Ведь по той же причине кнопка будет всё ещё нажатой и при выключении.
jar_ohty Автор
16.11.2024 19:39А она не по уровню включает, а по фронту. Поэтому при долгом нажатии контроллер выключается и, пока кнопку держат, не включается.
zurabob
16.11.2024 19:39Дребезг контактов, при отжатии кнопки будет пачка импульсов, которая включит проц. Поэтому я всегда дожидаюсь окончания дребезга после отпускания и только потом отправляю процессор в спячку или снимаю напряжение с вывода. который управляет ключом питания. Если нет периодических просыпаний по таймеру( или используется RTC и нет отдельного входа батарейки), спокойней и надежней добавить ключ по питанию и аппаратно снимать питание со всей схемы.
Sun-ami
16.11.2024 19:39Это он от кнопки по WakeUp не включается, а что ему мешает включиться от Reset IWDT? Можно, конечно, посмотреть флаги, но ведь вы пишете, что на них нельзя полагаться.
jar_ohty Автор
16.11.2024 19:39Ничего, но если не делать его слишком частым, вероятность случайного попадания срабатывания watchdog-таймера в период нажатия кнопки невелика.
Sun-ami
16.11.2024 19:39В моих проектах период WDT редко больше 1с, часто - около 100 мс, потому что период больше 1с существенно увеличивает время простоя при сбое, перезагрузка занимает как раз около секунды. Они, правда, все без батарейного питания.
jar_ohty Автор
16.11.2024 19:39Есть, но как я заметил в статье, иногда они не срабатывают.
Дребезг случиться может, но он в таком случае сгенерирует следующий фронт и заново включит контроллер. Опыт показывает, что включается контроллер таким образом надежно.
Yuri0128
16.11.2024 19:39Ну опрашиваем 200 мс, - если обнаружен хоть раз высокий уровень - решаем, что разбудили.
gleb_l
16.11.2024 19:39Дребезг - страшная вещь, часто даже непобеждаемая аппаратной и программной логикой. Я помню случай почти 40-летней давности из мира 8080 с контроллером прерываний 8059 - если на один из его входов прикрепить метелку из зачищенного МГТФ, и провести ей по земляной (или питания - не помню уже) шине - то хаотические прерывания намертво вешали систему - несмотря на запрет вложенных прерываний на аппаратном и программном уровне. Стоит сделать источник (даже высокочастотный) из тактируемых ИМС - все работает нормально ;)
jar_ohty Автор
16.11.2024 19:39А уверены, что система вешалась через прерывания? Помню, что спектрумы от подобной пурги, подаваемой просто в порт (например, от клавиатуры) тоже с ума сходили. Плюс еще не-КМОП логика не очень любит, когда ее входы непосредственно сажают на землю или питание, особенно когда это в динамике происходит.
gleb_l
16.11.2024 19:39Был уверен, да. Через буфер-триггер Шмидта вешалось все равно, через буфер + RC-цепь - нет. И если тактировать вход через D-триггер от sysclk - тоже нет.
Это было что-то на уровне логики цифрового автомата внутри контроллера.
vap1977
16.11.2024 19:39Уж не из-за метастабильности триггеров ли это происходило? Входной сигнал, приходящий на триггер очень близко к фронту тактового сигнала, не просто может защелкнуться или так, или иначе, но может еще привести к блуждающему на протяжении иногда даже двух тактов состоянию триггера. Соответственно, когда мы давали уйму сигналов прерывания, вероятность такого "срывания крыши" возрастала. Если так, то и штатная подача асинхронного сигнала на вход прерывания могла привести к некорректному поведению, просто вероятность ниже.
zurabob
16.11.2024 19:39Ничего страшного в дребезге нет, не надо мифологии. Есть начальный дребезг, есть периодический плохой контакт нажатого и есть дребезг отключения. Все это прекрасно распознается и давится программно в биглупе, прерывании по таймеру или отдельной задаче.
Зависоны на длинном проводе вполне возможно были вызваны ESD или индуктивным выбросом на линии, если ток замыкания задран. Небольшой последовательный резистор и емкость/TVS на землю всегда полезны, если рядом есть палец с зарядом тела человека или выход наружу корпуса.
Sergey_datex
16.11.2024 19:39оценивать разряд аккумулятора по его напряжению - плохая идея. 3,2V при +35 градусах и при -15 - совсем разньій уровень заряда, и во втором случае акк еще вполне жив. Не знаю, что посоветовать, наверное просто аппаратньій BOD поставить, отрубающий проц ресетом при просадке. Надеяться на то, что успеешь все записать во все файльі, еепромьі при батарейном питании - нельзя. Потому как достоверно никогда не знаешь, сколько секунд еще будет доступно питание. Вьіход - или делать power-safe запись всего, что обновляет прибор, или ставить power-gauge и мерять реальньій заряд в батарее.
jar_ohty Автор
16.11.2024 19:39Здесь нам не важен уровень заряда, а нужно спрогнозировать, как поведет себя аккумулятор под нагрузкой. При низкой температуре пороговое напряжение будет достигнуто, когда еще в аккумуляторе есть много заряда, но при этом будет и высокое внутреннее сопротивление. Нагружать его в этот момент не стоит. Если уж надо обеспечить надежную работу и включение устройства при минусовых температурах, то да - придется изощряться. Но надо сказать, что у меня несколько приборов используют этот подход, и это работает, в том числе - в полевых условиях, на палубе в Арктике.
gleb_l
16.11.2024 19:39Ну если нужны бронебойные решения для работы в Заполярье, я бы сделал даже программную нагрузочную вилку - скажем нагружать батарею через ключ на полевике на 500 Ом импульсом в пару десятков микросекунд, и смотреть падение, чтобы оценить внутреннее сопротивление.
zurabob
16.11.2024 19:39Либо акк выдает нужное напряжение при токе нагрузки и работать прибор может, либо нет . Поэтому вполне можно по напряжению под нагрузкой быстро оценить возможность включения и принять решение. Запись ессно должна быть с контролем целостности - ну не записалось до конца, просто отбросим.
И если под нагрузкой акк проседает, то это можно запомнить и вообще не пытаться включить нагрузку до начала подзаряда, если его можно определить. При этом акк не высадится окончательно.
nixtonixto
16.11.2024 19:39По неизвестной причине и вопреки документации, после сброса по NRST, IWDG и выхода из STANDBY у многих, если не всех, МК семейства STM32 сохраняется содержимое оперативной памяти
Вообще-то нигде в документации не сказано, что после сброса все ячейки ОЗУ затираются и инициализируются какими-то значениями. Только регистры.
Yuri0128
16.11.2024 19:39Вообще-то для stm32f*** в режиме Standby отключается домен 1.8В, - ну и, как следствие, данные в ОЗУ теряются (там черти-что). В режиме Stop домен не отключается и содержимое ОЗУ сохраняется. Как-бы так.
jar_ohty Автор
16.11.2024 19:39Вот не теряется. Видать, отключается некачественно, возможно - какая паразитная подпитка идет, достаточная для удержания триггеров. Но все это не гарантируется, разумеется. Особенно, как ниже заметили, при переходных процессах. Так что это очень грязный хак и использовать его не надо.
Зато этим методом можно подсмотреть, что осталось в памяти зависшего контроллера.
Yuri0128
16.11.2024 19:39Паразитная подпитка - ну, ежели не теряется, - то наверняка. Памяти по докам достаточно и 1.2 (а в жизни и того меньше), чтобы удержать данные. И ток там мизерный при отсутствие тактирования. Но хак грязный и нету никакой уверености, что в следующей схемотехнике оно бу работать.
Goron_Dekar
16.11.2024 19:39Вот да. Хуже того, иногда при запуске устройства от батарейки или от внешнего БП при засовывании батарейки в гнездо происходит дребезг контактов, способный "передавить" сглаживающий конденсатор БП.
Это может привести к очень интересному поведению: половина оперативной памяти успевает инициализироваться, а половина - нет, и устройство перезагружается с мусором в памяти.
Поэтому хорошим тоном является инициализация всей памяти в коде, а ещё ожидание стабильного питания перед запуском логики МК через механизмы, описанные в этой статье только для аккумуляторного питания.
Gudd-Head
16.11.2024 19:39потребление составляет первые микроамперы
Интересный оборот - первые микроамперы. Но может всё-таки единицы микроампер?
jar_ohty Автор
16.11.2024 19:39Оборот, может быть, чересчур разговорный, но Хабр в общем не предполагает строгого и сухого стиля. А я его к тому же недолюбливаю. Поэтому и позволяю себе написать "первые метры", назвать подножную грязь няшей, изобрести слово "снождь" и т.п. Главное, чтобы не страдала ясность текста, а она, как мне кажется, и не пострадала.
yappari
16.11.2024 19:39Некоторый оффтоп. "Первые" обычно означает наличие процесса (развития, не останавливающегося на этих первых, но по какой-то причине есть необходимость их подчеркнуть), другого употребления лично я что-то не припоминаю.
engin
16.11.2024 19:39STM32F1038T6, во многих отладочных шилдах пин 5 и 7 в параллель осцилятору задекларирована отладочная кнопка Reset - используется для перезагрузки, останавливает выполнение программы и возвращается в исходное состояние, как при первом включении питания.
Основные ее назначение - полезна для начала выполнения кода с самого начала или при зависании если при ошибках, просто для рестарта перед прошивкой.
slog2
16.11.2024 19:39Кто бы ещё подсказал дешёвый способ измерить напряжение аккумулятора. В дешёвых контроллерах внутренней опоры у ацп либо вообще нет, либо точность её совершенно не достаточна для измерения напряжения аккумулятора. Использовал INA219, хороша, но цена нынче не гуманная и не подделку найти шансов мало. Использую как опору TL431, но это +1ма к потреблению.
alcotel
16.11.2024 19:39Сам регулятор напряжения мк. Вы же не от 4,2 В его питаете. 1% точности вполне можно найти
В большинстве stm есть внутренни источник напряжения, с которым можно сравнить питание. Не особо точный, но калибруется
Есть TLV431 и другие его варианты. +0,1ма к потреблению. Ну и его можно выключать, когда не измеряете батарею
VM1989
16.11.2024 19:39Если нужно использовать watchdog в режиме STANDBY, лучше всего просыпаться по таймеру и сбрасывать watchdog, чем каждый раз идти в reset.
Reset от watchdog не должен быть чем-то нормальным, это признак проблемы в работе софта, которую нужно искать.
viordash
16.11.2024 19:39:) а тогда где гарантия что этот таймер спасет при зависании проги? Например после запуска таймера и перед переходом в сон
jar_ohty Автор
16.11.2024 19:39Как сказал Королев, самая надежная деталь - та, которой нет. Переусложнение только "ради фэншуя" (т.к. любой wakeup от таймера действует в STANDBY абсолютно так же, как и IWDT - ресетит МК) ведет лишь к появлению дополнительных точек отказа, да еще и заставляет пробуждать МК чаще, чем это сделал бы IWDT.
StepanovAlex
16.11.2024 19:39А вот в книге "Построение надёжных систем из ненадёжных элементов" доказывается что всё решает структура системы, и при правильной структуре надежность растёт с ростом числа элементов.
vagon333
16.11.2024 19:39... при правильной структуре надежность растёт с ростом числа элементов.
Лукавство.
Вы забыли упомянуть что в книге надежность реализуется за счет избыточности.
Используя методы, аналогичные тем, что применяются в теории связи для коррекции ошибок, фон Нейман продемонстрировал, что надёжность системы может быть значительно повышена за счёт увеличения числа элементов и их правильной организации.
Он разработал схемы, в которых ненадёжные элементы объединяются таким образом, что вероятность отказа всей системы становится сколь угодно малой при увеличении числа элементов и соответствующей структурной конфигурации.
VM1989
16.11.2024 19:39После резета можно из RCC_CSR прочитать о причинах резета. Конечно же, если после прочтения сбрасывать состояние этого регистра (единица в бит RMVF).
Опять же, если из сна нужно выходить часто, то watchdog оправдан. А если нужно сутки спать и две минуты работать, можно перед сном watchdog сбросить. То есть уйти в Software reset, не включить watchdog, уйти в сон. Всяко лучше, чем каждые 32 секунды просыпаться.
jar_ohty Автор
16.11.2024 19:39Разве при этом IWDG останавливается? Всегда считал, что его можно остановить, только обесточив.
Yuri0128
16.11.2024 19:39Выдержка из руководства по IWDG: " Once enabled, it forces the activation of the low-speed internal oscillator, and it can only be disabled by a reset. "
А вот если сделать "Hardware Start" - то не рубится резетом.
blomnik
16.11.2024 19:39А можете прямо сослаться на документацию, где написано, что память не обновляется в STANDBY?
jar_ohty Автор
16.11.2024 19:39Не понял вопрос?
Поведение, прописанное в даташите (для примера, взял STM32F103, следующее:
2.3.11 Voltage regulator
<...>
Power down is used in Standby mode: the regulator output is in high impedance: the kernel circuitry is powered down, inducing zero consumption (but the contents of the registers and SRAM are lost) This regulator is always enabled after reset. It is disabled in Standby mode, providing high impedance output.
2.3.12 Low-power modes
<....>
Standby mode: <...> After entering Standby mode, SRAM and register contents are lost except for registers in the Backup domain and Standby circuitry.
<...>
На практике наблюдается следующее: после сброса любым способом (в том числе и в результате выхода из Standby mode) без отключения питания содержимое памяти остается на месте. Если стартовая процедура не зачищает память или какой-либо ее участок, можно "заглянуть за грань".
zurabob
Это смотря какой STM32. В серии STM32G0 состояние пинов в Standby управляется.
In the Standby mode, the I/Os can be configured either with a pull-up (refer to PWR_PUCRx
registers (x=A, B, C, D, F), or with a pull-down (refer to PWR_PDCRx registers (x=A, B, C,
D, F)), or can be kept in analog mode.
jar_ohty Автор
Да, спасибо за замечание. Про эту возможность я недавно тоже узнал, но поскольку статья долго лежала в черновиках, в нее эта информация не попала.
gleb_l
Эти рекомендации гораздо более глобальные, чем поведение какой-то одной подветки вариантов STM32, и даже более глобальные, чем все STM, вместе взятые. Это фундаментальные правила разведчика, в которых нельзя терять из виду состояние ни одного контролируемого обьекта, и полностью представлять себе, что происходит в моменты входа/выхода из анабиоза, и кто в этот момент контролирует периферию. То, что где-то часть действий можно сделать средствами самого SoC’а, хорошо, но тоже оставляет вопросы - где гарантия, что грязный сброс или уход в полубессознательное состояние после неудачного выхода из стендбая не оставит эти регистры в состоянии мусора? Не говоря уже о том, что защелкнуться через защитные диоды может и сам SoC - и ему точно будет не до контроля других таких же зомби, подвешенных вверх ногами :). А определять потенциал внешними средствами на каждом выводе не то чтобы неохота или дорого (хотя и то, и то правда) - это приведет к существенной толчее на ПП вблизи МК (то есть как раз там, где изящная разводка критична), и может даже к лишним слоям только для того, чтобы сделать систему железобетонно устойчивой к засыпаниям/просыпаниям. В большинстве случаев разработчики просто забьют, и поставят больше аккумулятор, или скажут - автономная работа от батареи - месяц (вместо года), но истинные мастера, конечно, доведут дело до конца.
nixtonixto
Вообще-то состояние и работоспособность ног С13...С15 у всех STM32 сохраняется в любом режиме сна, если они управляются через часовой домен. Это конечно же костыли, как и 20...4к памяти часов, но позволяют даже в STANDBY сохранить минимальный функционал устройства и работу программы.