Перейти к содержанию
    

STM32L151 в режиме STANDBY с RTC

Кто работал с STM32L151 в режиме STANDBY с RTC ?

Никак не удается отладить вход/выход в/из STANDBY при помощи ИАРа и ST-Link/v2

 

Для отладки питаю МК от двух источников: 3В через диод на VDD и 3.3В через ключ на VDD.

Вход в STANDBY в прерывании PVD, который настроен на контроль VDD. Если VDD < 3.1В то прерывание.

Выход из STANDBY по ножке WakeUp2 (PC13), куда подается входное 3.3В.

 

Прерывание PVD нормально работает, но входить в STANDBY контроллер никак не хочет.

Под отладчиком в конце этого прерывания видны команды:

WFI - завалится в спячку

BX LR - return прерывания

 

Так вот отладчик спокойно шагает через WFI к BX LR и прыгает на задачу Idle FreeRTOS и там дальше крутится.

 

з.ы. Watchdog выключен, в RTC источники пробудки запрещены.

 

Что еще нужно сделать??? :smile3046:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Выход из режима StandBy подразумевает ПОЛНЫЙ сброс ядра. Автоматически у Вас должна сброситься отладка.

2. Инструкция WFI без дополнительной настройки отправит ядро в режим сна (Sleep). При этом ядро будет запитано, как и память и вся периферия, а так же источники тактирования.

3. Эпизодически подключеный отладчик может вызывать прерывания типа DebugMon_Handler и что-то похожее. Не углублялся, тут могу ошибиться.

 

Для перехода в режим именно StandBy необходимо:

PWR->CR |= PWR_CR_PDDS;

SCB->SCR |= SCB_SCR_SLEEPDEEP;

PWR->CSR &= ~PWR_CSR_WUF;

И сбросить соответствующие флаги RTC, чтобы контроллер не проснулся сразу же.

 

После выполнения инструкции WFI отладка отвалится!

 

Референс-мануал, глава 5.3.8 - StandBy Mode.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для перехода в режим именно StandBy необходимо: ...

Вроде проштудировал уже все примеры из Куба для отладочных плат. Да и функции применяю из HAL-а. :laughing:

 

После выполнения инструкции WFI отладка отвалится!

Судя по всему при пошаговой отладке в ИАРе команда WFI игнорируется.

Причем как при установленном бите (DBGMCU_CR->DBG_STANDBY) отладки Standby режима, так и при сброшенном.

 

А вот при работе без подключенного отладчика, контроллер по внешним признакам все-таки уходит в спячку, только через 4...10 мс снова просыпается, и так по кругу. Завтра буду дальше разбираться.

 

Дополнительно вопрос:

Кто нибудь пробовал отладку STM32L151 в режиме STANDBY с включенным битом DBGMCU_CR->DBG_STANDBY,

когда тактирование ядра не отключается после команды WFI. Как это должно выглядеть под отладчиком?

Потому что я никак не попадаю на вектор рестарта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот при работе без подключенного отладчика, контроллер по внешним признакам все-таки уходит в спячку, только через 4...10 мс снова просыпается, и так по кругу.

Разобрался в чем дело. Я применил схему из AN4718 How to design a VBAT system based on STM32L0/L1 series. Вариация Case 1b:

post-27881-1522165072_thumb.png

 

Когда я при снижении 3.3В до 3.0В попадал в прерывание и переходил в Standby, уровень на ноге WakeUp был еще высоким и снижался медленно, 20-30 мс. МК переходил в Standby, но событие WakeUp все равно защелкивалось (хотя оно должно быть по фронту, а не по спаду). Но срабатывало пробуждение не сразу, а после какой-то внутренней задержки, связанной с затуханием колебаний на кварце HSE. Поэтому МК будился через 4-10 мс и так по кругу.

 

Пришлось вносить задержку:

влетать в прерывание по падению 3.3В, отключать все по максимуму, переключаться на батарейку,

