Power Management часть 1 (перевод из книги Mastering STM32)

Power Management часть 2. Управление питанием в микроконтроллерах STM32F
Power Management часть 3. Управление питанием в микроконтроллерах STM32L
Power Management часть 4. Использование калькулятора энергопотребления CubeMX

Я уже делал перевод одной из глав этой замечательной книги и, судя по просмотрам данной статьи, материал довольно актуален и я решил перевести еще одну главу и чуть позже перевести главу по I2C. В данной статье пойдет речь про энергопотребление микроконтроллеров STM32. Перевод главы будет разбит на несколько частей, потому что глава очень объемная и будет удобно, если разделить ее условно на 4 части: в первой об энергопотреблении в Cortex-M устройствах, во второй и третьей про управление энергопотреблением в STM32F и STM32L сериях микроконтроллеров соответственно и в заключительной главе об использовании режимов энергосбережения на практике.

Нумерация глав в статье соответствует нумерации в книге.

18. Управление энергопотреблением (Power Management)

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

Часто мы думаем, что управление энергопотреблением связано лишь с электропитанием платы. В последние два десятилетия преобразование энергии тема для горячего обсуждения. Исследования и разработки крупных вендоров микроэлекторники породили огромное количество интегральных устройств, дающих возможность увеличить общую энергоэффективность в многих сферах применения, начиная от малопотребляющих устройств и заканчивая высоконагруженными конверторами на ток в сотни ампер. Как embedded разработчики, мы несем ответственность за то, чтобы наши программы минимизировали потребление энергии в устройствах, которые мы создаем.

Современные микроконтроллеры предоставляют разработчикам множество инструментов для минимизации энергопотребления. И семейство Cortex-M не исключение, предоставляя абстрактную модель управления электропитанием, которая может быть переработана конкретным производителем под создание своей собственной схемы питания. И STM32 это как раз тот случай, когда управление питанием присуще всем микроконтроллерам серии STM32, но имеет очень сложную реализацию в семействе STM32L, которая дает разработчикам масштабируемую модель управления питанием, позволяющую достичь наиболее тонкой настройки энергопотребления устройства. Все это позволяет разрабатывать устройства, имеющие возможность работать годы от небольшой батарейки.

В этой главе мы бегло рассмотрим управление энергопотреблением в STM32, проанализируем серию STM32F и STM32L по отдельности. Начнем с обзора реализации в ядре Cortex-M и далее рассмотрим как инженеры ST поработали над этой реализацией, предоставив только в серии STM32L4 до 11 различных режимов энергосбережения.

18.1 Управление энергопотреблением в микроконтроллерах на базе Cortex-M

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

Прежде всего, сложность устройства сама по себе влияет на потребление энергии. Большое количество активной периферии в вашем устройстве подразумевает большее количество необходимой энергии для его питания. Кроме того, некоторые виды периферии весьма требовательны к питанию и энергоёмки. Для примера, TFT дисплеи потребляют большое количество энергии в сравнении с другими компонентами на электронной плате. В конце концов, вопрос энергосбережения подразумевает очень тщательный и продуманный отбор компонентов для разрабатываемого устройства. Для примера, в приложении, где активен RTC (Real-Time Clock) во всех состояниях, включая режим сна (sleep), ожидания (shutdown) и VBAT, потребление тока низкочастотным генератором LSE начинает быть более критичным, чем общее потребление устройства.

Обращая внимание на МК, первым и самым важным аспектом энергопотребления является рабочая частота микроконтроллера: чем она выше, тем больше потребление тока. Это закон «выбитый на камне», который должны знать все разработчики встраиваемых решений: когда, используемый нами микроконтроллер, может работать на частотах до 200 МГц и если у нас нет необходимости в большой скорости, то ради экономии энергии необходимо просто понизить тактовую частоту. И это одна из самых важных причин почему микроконтроллеры STM32 имеют весьма сложную схему настройки тактирования.

