Предыстория
![](https://habrastorage.org/files/94d/f64/abc/94df64abccc143bc8b13ad62ad2e549b.png)
К делу
Если вам приходилось читать обзоры на современные микроконтроллеры, то вы согласитесь – кроме прочего там будет обязательно сказано о рекордно высокой производительности и о рекордно низком энергопотреблении. Кажется, это просто правило хорошего тона в клубе производителей МК, но случается что и шаблонные фразы маркетологов имеют смысл.
По документации энергопотребление у EFM32 действительно низкое, проверить это на практике можно с помощью утилиты для профилирования энергопотребления микроконтроллеров от Silicon Labs.
![](https://habrastorage.org/files/112/1a6/fe5/1121a6fe53d3451d95a25368884c7483.gif)
Под катом обзор утилиты и практические советы по её использованию.
Аппаратная часть: отладочная плата EFM32WG-STK3800.
Микроконтроллеры EFM32 бывают на базе ядер ARM Cortex-M0+, Cortex-M3 и Cortex-M4 и различаются по набору периферии и объему встроенной памяти. На каждую серию микроконтроллеров приходится отдельная отладочная плата, но все платы очень похожи и отпускаются по цене 42 USD. У меня кит для контроллеров EFM32 Wonder Gecko.
Программная часть: платформа для разработки и отладки проекта Simplicity Studio.
это что-то вроде агрегатора инструментов разработки для микроконтроллеров Silicon Labs (кстати, не только EFM32, но и старых-добрых C8051Fxxx, Zigbee-модулей и др.). Здесь IDE (gnu ARM eclipse), документация и с десяток разных вспомогательных утилит, в том числе искомый Energy Profiler. Полноценный дистрибутив Simplicity Studio (Windows, MAC, Ubuntu) можно скачать бесплатно на сайте silabs.com.
Главное меню Simplicity Studio сразу после установки:
![](https://habrastorage.org/files/daf/740/d1f/daf740d1fa5d4919bb37dd35a93988c1.png)
До подключения отладочной платы доступно относительно мало инструментов, но уже можно немного осмотреться: с левой стороны доступен параметрический поиск по микроконтроллерам (только SiLabs’овским, конечно), в правом верхнем углу три иконки, отвечающие за настройку компонентов, входящих в состав Simplicity Studio. Вообще, программа сама следит за выпуском новых утилит и обновлениями своих компонентов, но настройку можно проводить и вручную.
Чтобы начать работу с платой, достаточно подключить её к компьютеру через USB и выбрать в качестве источника питания платы debug USB (также доступно питание от батарейки и от USB целевого микроконтроллера).
![](https://habrastorage.org/files/e4a/09c/efe/e4a09cefe74140ec948ee25359694625.png)
После подключения плата определяется компьютером и становятся доступны все компоненты, предназначенные для соответствующей серии контроллеров (EFM32WGxxx).
![](https://habrastorage.org/files/58c/fd0/750/58cfd07509b44b37824c85256c416cae.png)
Знакомство проще всего начать с демо-примера, благо их в Simplicity Studio довольно много.
![](https://habrastorage.org/files/91f/2da/6e6/91f2da6e675343499f182db88d756177.png)
Я выбираю один из примеров для EFM32WG-STK3800 — простую программу для работы с LCD-дисплеем — и запускаю её с настройками по умолчанию.
![](https://habrastorage.org/files/f9c/6bc/363/f9c6bc363c1744d8a6b0e91e5b1312f8.png)
Одновременно с запуском программы на микроконтроллере начинается измерение энергопотребления кристалла. В реальном времени строится график зависимости энергопотребления от времени, это, пожалуй, самая наглядная часть профайлера.
Во-первых, на графике видна динамика изменения потребления по ходу исполнения программы. Во-вторых, для выбранной на графике точки и для выбранного отрезка времени доступны точные и средние значения измеряемых показателей.
![](https://habrastorage.org/files/147/1d5/b8b/1471d5b8b75e42cab5389b172e2ca459.png)
* на скриншоте зафиксировн момент, когда включены все доступные функции профайлера. При первом запуске картинка не выглядит так пёстро
Построение графика можно остановить и возобновить, график имеет функцию масштабирования по шкале времени, а по вертикальной оси можно задать как линейный, так и логарифмический масштаб. Логарифмическая шкала – это удобный инструмент для малых токов, однако возможности просто масштабировать график по вертикали всё же иногда не хватает.
Также доступно несколько других полезных функций: отображения на графике входов в обработчики прерываний (разноцветные вертикальные стрелки) и уровня напряжения питания, экспорт результатов измерений в excel и т.д.
Но самое вкусное – это корреляция графика с исполняемым кодом. Если процессорное ядро поддерживает трассировку (подойдут Cortex-M3 и M4), то любой точке на графике Energy Profiler сопоставит строчку кода – по клику на график подсветится строка в листинге справа. Для определения слишком «прожорливых» функций и процедур также служит статистика работы отдельных функций программы — под графиком видно распределение потребленной энергии между ними. Каждой функции можно назначить определенный цвет, тогда на графике будет понятно где она начинает и заканчивает выполняться.
Вся эта красота, если вкратце, реализована следующим образом:
В цепь питания микроконтроллера на отладочной плате встроен измерительный модуль. Через него на компьютер отправляются значения тока и напряжения, а также значение со встроенного на измерительный модуль таймера. Вместе со значением счетчика команд (линия SWO) данные обрабатываются и интерпретируются profiler’ом.
Ток, напряжение и время с начала измерений позволяют построить график зависимости энергопотребления от времени, а значение счетчика команд позволяет соотнести каждую точку с номером строки и названием файла исходного кода.
Energy Profiler использует объектный файл .axf с данными об отладке в формате DWARF (Debug With Arbitrary Record Format), который создается при компиляции проекта в режиме отладки и библиотеки libelf и libdwarf для определения нужной строки в коде.
![](https://habrastorage.org/files/cbd/a2a/96c/cbda2a96c99c42f5aa7d4feb20f529b8.png)
О профилировании собственного проекта
Выше был рассмотрен демо-пример, встроенный в Simplicity Studio. При использовании Energy Profiler подводных камней тоже немного.
Итак, для профилирования собственного проекта нужно находясь в окне Simplicity IDE выполнить следующие действия:
- Добавить в проект функцию настройки трассировки SWOTraceSetup() и вызвать её при инициализации контроллера.
- После компиляции создать новую конфигурацию профайлера:
- меню Run-> ProfilingConfigurations…
- клик на Simplicity Energy Profiler for ARM -> New
- указать файл *.afx в поле Executable
- проверить наличие галочки Enable Code Correlation на вкладке Profiler
SWOTraceSetup()
функцию можно найти в любом примере от производителя, в help-е и ещё много где, но сюда я её тоже добавлю
void BSP_TraceSwoSetup(void)
{
/* Enable GPIO Clock. */
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
/* Enable Serial wire output pin */
GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY) || defined(_EFM32_LEOPARD_FAMILY)
/* Set location 0 */
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC0;
/* Enable output on pin - GPIO Port F, Pin 2 */
GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
#else
/* Set location 1 */
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
/* Enable output on pin */
GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
#endif
/* Enable debug clock AUXHFRCO */
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
/* Enable trace in core debug */
CoreDebug->DHCSR |= 1;
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Enable PC and IRQ sampling output */
DWT->CTRL = 0x400113FF;
/* Set TPIU prescaler to 16. */
TPI->ACPR = 0xf;
/* Set protocol to NRZ */
TPI->SPPR = 2;
/* Disable continuous formatting */
TPI->FFCR = 0x100;
/* Unlock ITM and output data */
ITM->LAR = 0xC5ACCE55;
ITM->TCR = 0x10009;
}
После этого запускать профилирование (с предварительными сборкой и компиляцией проекта и прошивкой микроконтроллера) можно одним кликом.
![](https://habrastorage.org/files/f46/b3e/f75/f46b3ef75d864d3dac0f4d5d6882d5e4.png)
Поскольку утилита использует абсолютные пути к файлам исходного кода, лучше компилировать проект перед каждым профилированием, от греха подальше.
Говоря о настройке трассировки нужно помнить, что для неё используется вспомогательный RC-генератор AUXHFRCO. По идее он настраивается и запускается при выполнении функции настройки трассировки, однако, если предполагается что микроконтроллер часто использует режимы «глубокого сна», в которых отключается в том числе этот вспомогательный генератор, имеют место быть разные глюки. Если используются режимы работы EM2 и ниже, имеет смысл настроить питание AUXHFRCO вручную:
EMU -> CTRL |= _EMU_CTRL_EMVREG_FULL;
Вспомогательный генератор, обеспечивая передачу значения счетчика команд по линии SWO, увеличивает энергопотребление на ~400 мкА и немного зашумляет измерительный канал. Если оптимизация программы закончена и хочется получить точные результаты измерений, следует отключить корреляцию измерений с исполняемым кодом (читай трассировку ядра), т.е. убрать вызов функции SWOTraceSetup().
Профилирование можно проводить и для оригинальной целевой платы, в этом случае SiLabs’овская фирменная плата будет служить измерительным модулем между целевой платой и компьютером. Для этого понадобится:
- Запитать целевую плату от линии VMCU на плате Starter Kit и соединить выводы SWO целевого микроконтроллера и фирменной платы.
- Изменить режим работы платы – с режима отладки микроконтроллера находящегося на плате на работу в режиме внешнего отладчика. Настройка проводится в другой утилите, входящей в состав Simplicity Studio — Kit Manager.
Kit Manager