STM32MP1 — ядра + Linux = идеальный микроконтроллер +19





По роду своей деятельности занимаюсь разработкой различных приборов: измерительных, управляющих, контролирующих и т.п. В подавляющем большинстве устройство делится на 2 части:

  1. Требующий больших ресурсов микроконтроллера и не требующий жесткого реального времени графический интерфейс пользователя (GUI).
  2. Потребляющая немного ресурсов и работающая в жестком реальном времени аппаратная часть прибора.

И как правило, переход на новую серию микроконтроллеров определялся улучшением GUI: больше цветов, выше разрешение, более сложные элементы дизайна. Одно время была мысль использовать в качестве графического интерфейса какую-нибудь плату Raspberry.

Но с появлением у STM новой линейки микроконтроллеров STM32MP1 мои терзания закончились и вот что пока получилось.

Идеальный контроллер


Идеальный контроллер для меня должен обладать следующими характеристиками:

  • иметь приличные графические возможности, такие как простая поддержка различных графических форматов, поддержка векторных шрифтов
  • большой объем памяти для графики
  • поддержка USB клавиатуры и мышей
  • поддержка Ethernet
  • большое количество аппаратных таймеров
  • генерация ШИМ
  • большое количество GPIO
  • 16 разрядный АЦП

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

И поэтому я очень обрадовался увидев новый серию от STM: STM32MP1.

Первое знакомство


Для ознакомления с новым чипом была приобретена плата STM32MP157C-DK2. Вот такая (фото из инета):



Демоплата построена на кристалле STM32MP157CAC, который имеет в своем составе:

  • 2 ядра А7, по 650 МГц
  • 1 ядро М4, 208 МГц

Память


Самое первое отличие, которое бросается в глаза — это отсутствие флеш памяти на кристалле. Для ядра А7, которое по сути микропроцессор, это нормальная ситуация и код всегда выполняется из DRAM. Микроконтроллеры на основе М4, обычно имеют в своем составе флеш память, в которой хранится исполняемый код.

В этом кристалле у ядра М4 есть только оперативная память и код выполняется из нее (из даташита):

708 Kbytes of internal SRAM: 256 Kbytes of
AXI SYSRAM + 384 Kbytes of AHB SRAM +
64 Kbytes of AHB SRAM in Backup domain
and 4 Kbytes of SRAM in Backup domain

Ядро А7 имеет встроенный контроллер DDR (из даташита):
The STM32MP157C/F devices embed a controller for external SDRAM which support the
following devices:

  • LPDDR2 or LPDDR3, 16- or 32-bit data, up to 1 Gbyte, up to 533 MHz clock.
  • DDR3 or DDR3L, 16- or 32-bit data, up to 1 Gbyte, up to 533 MHz clock.

С одной стороны памяти у ядра M4 вроде бы меньше, чем у версии в флеш памятью, но с другой стороны RAM память работает на частоте ядра. Флеш память так не может, и там приходится использовать делитель частоты.

Организация рабочего места


Поскольку для работы с платой необходим Линукс, то пришлось установить дополнительный жесткий диск в свой комп и развернуть на нем Ubuntu 16.04. Эту ОС рекомендует STM.

Engineering & Production mode


Плата может стартовать в одном из двух режимов (определяется дип-свитчем). В режиме Engineering, ядро М4 работает обособленно. В Production mode ядро М4 работает под управлением ядра А7. Я не использовал режим Engineering, работал только в режиме Production. В этом режиме можно не заботиться о настройке тактирования ядер. Тактирование настраивается в процессе загрузки по максимальным величинам. Я проверил несколько регистров в отладчике, вывел часть частот на MCO и посмотрел осциллографом. A7 работает на частоте 650 МГц, М4 на частоте 208 МГц.

Ядро М4. Загрузка и запуск программ


Поскольку ядро М4 работает под управлением А7, значит под управлением OpenSTLinux. Для управления ядром М4 используется Linux remoteproc framework (RPROC). Этот фреймворк позволяет включать и отключать ядра, загружать и отлаживать программное обеспечение(ELF файлы).

Для загрузки программы в ядро M4 служит следующая команда:

echo -n <firmware_name.elf> > /sys/class/remoteproc/remoteproc0/firmware

Для старта программы:

echo start >/sys/class/remoteproc/remoteproc0/state

Для останова:

echo stop >/sys/class/remoteproc/remoteprocX/state

Ядро М4. SW4STM32


Выше упомянутые команды были опробованы, все работает :) Но для работы нужна какая-нибудь нормальная IDE. STM рекомендует для этого использовать софт компании AC6 SW4STM32. При этом на сайте OpenSTM32 есть очень классный заголовок:
With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world.
And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
То есть можно писать код как для ядра м4, так и для А7. Но это платная версия. А бесплатная, которая доступна для скачивания, позволяет писать и отлаживать код только для ядра М4.