Другое следствие данного аспекта то, что чем больше периферии активно тем больше потребление микроконтроллера. Это означает, что хорошо спроектированная прошивка должна немедленно отключать то устройство, которое становится не нужным. Например, если нам нужна память EEPROM по шине I2C во время процесса первоначальной загрузки (поскольку она хранит некоторые параметры конфигурации, которые мы загружаем в ОЗУ на время жизненного цикла прошивки), то после нам нужно отключить I2C периферийное устройство. Это причина, почему микроконтроллеры STM32 предлагают возможность выборочного отключения каждого периферийного устройства, путем вызова

__HAL__RCC_<PPP>_CLK_DISABLE();

где PPP это определенное периферийное устройство. Например,

 __HAL_RCC_DMA1_CLK_DISABLE();

позволяет отключить тактирование DMA1,

__HAL_RCC_DMA1_CLK_ENABLE();

включает его.

Когда мы говорим о микроконтроллерах то лучше говорить об энергоэффективности, нежели о потреблении энергии. В то время как энергопотребление говорит нам о том, сколько мА или мкА потребляет устройство, энергоэффективность измеряет «сколько работы» может выполнить устройство с ограниченным запасом энергии, например, в DMIPS/mW или CoreMark/mW. Таким образом, мы можем обнаружить,что для микроконтроллера STM32L4 наилучший энергетический компромисс достигается, когда он работает в режиме низкого энергопотребления (LPRUN), как показано на рисунке 8.

Наконец, сам дизайн микроконтроллера и его периферийных устройств влияет на общее энергопотребление. Это причина, по которой микроконтроллеры STM32L специально разработаны для обеспечения лучшего в своем классе энергопотребления при одновременном обеспечении наилучших характеристик производительности в соответствии с конкретным семейством микроконтроллеров данной серии. К примеру, некоторые интерфейсы передачи данных микроконтроллера STM32L4 (LPUART один из них) позволяют обмениваться данными в режиме DMA пока микроконтроллер находится в режиме STOP2 (в данном режиме ядро МК потребляет около 1.1мкА).

18.2 Как микроконтроллеры Cortex-M управляют режимами работы и энергосбережения

Когда микроконтроллер на базе Cortex-M перезагружается, его режим питания устанавливается в состояние работы (или по другому Run в англоязычной литературе для микроконтроллеров STM32, тогда как в документации от ARM этот режим называют Active). В данном режиме энергопотребление определяется всей конструкцией микроконтроллера, но в большей степени тактовыми частотами и количеством активной периферии. Здесь важно отметить, что Flash и SRAM память являются также «периферией» по отношению к ядру Cortex-M. Более того, применение передовых технологий предварительной выборки Flash памяти, таких как ускоритель ART TM, также влияет на общее энергопотребление.

В этом режиме разработчик может изменить способ, которым микроконтроллер потребляет энергию, регулируя его тактовую частоту и отключая ненужные периферийные устройства. Это может показаться очевидным, но это важно отметить, потому что во многих практических случаях, это может быть лучшим из способов оптимизации энергопотребления устройства. Как мы увидим позже в этой главе, микроконтроллеры STM32L структурируют режим работы в нескольких подрежимах, предлагая больший контроль над энергопотреблением, гарантируя при этом большинство функциональных возможностей и наилучшую производительность процессора.

Если мы знаем, что для нас нет необходимости ничего обрабатывать в течение определенного периода времени, то ядра Cortex-M позволяют переводить их в спящий режим (Sleep режим) без каких-либо задержек. В этом режиме ядро останавливается и его можно разбудить только «внешним событием», исходящим от EXTI контроллера прерываний (например, кнопкой, подключенной к GPIO). И опять же, микроконтроллеры STM32L расширяют этот режим, предлагая до восьми различных подрежимов, о которых будет написано далее.

Важно подчеркнуть, что ядро Cortex-M входит в спящий режим «на добровольной основе»: две различные инструкции ARM позволяют переводить процессор в спящий режим, оставляя активной реакцию на некоторые события. По запуску этих событий процессор возобновляет выполнение программы в течение некоторого времени пробуждения, которое зависит от уровня режима энергосбережения и типа ядра Cortex-M (M0, M3 и т.д.).

