Предыстория


Два года назад компания Silicon Labs поглотила очередную компанию поменьше – на этот раз норвежского производителя малопотребляющих ARM-контроллеров EnergyMicro. С тех пор SiLabs активно развивает и продвигает микроконтроллеры серии EFM32 со смешной ящерицей на корпусе.

К делу


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

По документации энергопотребление у EFM32 действительно низкое, не хуже чем у популярных MSP430 и STM32. Лично мне убедиться в этом помогла утилита для профилирования энергопотребления от Silicon Labs.



Под катом обзор утилиты и практические советы по её использованию.

Аппаратная часть: отладочная плата EFM32WG-STK3800.
Микроконтроллеры EFM32 бывают на базе ядер ARM Cortex-M0+, Cortex-M3 и Cortex-M4 и различаются по набору периферии и объему встроенной памяти. На каждую серию микроконтроллеров приходится отдельная отладочная плата, но все платы очень похожи. У меня кит для контроллеров EFM32 Wonder Gecko, в РФ можно купить за $30-50.

Программная часть: платформа для разработки и отладки проекта Simplicity Studio.
это что-то вроде агрегатора инструментов разработки для микроконтроллеров Silicon Labs (кстати, не только EFM32, но и старых-добрых C8051Fxxx, Zigbee-модулей и др.). Здесь IDE (gnu ARM eclipse), документация и с десяток разных вспомогательных утилит, в том числе искомый Energy Profiler. Полноценный дистрибутив Simplicity Studio (Windows, MAC, Ubuntu) можно скачать бесплатно на сайте silabs.com.

Главное меню Simplicity Studio сразу после установки:



До подключения отладочной платы доступно относительно мало инструментов, но уже можно немного осмотреться: с левой стороны доступен параметрический поиск по микроконтроллерам (только SiLabs’овским, конечно), в правом верхнем углу три иконки, отвечающие за настройку компонентов, входящих в состав Simplicity Studio. Вообще, программа сама следит за выпуском новых утилит и обновлениями своих компонентов, но настройку можно проводить и вручную.

Чтобы начать работу с платой, достаточно подключить её к компьютеру через USB и выбрать в качестве источника питания платы debug USB (также доступно питание от батарейки и от USB целевого микроконтроллера).



После подключения плата определяется компьютером и становятся доступны все компоненты, предназначенные для соответствующей серии контроллеров (EFM32WGxxx).



Знакомство проще всего начать с демо-примера, благо их в Simplicity Studio довольно много.



Я выбираю один из примеров для EFM32WG-STK3800 простую программу для работы с LCD-дисплеем и запускаю её с настройками по умолчанию.



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

Во-первых, видна сама динамика изменения потребления по ходу исполнения программы. Во-вторых, для выбранной на графике точки и для отрезка времени доступны точные и средние значения изменяемых показателей.


* на скриншоте все возможные функции профайлера включены, при запуске это выглядит не так пёстро

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

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

Но самое вкусное – это корреляция графика с исполняемым кодом. Если процессорное ядро поддерживает трассировку (подойдут Cortex-M3 и M4), то любой точке на графике Energy Profiler сопоставит строчку кода – по клику на график подсветится строка в листинге справа. Для определения слишком «прожорливых» функций и процедур также служит часть профайлера, собирающая статистику по работе отдельных функций программы — под графиком доступно распределение потребленной энергии по исполняемым функциям. Каждой функции можно назначить определенный цвет, тогда на графике будет понятно где она начинает и заканчивает выполняться.

Вся эта красота, если вкратце, реализована следующим образом:
В цепь питания микроконтроллера на отладочной плате встроен измерительный модуль. Через него на компьютер отправляются значения тока и напряжения, а также значение со встроенного на измерительный модуль таймера. Вместе со значением счетчика команд (линия микроконтроллера SWO) данные обрабатываются и интерпретируются profiler’ом.

Ток, напряжение и время с начала измерений позволяют построить график зависимости энергопотребления от времени, а значение счетчика команд позволяет соотнести его с номером строки и название файла исходного кода.

Energy Profiler использует объектный файл .axf с данными об отладке в формате DWARF (Debug With Arbitrary Record Format), который создается при компиляции проекта в режиме отладки и библиотеки libelf и libdwarf для определения искомой строки в коде.



О профилировании собственного проекта


Подводных камней при использовании Energy Profiler немного.
Для собственного проекта на Си при первом профилировании находясь в окне Simplicity IDE нужно:
  1. Добавить в проект функцию настройки трассировки SWOTraceSetup() и вызвать её при инициализации контроллера.
  2. После компиляции создать новую конфигурацию профайлера:
    • меню 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;
}


После этого запускать профилирование (с предварительными сборкой и компиляцией проекта и прошивкой микроконтроллера) можно одним кликом.



Поскольку утилита использует абсолютные пути к файлам исходного кода, лучше компилировать проект перед каждым профилированием, от греха подальше.
Говоря о настройке трассировки нужно помнить, что для неё используется вспомогательный RC-генератор AUXHFRCO. По идее он настраивается и запускается при выполнении функции настройки трассировки, однако, если предполагается что микроконтроллер часто использует режимы «глубокого сна», в которых отключается в том числе этот вспомогательный генератор, имеют место быть разные глюки. Если используются режимы работы EM2 и ниже, имеет смысл настроить питание AUXHFRCO вручную:

EMU -> CTRL |= _EMU_CTRL_EMVREG_FULL; 

Вспомогательный генератор, обеспечивая передачу значения счетчика команд по линии SWO, увеличивает энергопотребление на ~400 мкА и немного зашумляет измерительный канал. Если оптимизация программы закончена и хочется получить точные результаты измерений, следует отключить корреляцию измерений с исполняемым кодом (читай трассировку ядра), т.е. убрать вызов функции SWOTraceSetup().

Профилирование можно проводить и для оригинальной целевой платы, в этом случае SiLabs’овская фирменная плата будет служить измерительным модулем между целевой платой и компьютером. Для этого понадобится:
  • Запитать целевую плату от линии VMCU на плате Starter Kit и соединить выводы SWO целевого микроконтроллера и фирменной платы.
  • Изменить режим работы платы – с режима отладки микроконтроллера находящегося на плате на работу в режиме внешнего отладчика. Настройка проводится в другой утилите, входящей в состав Simplicity Studio — Kit Manager.

    Kit Manager

Комментарии (4)


  1. Pugnator
    08.05.2015 02:40

    Всегда было интересно, какой усилитель токового шунта лучше всего подойдет для таких целей — самоконтроль в устройстве с батарейным питанием и очень малым потреблением, скажем, от микроампер до единиц миллиампер.


    1. uuuulala Автор
      08.05.2015 11:35
      +1

      Про «лучше всего» не скажу, но на этой плате стоит измеритель тока LTC6102CDD и два усилителя AD8656ARMZ — один для токов до 200 мкА, другой для токов выше 200 мкА. Схемотехника по ссылке (см. раздел AEM Current Measurement).


  1. k0ldbl00d
    08.05.2015 08:51
    +1

    Долго думал что за Девид-интерфейс на третьей иллюстрации.


    1. uuuulala Автор
      08.05.2015 11:48

      и как успехи?)