Комментарии 55
Вы думали, что перейдя в режим STANDBY, МК сохранит состояние ног? Как бы не так! Он их просто бросает, как блондинка из анекдотов — руль.
Это смотря какой 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.
Да, спасибо за замечание. Про эту возможность я недавно тоже узнал, но поскольку статья долго лежала в черновиках, в нее эта информация не попала.
Эти рекомендации гораздо более глобальные, чем поведение какой-то одной подветки вариантов STM32, и даже более глобальные, чем все STM, вместе взятые. Это фундаментальные правила разведчика, в которых нельзя терять из виду состояние ни одного контролируемого обьекта, и полностью представлять себе, что происходит в моменты входа/выхода из анабиоза, и кто в этот момент контролирует периферию. То, что где-то часть действий можно сделать средствами самого SoC’а, хорошо, но тоже оставляет вопросы - где гарантия, что грязный сброс или уход в полубессознательное состояние после неудачного выхода из стендбая не оставит эти регистры в состоянии мусора? Не говоря уже о том, что защелкнуться через защитные диоды может и сам SoC - и ему точно будет не до контроля других таких же зомби, подвешенных вверх ногами :). А определять потенциал внешними средствами на каждом выводе не то чтобы неохота или дорого (хотя и то, и то правда) - это приведет к существенной толчее на ПП вблизи МК (то есть как раз там, где изящная разводка критична), и может даже к лишним слоям только для того, чтобы сделать систему железобетонно устойчивой к засыпаниям/просыпаниям. В большинстве случаев разработчики просто забьют, и поставят больше аккумулятор, или скажут - автономная работа от батареи - месяц (вместо года), но истинные мастера, конечно, доведут дело до конца.
Вообще-то состояние и работоспособность ног С13...С15 у всех STM32 сохраняется в любом режиме сна, если они управляются через часовой домен. Это конечно же костыли, как и 20...4к памяти часов, но позволяют даже в STANDBY сохранить минимальный функционал устройства и работу программы.
Если нажали кнопку — вряд ли ту кнопку успеют отпустить за те десятки‑сотни микросекунд, что пройдут от старта МК до запуска функции main(), и мы увидим единицу на PA0.
а если дребезг контакта?
Вроде же есть какие-то флаги источника сброса? Если есть, то лучше их опросить
Более интересно, как при таком подходе выключать девайс по длинному нажатию той же кнопки? Ведь по той же причине кнопка будет всё ещё нажатой и при выключении.
А она не по уровню включает, а по фронту. Поэтому при долгом нажатии контроллер выключается и, пока кнопку держат, не включается.
Дребезг контактов, при отжатии кнопки будет пачка импульсов, которая включит проц. Поэтому я всегда дожидаюсь окончания дребезга после отпускания и только потом отправляю процессор в спячку или снимаю напряжение с вывода. который управляет ключом питания. Если нет периодических просыпаний по таймеру( или используется RTC и нет отдельного входа батарейки), спокойней и надежней добавить ключ по питанию и аппаратно снимать питание со всей схемы.
Это он от кнопки по WakeUp не включается, а что ему мешает включиться от Reset IWDT? Можно, конечно, посмотреть флаги, но ведь вы пишете, что на них нельзя полагаться.
Ничего, но если не делать его слишком частым, вероятность случайного попадания срабатывания watchdog-таймера в период нажатия кнопки невелика.
Есть, но как я заметил в статье, иногда они не срабатывают.
Дребезг случиться может, но он в таком случае сгенерирует следующий фронт и заново включит контроллер. Опыт показывает, что включается контроллер таким образом надежно.
Ну опрашиваем 200 мс, - если обнаружен хоть раз высокий уровень - решаем, что разбудили.
Дребезг - страшная вещь, часто даже непобеждаемая аппаратной и программной логикой. Я помню случай почти 40-летней давности из мира 8080 с контроллером прерываний 8059 - если на один из его входов прикрепить метелку из зачищенного МГТФ, и провести ей по земляной (или питания - не помню уже) шине - то хаотические прерывания намертво вешали систему - несмотря на запрет вложенных прерываний на аппаратном и программном уровне. Стоит сделать источник (даже высокочастотный) из тактируемых ИМС - все работает нормально ;)
А уверены, что система вешалась через прерывания? Помню, что спектрумы от подобной пурги, подаваемой просто в порт (например, от клавиатуры) тоже с ума сходили. Плюс еще не-КМОП логика не очень любит, когда ее входы непосредственно сажают на землю или питание, особенно когда это в динамике происходит.
Был уверен, да. Через буфер-триггер Шмидта вешалось все равно, через буфер + RC-цепь - нет. И если тактировать вход через D-триггер от sysclk - тоже нет.
Это было что-то на уровне логики цифрового автомата внутри контроллера.
Уж не из-за метастабильности триггеров ли это происходило? Входной сигнал, приходящий на триггер очень близко к фронту тактового сигнала, не просто может защелкнуться или так, или иначе, но может еще привести к блуждающему на протяжении иногда даже двух тактов состоянию триггера. Соответственно, когда мы давали уйму сигналов прерывания, вероятность такого "срывания крыши" возрастала. Если так, то и штатная подача асинхронного сигнала на вход прерывания могла привести к некорректному поведению, просто вероятность ниже.
Ничего страшного в дребезге нет, не надо мифологии. Есть начальный дребезг, есть периодический плохой контакт нажатого и есть дребезг отключения. Все это прекрасно распознается и давится программно в биглупе, прерывании по таймеру или отдельной задаче.
Зависоны на длинном проводе вполне возможно были вызваны ESD или индуктивным выбросом на линии, если ток замыкания задран. Небольшой последовательный резистор и емкость/TVS на землю всегда полезны, если рядом есть палец с зарядом тела человека или выход наружу корпуса.
оценивать разряд аккумулятора по его напряжению - плохая идея. 3,2V при +35 градусах и при -15 - совсем разньій уровень заряда, и во втором случае акк еще вполне жив. Не знаю, что посоветовать, наверное просто аппаратньій BOD поставить, отрубающий проц ресетом при просадке. Надеяться на то, что успеешь все записать во все файльі, еепромьі при батарейном питании - нельзя. Потому как достоверно никогда не знаешь, сколько секунд еще будет доступно питание. Вьіход - или делать power-safe запись всего, что обновляет прибор, или ставить power-gauge и мерять реальньій заряд в батарее.
Здесь нам не важен уровень заряда, а нужно спрогнозировать, как поведет себя аккумулятор под нагрузкой. При низкой температуре пороговое напряжение будет достигнуто, когда еще в аккумуляторе есть много заряда, но при этом будет и высокое внутреннее сопротивление. Нагружать его в этот момент не стоит. Если уж надо обеспечить надежную работу и включение устройства при минусовых температурах, то да - придется изощряться. Но надо сказать, что у меня несколько приборов используют этот подход, и это работает, в том числе - в полевых условиях, на палубе в Арктике.
Либо акк выдает нужное напряжение при токе нагрузки и работать прибор может, либо нет . Поэтому вполне можно по напряжению под нагрузкой быстро оценить возможность включения и принять решение. Запись ессно должна быть с контролем целостности - ну не записалось до конца, просто отбросим.
И если под нагрузкой акк проседает, то это можно запомнить и вообще не пытаться включить нагрузку до начала подзаряда, если его можно определить. При этом акк не высадится окончательно.
По неизвестной причине и вопреки документации, после сброса по NRST, IWDG и выхода из STANDBY у многих, если не всех, МК семейства STM32 сохраняется содержимое оперативной памяти
Вообще-то нигде в документации не сказано, что после сброса все ячейки ОЗУ затираются и инициализируются какими-то значениями. Только регистры.
Вообще-то для stm32f*** в режиме Standby отключается домен 1.8В, - ну и, как следствие, данные в ОЗУ теряются (там черти-что). В режиме Stop домен не отключается и содержимое ОЗУ сохраняется. Как-бы так.
Вот не теряется. Видать, отключается некачественно, возможно - какая паразитная подпитка идет, достаточная для удержания триггеров. Но все это не гарантируется, разумеется. Особенно, как ниже заметили, при переходных процессах. Так что это очень грязный хак и использовать его не надо.
Зато этим методом можно подсмотреть, что осталось в памяти зависшего контроллера.
Вот да. Хуже того, иногда при запуске устройства от батарейки или от внешнего БП при засовывании батарейки в гнездо происходит дребезг контактов, способный "передавить" сглаживающий конденсатор БП.
Это может привести к очень интересному поведению: половина оперативной памяти успевает инициализироваться, а половина - нет, и устройство перезагружается с мусором в памяти.
Поэтому хорошим тоном является инициализация всей памяти в коде, а ещё ожидание стабильного питания перед запуском логики МК через механизмы, описанные в этой статье только для аккумуляторного питания.
потребление составляет первые микроамперы
Интересный оборот - первые микроамперы. Но может всё-таки единицы микроампер?
Оборот, может быть, чересчур разговорный, но Хабр в общем не предполагает строгого и сухого стиля. А я его к тому же недолюбливаю. Поэтому и позволяю себе написать "первые метры", назвать подножную грязь няшей, изобрести слово "снождь" и т.п. Главное, чтобы не страдала ясность текста, а она, как мне кажется, и не пострадала.
STM32F1038T6, во многих отладочных шилдах пин 5 и 7 в параллель осцилятору задекларирована отладочная кнопка Reset - используется для перезагрузки, останавливает выполнение программы и возвращается в исходное состояние, как при первом включении питания.
Основные ее назначение - полезна для начала выполнения кода с самого начала или при зависании если при ошибках, просто для рестарта перед прошивкой.
Кто бы ещё подсказал дешёвый способ измерить напряжение аккумулятора. В дешёвых контроллерах внутренней опоры у ацп либо вообще нет, либо точность её совершенно не достаточна для измерения напряжения аккумулятора. Использовал INA219, хороша, но цена нынче не гуманная и не подделку найти шансов мало. Использую как опору TL431, но это +1ма к потреблению.
Сам регулятор напряжения мк. Вы же не от 4,2 В его питаете. 1% точности вполне можно найти
В большинстве stm есть внутренни источник напряжения, с которым можно сравнить питание. Не особо точный, но калибруется
Есть TLV431 и другие его варианты. +0,1ма к потреблению. Ну и его можно выключать, когда не измеряете батарею
От 4.2 и питаю. Если проц позволяет то зачем лишний стабилизатор. Если питать от 3,3в то всё ломается при разряжающемся аккуме. Так себе вариант.
Есть не везде. Калибровка лишняя операция. При прошивке может слететь.
На мой взгляд пока что самый годный вариант.
Если речь о STM32 и вообще любых других трехвольтовых -- их выше 3,6 В нельзя. Возможно, работать будет, может даже и долго -- но может и не повезти.
Много контролеров допускают питание от +5 речь про них, а не про STM32. C питанием 3,3в контроллеров от лития много лишних проблем, тут надо думать стоит ли использовать STM32 если питание от одного литиевого элемента.
Зачем же 3,3 ? Из литиевого напряжения удобнее 2,5V получать.
Но я не знаю вашей задачи. Так бы ещё вариантов накидал
Взять другой контроллер. Если мк не может сам измерить напряжение батареи, возможно, он не проектировался под батарейное питание.
Поискать у китайцев, на LCSC, например. Китайцы дофига всего наделали, и скорее всего найдётся чип, который и заряд измерит, и ещё зарядит, и напряжение преобразует... Разве что
не отсосётборщ не сварит)
А зачем? Разряжать литий ниже 3,4 В смысла мало, там между 3,4 и 3,0 энергии кот наплакал. Поставить LM3671 - проще некуда, у нее ток холостого хода ничтожно мал (14, что ли микроампер), и во всем диапазоне полезных напряжений лития 3,3 В на выходе стоять будет мертво. И умеет переключаться в режим байпаса при напряжении на входе, равном или ниже 3,3 В.
Иногда битва идёт за микроамперы и часы работы, а вы сразу 0,4в предлагаете выкинуть. LM3671 хорошая штука, только вот нынче с ценой и доступностью не всё хорошо.
Иногда битва идёт за микроамперы и часы работы, а вы сразу 0,4в предлагаете выкинуть. LM3671 хорошая штука, только вот нынче с ценой и доступностью не всё хорошо.
Я не про какую-то конкретную задачу, их много разных. Из лития надо делать 3.0в для питания контроллера. А это потери на кпд стабилизатора. Какой будет лучше линейный или импульсный вообще не всегда сразу очевидно. Даже возможно иногда 5в контроллер стоит питать от 3в потому что при этом потребление будет меньше, даже с учетом потерь в стабилизаторе.
Если нужно использовать watchdog в режиме STANDBY, лучше всего просыпаться по таймеру и сбрасывать watchdog, чем каждый раз идти в reset.
Reset от watchdog не должен быть чем-то нормальным, это признак проблемы в работе софта, которую нужно искать.
:) а тогда где гарантия что этот таймер спасет при зависании проги? Например после запуска таймера и перед переходом в сон
Как сказал Королев, самая надежная деталь - та, которой нет. Переусложнение только "ради фэншуя" (т.к. любой wakeup от таймера действует в STANDBY абсолютно так же, как и IWDT - ресетит МК) ведет лишь к появлению дополнительных точек отказа, да еще и заставляет пробуждать МК чаще, чем это сделал бы IWDT.
А вот в книге "Построение надёжных систем из ненадёжных элементов" доказывается что всё решает структура системы, и при правильной структуре надежность растёт с ростом числа элементов.
... при правильной структуре надежность растёт с ростом числа элементов.
Лукавство.
Вы забыли упомянуть что в книге надежность реализуется за счет избыточности.
Используя методы, аналогичные тем, что применяются в теории связи для коррекции ошибок, фон Нейман продемонстрировал, что надёжность системы может быть значительно повышена за счёт увеличения числа элементов и их правильной организации.
Он разработал схемы, в которых ненадёжные элементы объединяются таким образом, что вероятность отказа всей системы становится сколь угодно малой при увеличении числа элементов и соответствующей структурной конфигурации.
После резета можно из RCC_CSR прочитать о причинах резета. Конечно же, если после прочтения сбрасывать состояние этого регистра (единица в бит RMVF).
Опять же, если из сна нужно выходить часто, то watchdog оправдан. А если нужно сутки спать и две минуты работать, можно перед сном watchdog сбросить. То есть уйти в Software reset, не включить watchdog, уйти в сон. Всяко лучше, чем каждые 32 секунды просыпаться.
Разве при этом IWDG останавливается? Всегда считал, что его можно остановить, только обесточив.
А можете прямо сослаться на документацию, где написано, что память не обновляется в STANDBY?
Не понял вопрос?
Поведение, прописанное в даташите (для примера, взял 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) без отключения питания содержимое памяти остается на месте. Если стартовая процедура не зачищает память или какой-либо ее участок, можно "заглянуть за грань".
STM32 — грамотно включаемся от кнопки