Задержка во времени пробуждения может быть выражена через количество процессорных циклов для «облегченных» режимов сна и в мкс для режимов глубокого сна (deep sleep режимы). Это означает, что чем глубже спящий режим, тем дольше время пробуждения. Разработчик должен решить, какой режим ему следует использовать для конкретного приложения: энергия и время, затрачиваемое на вход и выход из режима глубокого энергосбережения, могут перевесить любые потенциальные выгоды от энергосбережения. Как правило, в носимых устройствах энергоэффективность является наиболее важным фактором, в то время как в большинстве промышленных приложений контроль задержки включения может быть действительно критичным.

Существуют также разные подходы к проектированию систем с низким энергопотреблением. В настоящее время многие встраиваемые системы управляются посредством прерываний. Это значит, что система находится в спящем режиме до тех пор пока нет запросов для обработки. Когда приходит запрос на прерывание, процессор просыпается и обрабатывает его, а после возвращается в спящий режим, когда работа завершена. Как альтернативное решение, если запрос на обработку данных является периодическим и имеет постоянную продолжительность, и если задержка обработки данных не является критической, то вы можете запустить микроконтроллер на самой низкой тактовой частоте для того, чтобы максимально снизить энергопотребление. Нет четкого ответа на вопрос, какой подход лучше, поскольку выбор будет зависеть от требований приложения к обработке данных, используемого микроконтроллера и других факторов, таких как тип источника питания.

Управление режимами работы микроконтроллера STM32
Рисунок 1. Как прошивка МК может потенциально управлять тактовой частотой и режимами питания во время своей работы

На рисунке 1 показана возможная стратегия минимизации энергопотребления. В процессе загрузки микроконтроллера он работает на максимальной тактовой частоте, что позволяет быстро завершить все действия по инициализации. Когда все периферийные устройства сконфигурированы, тактовая частота снижается и микроконтроллер переходит в спящий режим. В этот период микроконтроллер пробуждается прерываниями, которые могут быть обработаны на более низких тактовых частотах. Когда требуется максимальная производительность частота тактирования увеличивается, а после выполнения обработки снова уменьшается.

Итак, когда же все-таки переходить в спящий режим? Как уже было сказано ранее, нам необходимо выбрать правильное время, когда микроконтроллер следует перевести в режим сна. Если мы ждем каких-то асинхронных событий, которые следуют за прерываниями, то лучше перейти в режим ожидания нежели просто ждать события в пустом цикле. Давайте рассмотрим классическое приложение мигания светодиодом.

...
while(1) 
{
  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  HAL_Delay(500);
}

Этот простой с виду код оказывает огромное влияние на энергопотребление нашего микроконтроллера. Даже если нет необходимости слишком много чего делать в течение этих 500 мс, мы тратим много сил, проверяя значение глобального счетчика SysTick, чтобы проверить, прошло ли время задержки. Вместо этого мы можем большую часть времени держать микроконтроллер в спящем режиме, предварительно настроив таймер на прерывание каждые 500мс, которое будет пробуждать наш микроконтроллер.

Разрешение другим программным компонентам решать, когда переводить микроконтроллер в спящий режим, может предоставлять другой подход. В следующей главе мы рассмотрим применение, когда ОСРВ переводит микроконтроллер в спящий режим в случае простоя.

18.2.1 Вход и выход из спящего режима

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

Микроконтроллеры с ядром Cortex-M предлагают две инструкции для перехода в спящий режим: WFI и WFE. Инструкция Wait For Interrupt (WFI) также называется инструкцией безусловного спящего режима. Выполняя данную инструкцию, процессор немедленно останавливает выполнение кода. Его исполнение будет возобновлено только по запросу прерывания, в зависимости от приоритета прерывания и эффективного уровня спящего режима (подробнее об этом позже), также в случае событий отладки. Если прерывание наступает в момент выполнения инструкции WFI, процессор войдет в спящий режим и выйдет из него немедленно в обработчик прерывания.