IDE SW4STM32 была скачана, установлена и попробована. Все работает, процесс написания и компиляции не отличается от версии в Windows.
Отличается только загрузка кода и отладка, поскольку для записи софта используется Ethenet и соединение по SSH. Для отладки и остановки по точкам используется встроенный на плате ST LINK.

Ядро А7. Кросс-компилятор


Для компиляции программ на ПК STM предлагает кросс-компилятор. Процесс загрузки и запуска скрипта кросс-компилятора подробно описан в Вики STM32MP1, ссылка ниже. Все было сделано согласно инструкции, все работает как надо. :)

Запуск кросс-компилятора для экосистемы v1.1.0:

source SDK/environment-setup-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi
ну далее команда
make
и исходный код, в соответствии с makefile, скомпилируется в коды ARM :)

Ядро А7. Загрузка и запуск программ


Чтобы загрузить программу в демо плату используется команда:

scp gtk_hello_world root@192.168.1.18:/usr/local

Эта команда загружает файл gtk_hello_world в раздел /usr/local, который находится на плате с IP адресом: 192.168.1.18. Root — пароль, который стоит на плате по умолчанию.

Обмен данными между ядрами


Больше всего времени ушло на понимание работы механизма обмена данными между ядрами. В примерах, которые поставляются STM, есть несколько вариантов реализации подобного обмена. Можно работать напрямик с драйвером из OpenSTLinux или использовать механизм виртуальных UARTов. Я решил сделать обмен через виртуальные порты, как более простой.

Со стороны Линукс это выглядит так:

Открываем устройство:

fd = open("/dev/ttyRPMSG0", O_RDWR);

Потом пишем в него или читаем:

write(fd, «LED_Toggle\r\0», 10);
len = read( fd, buf, sizeof(buf));

Все достаточно просто, но есть маленький нюанс. Чтобы появилось устройство ttyRPMSG0, нужно чтобы ядро М4 обратилось к ядру А7 в таком виде:

это строки кода ядра М4:

VIRT_UART_Init(&huart0); //регистрация виртуального порта
VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) //регистрация и выделение памяти для приемного буфера.

Прием данных из виртуального порта ядром М4:

if (VirtUart0RxMsg)
{
      //обработка данных во входном буфере VirtUart0ChannelBuffRx
     
      VirtUart0RxMsg = 0;
}

Запись данных в виртуальный порт:

VIRT_UART_Transmit(&huart0, TxArray, TXCounter);

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

Весь этот механизм реализуется набором сторонних библиотек OpenAMP. Эта библиотека должна быть включена в проект ядра М4 и соответственно проинициализирована.

Дальнейшие планы


Установить и настроить Eclipse для написания и отладки кода для А7.
Написать нормальное графическое демо, типа осцилоскопа из АЦП М4.
И наконец, сделать свою плату контроллера на основе этого чипа. :)

Полезные ссылки

Wiki STM32MP1
OpenSTM32
ST Community
AC6

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (29):

  1. zedroid
    /#21426468

    Слой yocto для проца есть? Портирован ли qt? И в чем GUI обычно пишете?

    • sanders1967
      /#21426476

      Yocto — есть, qt — не знаю, GUI — планирую писать на Glade :)

  2. GarryC
    /#21426496 / +1

    10+ баксов, необходимость внешней памяти и внешнего флэша — я не уверен, что это станет моим любимым контроллером.

    • sanders1967
      /#21426528

      У всех свой идеальный контроллер :)

    • NordicEnergy
      /#21430694

      10+ баксов стоят и старшие камни F7 и H7, вряд ли дело в цене. Вообще есть SiP от Octavo на AM3358, там и проц, и озу, и флеша, и питание, а самое главное корпус bga с шагом 1 мм. Вот такой подход можно назвать «идеальным», но пока выбор их не велик, хотелось бы чего-то такого с i.MX8 внутри что ли

  3. mcu_by
    /#21426510 / +1

    1. stm32mp1 — это не микроконтроллер, а микропроцессор (https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html, STM32MP1 microprocessor series with dual Arm® Cortex®-A7 and Cortex®-M4 Cores)
    2. «Поскольку ядро М4 работает под управлением А7, значит под управлением OpenSTLinux.» Не догма, Developers should note that OpenSTLinux Distribituion is not a specific, custom Linux distribution. Вы может использовать buildroot для сборки тоже, плюс можно там и там запускать и bare-metal и rtos.
    3. Raspberry в разы мощнее чем mp1
    4. «В этом кристалле у ядра М4 есть только оперативная память и код выполняется из нее (из даташита):» скорее правильно написать:
    All devices feature:
    • SYSRAM in MPU domain: 256 Kbytes
    • SRAM1 in MCU domain: 128 Kbytes
    • SRAM2 in MCU domain: 128 Kbytes
    • SRAM3 in MCU domain: 64 Kbytes
    • SRAM4 in MCU domain: 64 Kbytes
    • RETRAM (retention RAM): 64 Kbytes
    The content of this area can be retained in Standby or VBAT mode.
    • BKPSRAM (backup SRAM): 4 Kbytes
    The content of this area is protected against possible unwanted write accesses, and
    can be retained in Standby or VBAT mode.
    BKPSRAM can be defined (in ETZPC) as accessible by secure software only
    там память шарится между ядрами.

    • dernuss
      /#21427306

      Raspberry и дороже, и поди купи сразу 3000 партию;)

      • NordicEnergy
        /#21430706

        В таких объемах можно купить SoM модуль малиновский (по крайней мере азиатские контрактники покупали) или как вариант заказать производство в Китае, благо исходники на железо открыты насколько помню

        • dernuss
          /#21430790

          раньше SoM модули малиновсковские ни кому кроме них не продавали вроде

  4. gosha-z
    /#21427288

    Идеал не абсолютен. Особенно при наличии i.MX8 и AM65xx

    • dernuss
      /#21427352

      А есть ещё allwinner s3 ;)

      • gosha-z
        /#21427362

        Угу. С документацией «чуть меньше чем ничего». Не, все allwinner'ы идут подальше парадным шагом.

        • dernuss
          /#21427464

          Но зато цена;)
          Но в принципе доков хватает. Просто их чуток поискать надо. Зато DDR внутри

        • Swarg64
          /#21431916

          То, что для S3, A10, A13, RDA8810 и т.д. в публичном доступе не очень с документацией, сдк, исходниками портированных ОС и прочим, так это нормально — особенности ниши. Закупайте процессоры большими партиями и производитель предоставит немного документации, консультаций и прочего. Нужны небольшими, так всё очень просто — смотреть, есть ли чего подходящего из уже сделанного другими (платы, софт, портированные ОС, SDK,...) или сразу смотреть в сторону продукции от компаний, у которых немного другая модель работы (TI, ST, NXP и т.д).

      • Swarg64
        /#21433450

        В RDA8810 встроено 2ГБит озу и 4ГБит flash. Тут немного ещё информации по процессору.
        У Xunlong на этом процессоре есть Orange PI i96.

        • dernuss
          /#21434662

          Хм. Спасибо. Неплохо неплохо. Но вероятно дороже чем S3;)

  5. ancc
    /#21428338

    Так код на M4 нельзя автоматом первый стартовать? А оттуда уже программно разрешать запуск A7.

    • MinimumLaw
      /#21428418

      Увы нет. Сами ST сказали — A7, и только за тем M4. Впрочем, вариант прогрузить и стартовать M4 из U-Boot без всяких Linux'ов присутствует.

  6. im_stD
    /#21431740

    Здравствуйте. Спасибо за статью. Сам мучаю эту плату, пока что ковыряюсь вокруг А7.

    Правильно ли я понимаю, что вы создали приложение для А7 и программу для М4, и они взаимодействуют между собой через виртуальный УАРТ?

    Не могли бы вы выложить чуть более подробные коды работы с виртуальным портом? А то не совсем понятно, например, откуда взялась переменная «if (VirtUart0RxMsg)». Может выложите проект куда-нибудь?

  7. garriad
    /#21431918

    orange pi стоили до падения рубля около 800-900руб 12$ примерно, чем хуже? даже были версии дешевле

  8. freddie
    /#21431924

    Пытался использовать DK2 для эмуляции USB mass storage. Получил скорость 13.6MB/s.
    Для сравнения: teensy 3.6 давал около 10 MB/s.

    Потестировал шифрование:
    Testing AES-128-CBC cipher:
    Using cbc(aes) driver cbc-aes-neonbs:
    Encrypting in chunks of 512 bytes: done. 63.74 MB in 5.00 secs: 12.75 MB/sec
    Encrypting in chunks of 65536 bytes: done. 76.68 MB in 5.00 secs: 15.33 MB/sec

    А вот аппаратное шифрование:

    Using cbc(aes) with driver stm32-cbc-aes:
    Encrypting in chunks of 512 bytes: done. 9.28 MB in 5.00 secs: 1.86 MB/sec
    Encrypting in chunks of 65536 bytes: done. 13.24 MB in 5.01 secs: 2.64 MB/sec

  9. Swarg64
    /#21433650

    Из двухядерных микроконтроллеров у ST есть stm32h745-755 и STM32H747-757.
    У NXP недавно анонсированы i.MX RT1170 (1ГГц M7 ядро + 400МГц M4).

    • gosha-z
      /#21434418

      Это два M. MP1, i.MX8, AM65xx, ZynqMP — A+M/R. Почувствуйте разницу.

      • Swarg64
        /#21435430

        Да, в них два микроконтроллерных ядра, об этом выше и было написано. Эти mx8, zynq и прочие такие мощные штуки, это конечно здорово — чипы очень хорошие и нужные. Только ниш много, задачи разные бывают и не везде есть смысл или возможность использовать Linux и чипы с FPGA или A ядрами.