далее ожидать падение напряжение на ноге WakeUp до уровня нуля цифрового входа,

и только после этого входить в Standby.

 

А по вопросу отладки с режимом Standby с включенным битом DBGMCU_CR->DBG_STANDBY так ничего и не понял.

То ли у меня ИАР очень старый (7.5), то ли так и должно быть...

У меня команда WFI входа в Standby под отладчиком просто игнорируется и дальше получается полная ерунда, которая не наблюдается в нормальном режиме работы. Но отладчик не отваливается, просто ведет себя неадекватно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помнится, при отключеных битах отладочных возможностей, отладка как раз таки будет отваливаться с руганью отладчика, что Target has gone или нечто подобное. Уже не вспомню сообщения Keil'а, но там было предложение прекратить текущую сессию отладки, от которого было невозомжно отказаться (только OK).

 

HAL'ом стараюсь не пользоваться. Больно уж высокоуровневые они функции наворотили, да ещё в индусском стиле.

Частенько у меня их инициализация на 50-100 строк после выпиливания проверок и сведения изменений к одной строке, завершалась за 4-5 строк итогового кода. Соответственно, и работало быстрее и занимало меньше пространства в памяти. А для сборки проекта в RAM это не пустой звук.

 

Эх, надо бы поискать свою отладочную плату с L152. Хотя, там питание я разводил из рук вон плохо (всё соединено в общую линию без всяких заморочек).

 

По поводу битов отладки - глава 30 - Debug Support

Пункт 30.16.1 - Поддержка отладки в режимах низкого потребления.

 

To enter low-power mode, the instruction WFI or WFE must be executed. The MCU implements several low-power modes which can either deactivate the CPU clock or reduce the power of the CPU. The core does not allow FCLK or HCLK to be turned off during a debug session. As these are required for the debugger connection, during a debug, they must remain active. The MCU integrates special means to allow the user to debug software in low-power modes.

 

Для входа в режим низкого потребления, должна быть выполнена инструкция WFI или WFE. В контроллере реализовано несколько маломощных режимов, которые либо отключают тактирования ядра ЦП, или снижают потребляемую мощность. Отладочное ядро не позволяет отключать тактирование FCLK или HCLK во время отладки. Так как они требуются для отладчика в процессе отладки, они должны быть сохранены. Микроконтроллер модержит специальные механихмы, позволяющие пользователю отлаживать код в режиме низкого потребления.

 

 

Bit 2 DBG_STANDBY: Debug Standby mode

0: (FCLK=Off, HCLK=Off) The whole digital part is unpowered. From software point of view, exiting from Standby is identical than fetching reset vector (except a few status bit indicated that the MCU is resuming from Standby)

1: (FCLK=On, HCLK=On) In this case, the digital part is not unpowered and FCLK and HCLK are provided by the internal RC oscillator which remains active. In addition, the MCU generate a system reset during Standby mode so that exiting from Standby is identical than fetching from reset

 

Бит 2.

0 - После инструкции WFI/WFE частоты FCLK, HCLK отключены. Для ПО выход из даннго состояния равносилен переходу на вектор сброса.

1 - В этом случае, цифровая часть НЕ обесточекна и частоты присутствуют и предоставляются внутренним RC-генератором, который остаётся активен. В дополнении, контроллер генерирует системный сброс во время состояния Standby, так что выход из режима ТАК ЖЕ происходит через точку сброса.

 

 

Изменено пользователем AlanDrakes

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помнится, при отключеных битах отладочных возможностей, отладка как раз таки будет отваливаться с руганью отладчика, что Target has gone или нечто подобное. Уже не вспомню сообщения Keil'а, но там было предложение прекратить текущую сессию отладки, от которого было невозомжно отказаться (только OK).

Да, когда биты отладки отключены, при входе в Standby и в ИАРе отладчик гарантированно отваливается и предлагает закрыть сессию.

 

А вот при включенных битах непонятно. Думаю, у меня ИАР старый, не все поддерживает. Додумался добавить после команды WFI вечный цикл while(1); Стало лучше :) По крайней мере больше не попадаю обратно в Idle задачу FreeRTOS.

 

Возникла у меня новая засада. Раньше я отлаживал все с выключенным сторожевиком IWDG. А теперь его включил на период 2 сек. И обнаружил, что после ухода в Standby я через 2 сек просыпаюсь по сторожевику, что логично. Но когда потом снова ухожу в Standby еще до полной инициализации периферии и IWDG, то уже больше не просыпаюсь по сторожевику. Разве это правильно?

Часовой кварц для RTC при этом исправно работает...

 

В документации этот момент описан размыто. В одном месте сказано, что срабатывание IWDG приводит к System Reset. В другом месте сказано, что если IWDG запущен, то остановить его может только ресет (и не указано какого типа!).

Кроме того все форумы пестрят вопросами: "мне нужен Standby с RTC и IWDG, но сторожевик все время будит STM32, как выключить IWDG?" И всегда отвечают: "никак, так и будете периодически будиться".

 

Так при пробуждении из Standby по IWDG_reset сторожевик отключается или нет???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Додумался добавить после команды WFI вечный цикл while(1); Стало лучше :) По крайней мере больше не попадаю обратно в Idle задачу FreeRTOS.
Может я отстал от жизни, но обычно Idle-задача как раз и состоит из единственной команды WFI в бесконечном цикле.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может я отстал от жизни, но обычно Idle-задача как раз и состоит из единственной команды WFI в бесконечном цикле.

Я совсем не знаток FreeRTOS, но у меня включен дефайн configUSE_IDLE_HOOK, поэтому есть мой колбэк Idle, в котором пока ничего нет. А команда WFI в оси наблюдается только в ветке configUSE_TICKLESS_IDLE, но у меня этот дефайн неактивный.

 

Добрался я снова до этой темы, продолжу...

С отладкой в Standby разобрался. При включенных битах отладки все нормально отрабатывается в ИАР, и пробуждение по сторожевику и пробуждение по ноге WakeUp. Главный нюанс в ИАРе - когда МК в Standby, не нажимать на "Стоп" отладчика, а ожидать пробуждения. Если нажать на стоп, то в лучшем случае предлагается закрыть сессию, а в худшем - ИАР тупо без предупреждения закрывается...

 

С работой сторожевика IWDG тоже понятно: если IWDG был включен, то при входе в Standby он продолжает работать до срабатывания. Его собственный ресет выключает генератор LSI и сторожевик и будит МК. После чего можно сторожевик не включать и снова уйти в Standby уже без сторожевика. А можно и включить.

 

Получил следующие токи в Standby:

9.4 мкА = RTC + WDT + Vrefint ON (ULP=0, FWU=0)

4.4 mkA = RTC + WDT - Vrefint OFF (ULP=1, FWU=1)

2.7 mkA = RTC - Vrefint OFF (ULP=1, FWU=1)

 

Очередные проблемы:

Мне не нравиться работа RTC в спячке без сторожевика, потому что пробуждение при этом возможно только по сигналу WakeUp. Если из-за сбоя флаг WakeUp запретится, МК можно будет разбудить только вынимая батарейку :(

 

Поэтому хочется включить IWDG. Но обнаружил, что при пробуждении и засыпании по IWDG, ток потребления по форме напоминает треугольный импульс длительностью около 3 мс и размахом около 0.5 мА

Upd.: при пробуждении каждые 20 сек, батарейки CR2032 на 200мАч хватит на 5 лет. Хочется больше.

 

Что еще можно сделать, чтобы уменьшить статический ток потребления и время пробуждения/засыпания ???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

поэтому есть мой колбэк Idle, в котором пока ничего нет
Вот туда и засунуть WFI. Все равно в IDLE проц будет крутиться до тех пор, пока прерывание не разбудит какую-либо из задач.

 

Что еще можно сделать, чтобы уменьшить статический ток потребления
Поиграться с настройками портов. В том числе и тех ног, которые не выведены наружу в вашем корпусе, но есть на кристалле. С L151 не работал, но в других процессорах (LPC1114, AX8051F143) получал очень хорошую экономию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разбираюсь дальше с этой темой.

Решил посмотреть, как будет работать периодическое пробуждение из Standby при помощи Wake-up таймера RTC.

 

Очередной затык: добился, что под отладчиком, STM32L151 с битом отладки, который запрещает отключение тактирования при уходе в Standby, засыпает и пробуждается каждые 2 сек. Это при отсутствии основного питания и работе от батарейки.

 

Но как только я отключаю отладчик и пытаюсь проделать то-же без него, то улетаю в HardFault.

 

Причем это происходит уже после первого просыпания, в __low_level_init, когда я инициализирую только необходимый минимум для проверки наличия основного питания и ухода в спячку снова.

 

Может ли быть сваливание в HardFault, если я пытаюсь читать какой-нибудь регистр периферии, на который не подано тактирование?

 

Хотя я попадаю в HardFault при переинициализации Wake-up таймера RTC, а RTC при этом справно работает :(

Как это отладить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может ли быть сваливание в HardFault, если я пытаюсь читать какой-нибудь регистр периферии, на который не подано тактирование?
Не должно, в доках пишут, что при этом будут читаться нули.

А проблема с HardFault была из-за моей ошибки - забыл инициализировать один указатель...

 

 

Обнаружил несколько вещей в режиме Standby, не описанных в документации.

Exit from Standby по разным источникам происходит совершенно по-разному.

 

1. Если это просыпание по срабатыванию IWDG, то происходит нормальный System reset с дерганием ножки NRST, очисткой всех регистров, кроме RTC, выключением IWDG и LSI. Просыпание проходит с ожиданием готовности 3ms внутренней опоры Vrefint, независимо от установки бита Fast Wake-Up (FWU) и выключения BOR в Option byte.

 

2. Если это просыпание по срабатыванию RTC Wakeup Timer, то ножка NRST не дергается, генератор LSI не выключается и просыпание происходит быстро, если установлен бит Fast Wake-Up (FWU).

IWDG, если был включен раньше, продолжает работать с прежним делителем. IWDG можно пересбросить или не трогать, и он тогда может досчитать до нуля и сбросить МК как в первом случае.

 

Цифры токов потребления удалось "найти" путем замены вольтметра на другой. Оказалось, что мой бессовестно привирал при измерении в положительную сторону. А в отрицательную сторону измерял нормально.

 

В результате для STM32L151RC получил цифры, которые практически равны типовым значениям из документации.

Везде применялось: VDD=3.0V, ULP=1, FWU=1, LSE=32kHz

В скобках значения из документации (Typ/Max)
0.3 mkA - все выключено           (0.29/0.6 mkA)
1.0 mkA - IWDG + LSI               (1.0/1.7 mkA)
1.1 mkA - RTC + LSI, LSE=Off      (1.15/1.9 mkA)
1.4 mkA - RTC + LSE, LSI=Off       (1.3/--- mkA)
2.0 mkA - RTC + LSE, LSI=ON
2.1 mkA - RTC + LSE, IWDG + LSI
4.4 mkA - RTC + LSE, IWDG + LSI, Vrefint=ON (ULP=0, FWU=0)

Режим с IWDG в документации вообще не отражен, видимо посчитали, что его никто применять не будет.

А я как раз хочу его применить в приборах с "параноидальным" тройным дублированием просыпания. Там, где нет возможности обеспечить доступ к резервной кнопке Reset. При токе 2.1 мкА и периодическим просыпанием по RTC Wakeup Timer каждые 10 сек батарейка CR2032 должна продержаться 10 лет.

 

А дополнительно включенный в спячке IWDG с периодом в 30 сек должен обеспечить дополнительную защиту от вечного сна при сбое всех источников просыпания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...