Инструкция Wait For Event (WFE) еще одна команда, которая переводит процессор в спящий режим. Он отличается от WFI тем, что проверяет состояние определенного регистра событий (этот внутренний регистр недоступен для пользователя) прежде чем остановить ядро: если этот регистр установлен, WFE сбрасывает его и не останавливает работу процессора, продолжая выполнение программы (это позволяет управлять событием ожидания, если необходимо). В противном случае он останавливает процессор, пока этот регистр событий снова не будет установлен.

Но в чем именно разница между событием и прерыванием? События являются источником путаницы в мире STM32 (как и в мире Cortex-M в целом). Они выглядят как нечто нематериальное по сравнению с прерываниями, которые мы научились обрабатывать в главе 7. Прежде чем мы выясним, что такое события, нам нужно лучше объяснить роль контроллера внешних прерываний EXTI в STM32. Расширенный контроллер прерываний и событий (EXTI) является внутренним аппаратным компонентом процессора, который управляет внешними и внутренними асинхронными прерываниями / событиями и генерирует событие запроса для контроллера NVIC и запрос активизации для контроллера питания (Рисунок 2). EXTI позволяет управлять несколькими линиями событий, которые могут вывести процессор из некоторых режимов ожидания (не все события могут пробудить процессор). Линии могут быть конфигурируемыми или прямыми и, следовательно, встроенными в микроконтроллер:

  • Настраиваемые линии: активный фронт может быть выбран независимо, а флаг состояния указывает источник прерывания. Настраиваемые линии используются внешними прерываниями ввода-вывода и несколькими периферийными устройствами (подробнее об этом позже).
  • Прямые линии: они используются некоторыми периферийными устройствами для генерации пробуждения от события остановки или прерывания. Флаг состояния предоставляется самой периферией. Например, RTC может использоваться для генерации события для пробуждения микроконтроллера.
Как события могут быть использованы для пробуждения ядра
Рисунок 2. Как события могут быть использованы для пробуждения ядра

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

Еще один важный аспект, который необходимо прояснить в отношении контроллеров EXTI и NVIC, заключается в том, что каждая строка может маскироваться независимо для прерывания или генерации события. Например, в главе 6 мы видели, что GPIO можно настроить для работы в режиме GPIO_MODE_EVT_ *, который отличается от режима GPIO_MODE_IT_ *: в первом случае, когда на входе срабатывает триггер, он не будет генерировать запрос прерывания, но он установит флаг события. Это приведет к пробуждению микроконтроллера, если он перешел в режим пониженного энергопотребления с использованием инструкции WFE.

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

  • В случае исключения входа/выхода;
  • Когда включена опция SEV-On-Pend, регистр событий может быть установлен когда статус ожидания прерывания меняется с 0 на 1 (подробнее об этом далее);
  • периферийное устройство устанавливает свою выделенную линию событий (это зависит от периферийного устройства);
  • выполнение инструкции SEV (Send Event);
  • событие отладки (например, запрос на остановку выполнения программы).

В главе 7 мы увидели, что в ядрах Cortex-M3/4/7 мы можем временно маскировать выполнение этих прерываний, имеющих приоритет ниже значения, установленного в регистре BASEPRI. Однако эти прерывания все еще включены и помечены как ожидающие, если они срабатывают. Мы можем настроить микроконтроллер для установки регистра событий в случае ожидающих прерываний, установив бит SCR->SEVONPEND. Как следует из названия, этот регистр приведет к «установке регистра событий, если прерывания ожидают». Таким образом, если процессор был переведен в спящий режим по инструкции WFE, он сразу же пробуждается и мы можем в конечном итоге обрабатывать ожидающие прерывания. Вместо этого инструкция WFI никогда не разбудит ядро. Cube HAL предоставляет две удобные функции, HAL_PWR_EnableSEVOnPend() и HAL_PWR_DisableSEVOnPend(), для выполнения этой настройки.

Если вместо этого прерывания маскируются установкой регистра PRIMASK, ожидающее прерывание может разбудить процессор, независимо от используемой команды ожидания (WFI или WFE): эта характеристика позволяет некоторым частям микроконтроллера отключаться программным обеспечением путем отключения тактирования и оно же может включить его после пробуждения перед выполнением ISR.

Итак, подведем итог, WFI и WFE имеют схожее поведение:

  • активируют запросы прерывания / исключения, которые включены и имеют более высокий приоритет, чем текущий уровень;
  • микроконтроллер может быть разбужен событиями отладки;
  • могут быть использованы для создания режимов сна и глубокого сна.

Отличия инструкций WFI и WFE в следующем:

  • выполнение WFE не переводит МК в спящий режим, если установлен внутренний регистр событий, в то время как выполнение WFI всегда включает спящий режим;
  • ожидание отключенного или маскированного прерывания может пробудить процессор от инструкции WFE, если установлен регистр SEVONPEND;
  • WFE может быть разбужен внешним событием;
  • WFI может быть разбужен включенным прерыванием, когда установлен регистр PRIMASK.

18.2.1.1 Sleep-On-Exit

Функция Sleep-On-Exit полезна для приложений, которые управляются прерываниями, где все операции (кроме этапа инициализации) выполняются внутри обработчиков прерываний. Это программируемая функция, которую можно включить или отключить, установив бит регистра SCB->SCR. При включении ядро Cortex-M автоматически переходит в спящий режим (аналогично выполнению инструкции WFI) при выходе из обработчика прерываний. Функция Sleep-On-Exit должна быть включена в конце этапа инициализации. В противном случае, если прерывания происходит во время этапа инициализации, когда функция Sleep-On-Exit уже включена, процессор перейдет в спящий режим, даже если этап инициализации еще не завершен.

CubeHAL предоставляет две удобные процедуры для включения / отключения этого режима: HAL_PWR_EnableSleepOnExit() и HAL_PWR_DisableSleepOnExit().

18.2.2 Режимы сна в микроконтроллерах Cortex-M

До сих пор мы обсуждали спящие режимы. Это в основном потому, что схема управления питанием, определенная ARM, дополнительно специализируется производителем микросхем, как это делает ST со своими продуктами. Микроконтроллеры на базе Cortex-M архитектурно поддерживают два спящих режима: нормальный спящий режим и глубокий спящий режим. Как мы узнаем позже в этой главе, микроконтроллеры STM32F называют их спящим режимом Sleep и режимом остановки Stop соответственно и добавляют третий, еще более глубокий спящий режим, называемый режимом ожидания Standby. Серия STM32L дополнительно расширяет эти два «основных» рабочих режима в нескольких подрежимах.

И режим сна, и режим глубокого сна достигаются с помощью инструкций WFI и WFE, описанных ранее. Единственное отличие состоит в том, что режим глубокого сна достигается установкой бита SLEEPDEEP в 1 в регистре PWR->SCR. Однако обращаться напрямую к регистру нам нет необходимости, поскольку CubeHAL предоставляет инструменты абстракции.

Обычно микроконтроллеры STM32 спроектированы таким образом, что в спящем режиме отключается только тактирование процессора, в то время как другие тактовые сигналы остаются в рабочем режиме (это означает, что все включенные периферийные устройства остаются активными). В режиме остановки все периферийные устройства, с питанием 1,8 В (или 1,2 В для более новых микроконтроллеров STM32), отключаются, а с питанием VDD остаются включенными, за исключением генератора HSI и генератора HSE, которые выключены. В режиме ожидания и те, и другие выключены. Далее все эти моменты будут рассмотрены более подробно.

Один ответ в “Power Management часть 1 (перевод из книги Mastering STM32)”

  1. Большая просьба, если вы заметили ошибку или неточность в переводе, напишите об этом в комментарии, чтобы я мог исправить ее.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *