STM32MP1 - часть первая





Здравствуйте.

Рассказ пойдёт об относительно новой серии устройств STM32MP, в частности у меня самая простая плата — stm32MP157A-DK1. Вот такая…



На обратной стороне сделаны разъёмы для подключения ардуиновских шилдов.


Основная идея этой штуковины в том, что она двухядерная. Первое ядро — Cortex-A7 отвечает за работу с Линуксом со всеми вытекающими, а второе ядро — Cortex-M4 работает как обычный микроконтроллер. Всё это хозяйство упаковано в один камень и может взаимодействовать между собой.

Характеристики…



Подробнее можно посмотреть на сайте производителя.

User manual UM2534 с обозначениями всего что есть на плате и распиновкой ножек.



Далее все операции будут производится на Ubuntu 18.04 (если вы не крутой линксойд, тогда советую использовать именно её). Поклонникам Windows нужно либо раздобыть где-то комп с Ubuntu, либо поставить её параллельно с Windows, либо в виртуальную машину.




Итак, откройте wiki по запуску этой платы — wiki.st.com/stm32mpu/wiki/Getting_started/STM32MP1_boards/STM32MP157C-DK2/Let%27s_start — это будет вашим основным документом по изучению сабжа.


Про провод
Мне некуда было воткнуть USB Type-С чтоб запитать устройство (откровенно говоря непонятно о чём думал производитель, при условии что плата потребляет до 3А), поэтому я разрезал тот что был в комплекте, и методом прозвона и тыка, выяснил как подключить его к источнику питания. Нужно найти толстый красный провод и тоненький чёрный (оба они не обмотаны фольгой). К минусу подсоединяется экран-оплётка. К плюсу подключается красный провод напрямую, чёрный через резистор 10КОм.




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

Первым делом нам нужно завести Cortex-A7, то есть превратить плату в почти полноценный компьютер. Плата комплектуется SD-картой с установленным образом. Карту нужно вставить в слот, подключить HDMI кабель к монитору, подключить интернет, подключить мышку, и убедится что переключатели режимов загрузки (SW1) переключены в ON…



Теперь можно подавать питание на в разъём USB Type-C (PWR IN), который располагается возле интернета.

Тут есть важный момент — нужно обеспечить питание до 3 ампер! Если силы тока будет не хватать, тогда красный светик будет подавать различные сигналы...




В идеале, если всё хорошо, то через некоторое время вы увидите на экране такую картинку…



Это запустился дефолтный лаунчер. Иконки говорят сами за себя, камеру можно подключить и посмотреть, видео проиграть, кубик покрутить, но сейчас самая интересная иконка это Netdata, если её нажать, то система покажет IP-адрес и порт, зайдя по которому можно будет в браузере просматривать различные параметры системы…


Можно нажимать что угодно и получать разнообразную инфу.


При работе Линукса будет гореть или мигать синенький светик.



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

Отключаем питание платы и подключаем кабель к микроюсби (ST-Link CN11) и к компьютеру. Открываем какой-нибудь монитор порта (я пользуюсь ардуиновским) и выбираем порт /dev/ttyACMx (скорость 115200). Подаём питание на плату…



Питание можно было не отключать, а просто подключить кабель и нажать кнопочку RESET (чёрная).

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


На этом загрузка остановится.



Поскольку это не просто вывод инфы, а самый обычный терминал, то можно давать какие-либо команды. Например если дать команду df -h, то увидим размеры разделов (предварительно нажмите пару раз «Отправить» с пустой строкой)


У меня разделы уже увеличены (об этом ниже), а у вас они будут меньше.


Посмотреть версию ядра (uname -a)




Посмотреть ip (ifconfig)



Для отправки команд должны быть включены «перенос» и «новая строка» (NL &CR).



Далее, если всё работает и подключён интернет, тогда заходим на устройство по ssh (адрес мы уже знаем) и работаем как с обычным компом…


Заходим как root, пароля нет.

Собственно монитор нам больше не особо то и нужен (и с самого начала тоже не был нужен).


Стандартные команды apt-get update и apt-get upgrade


Обновлять нечего.


Про установку других программ поговорим позже.




Starter Package

Это пакет с файлами готового образа для записи на SD-карту.


Рассмотрим тот случай когда у вас нет готовой SD-карты. Потребуется карточка от 16Г, в принципе образ по умолчанию влезет и на 2Г, но лучше взять побольше чтоб потом увеличить разделы.

Способы записи образа описаны здесь. Первый вариант делается с использованием утилиты STM32CubeProgrammer, той самой с помощью которой можно работать с обычными камнями. Суть заключается в том, что образ разбитый на несколько файлов заливается на SD-карту по частям через USB OTG в режиме DFU.



Описывать я его не буду так как люди жалуются на глюки.


Второй способ, это собрать файлы образа в один, и залить его на SD-карту на компьютере программой dd.

Итак, идём сюда, находим главу 5 Download the image и качаем архив STM32MP15-Ecosystem-v1.2.0 Starter Package в домашнюю папку…


… и распаковываем.

После распаковки появится папка stm32mp1-openstlinux-20-02-19, в которой в подпапках будут находится куча файлов из которых собирается образ.

Открываем терминал и переходим в папку со скриптом, который будет собирать образ…

cd $HOME/stm32mp1-openstlinux-20-02-19/images/stm32mp1/scripts/


Теперь лезем в проводник, в папку /stm32mp1-openstlinux-20-02-19/images/stm32mp1/flashlayout_st-image-weston/


Видим там кучу файлов среди которых есть несколько заканчивающихся ...-trusted.tsv, это стартовые файлы для сборки образа. В их именах содержится название платы, в частности для моей STM32MP157A-DK1 нужен выделенный на картинке файл. То есть, если у вас плата другая, то ищите файл с её названием заканчивающийся на ...-trusted.tsv.

Возвращаемся в терминал и вводим команду запускающую скрипт сборки с соответствующим файлом…

./create_sdcard_from_flashlayout.sh ../flashlayout_st-image-weston/FlashLayout_sdcard_stm32mp157a-dk1-trusted.tsv

Название платы у вас своё, будьте внимательны!



Нажимаем Enter и ждём…


В процессе нам покажут какие разделы создаются и их размеры.


Через минуту мы получим готовый образ для записи на SD-карту. Система подскажет где он лежит, и как использовать программу dd.



В результате в папке /stm32mp1-openstlinux-20-02-19/images/stm32mp1/ будет лежать наш образ (заканчивается на ...trusted.raw)flashlayout_st-image-weston_FlashLayout_sdcard_stm32mp157a-dk1-trusted.raw. У вас опять же будет своё название платы.


Остаётся только записать его на SD-карту. Вставляем карту в комп (надеюсь у вас есть переходник на USB или картридер) и проверяем как она определилась в системе — даём команду…

sudo fdisk -l



У меня она определилась как sdc. На существующие разделы не обращайте внимания, я уже много раз перезаписывал.


Осталось записать образ. Даём команду…

sudo dd if=../flashlayout_st-image-weston/../flashlayout_st-image-weston_FlashLayout_sdcard_stm32mp157a-dk1-trusted.raw of=/dev/sdc bs=8M conv=fdatasync status=progress

И опять же, название платы у вас своё.



Warning! Проверяем ещё раз что имя карточки указано именно ваше (of=/dev/sd?) и только после этого жмём Enter.


Процесс займёт какое-то время, поэтому садимся и наблюдаем за циферками…



Не закрывайте этот терминал когда всё завершится, он нам ещё пригодится.


После окончания записи делаем всё как написано выше, вставляем карту в устройство, проверяем переключатель режимов (SW1), подключаем вывод лога загрузки, и подаём питание.

Если всё загрузилось, тогда отправляем команду ifconfig чтоб узнать ip-адрес и подключиться по ssh…



Если грузится не хочет, то попробуйте нажать RESET, если выдаёт какую-то ошибку, то попробуйте перезаписать образ предварительно отформатировав карту в FAT.


Итак, заходим по ssh (подробности выше) и смотрим размеры разделов командой…

df -h






У нас есть два «больших» раздела. Первый это /dev/root, смонтирован в корень /. Сюда будут устанавливаться различные программы из репозитория, если вы их планируете устанавливать. Там лежат привычные системные папки…




Второй раздел /dev/mmcblk0p7, смонтирован в /usr/local. Сюда можно сваливать всяких хлам. Там лежат всякие STMовские файлы — примеры и прочее…




Чтоб было удобнее посмотреть что где лежит, нужно установить Midnight Commander…

apt-get update
apt-get install mc


Запускаем…

mc




Чтобы заработала мышка, нужно перед запуском дать команду…

export TERM="xterm"

Однако это будет работать только до следующей перезагрузки. Чтобы работало постоянно, нужно эту строчку добавить в конец файла /etc/profile.


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

Для этого нам придётся пересобрать образ предварительно внеся пару изменений в сборочный скрипт.

Идём в папку /stm32mp1-openstlinux-20-02-19/images/stm32mp1/scripts/ и открываем скрипт create_sdcard_from_flashlayout.sh. Комментируем строчки…

# Size of 1.5GB
#DEFAULT_RAW_SIZE=1536

# size of 768MB
#DEFAULT_ROOTFS_PARTITION_SIZE=768432


И вместо них вписываем такие…

# Size of 1.5GB
#DEFAULT_RAW_SIZE=1536
DEFAULT_RAW_SIZE=12288

# size of 768MB
#DEFAULT_ROOTFS_PARTITION_SIZE=768432
DEFAULT_ROOTFS_PARTITION_SIZE=7397376

Сохраняем и закрываем.

Это рассчитано на флешку не меньше 16Гб.


Возвращаемся в тот терминал где собирали образ и даём знакомую команду сборки образа…

./create_sdcard_from_flashlayout.sh ../flashlayout_st-image-weston/FlashLayout_sdcard_stm32mp157a-dk1-trusted.tsv

Не забудьте про название платы.

Жмём Enter (появится вопрос переписать ли старый образ — согласитесь — Y)



В результате мы увидим что те самые разделы стали 7.1Гб и 4.9Гб соответственно.


Теперь записываем образ на карту. Вставьте её в комп, проверьте что карточка определилась под тем же именем…

sudo fdisk -l


И дайте почти такую же команду что и ранее, но только изменив один параметр — bs (block size), вместо 8M укажем 1M.

sudo dd if=../flashlayout_st-image-weston/../flashlayout_st-image-weston_FlashLayout_sdcard_stm32mp157a-dk1-trusted.raw of=/dev/sdc bs=1M conv=fdatasync status=progress


Запускаем и ждём, процесс будет идти дольше чем в предыдущий раз. Можно даже чаю налить.



По завершению втыкаем карту в плату, подаём питание и смотрим лог загрузки. Первый раз он будет гораздо дольше чем обычно, проявите терпение, а на экране будут повторяться похожие фразы, типа «A start job is running for Resize»…


Это происходит применение новых размеров разделов. Когда плата всё поделает и окончательно загрузится (появится строка приглашения), можете нажать ресет чтоб убедиться, что теперь загрузка проходит как обычно.

Повторюсь. Если система не грузится после записи нового образа, то просто повторите всё с начала. У меня такое случалось не однократно, то просто не грузилось, то Kernel Panic, и ещё что-то было. Это относится к только что записанному образу, дальше, если он загрузился и заработал, уже никаких ошибок не будет.


Теперь заходим по ssh (ip-адрес у устройства поменяется) и смотрим что у нас получилось…



Системный раздел теперь 7Гб, а /usr/local 4.8Гб. Можно смело устанавливать различные программы.


Посмотреть установленные пакеты…

dpkg -l


Посмотреть доступные пакеты…

apt-cache search deb*


Посмотреть наличие конкретного пакета…

apt-cache search mc


Установить пакет…

apt-get install mc


Удалить пакет…

apt-get remove mc



Установить пароль root'а…

passwd root



Ввести и повторить. При вводе ничего не отображается. Пока что этого делать не надо.


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




Developer Package SDK

Это пакет для кросс-компиляции приложений для А7.


Теперь нам нужно научится писать графические или консольные приложения для А7. Сделать это на самой плате нельзя, можно только с помощью кросс-компиляции (компиляция программ для одной платформы на другой платформе) на большом компьютере.

Для этого нужно собрать специальное SDK. Как это сделать описано здесь.

Вначале нужно установить доп. пакеты…

sudo apt-get update
sudo apt-get install sed wget curl cvs subversion git-core coreutils unzip texi2html texinfo docbook-utils gawk python-pysqlite2 diffstat help2man make gcc build-essential g++ desktop-file-utils chrpath libxml2-utils xmlto docbook bsdmainutils iputils-ping cpio python-wand python-pycryptopp python-crypto
sudo apt-get install libsdl1.2-dev xterm corkscrew nfs-common nfs-kernel-server device-tree-compiler mercurial u-boot-tools libarchive-zip-perl
sudo apt-get install ncurses-dev bc linux-headers-generic gcc-multilib libncurses5-dev libncursesw5-dev lrzsz dos2unix lib32ncurses5 repo libssl-dev

Это рекомендуется в главе 2 Host computer configuration. Я опустил установку пакета default-jre так как у меня java устанавливалась так.


Создаём в домашней папке каталог SDK…

mkdir SDK


Теперь ищем по ссылке выше главу Download the SDK и скачиваем в этот каталог пакет STM32MP15-Ecosystem-v1.2.0 Developer Package SDK…


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


После скачивания переходим в каталог SDK и распаковываем полученный архив…

cd SDK


tar xvf en.SDK-x86_64-stm32mp1-openstlinux-20-02-19.tar.xz

Если версия более новая, тогда либо подставьте нужное, либо распакуйте «мышкой».


В результате получим такое…




Теперь нам нужно запустить скрипт находящийся в /home/dima/SDK/stm32mp1-openstlinux-20-02-19/sdk/, который установит SDK.

На всякий случай сделаем его исполняемым…

chmod +x $HOME/SDK/stm32mp1-openstlinux-20-02-19/sdk/st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-2.6-openstlinux-20-02-19.sh


И запустим его командой…

$HOME/SDK/stm32mp1-openstlinux-20-02-19/sdk/st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-2.6-openstlinux-20-02-19.sh -d $HOME/SDK



Всё готово…



Warning!

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

. /home/dima/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

Точка и пробел в начале. Замените имя пользователя на своё.


Теперь каталог SDK выглядит так…


Выделенное нужно удалить, чтоб потом оно не мешалось.


Далее, находясь в каталоге SDK дайте команду…

source environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi


Теперь выполним проверки настройки компилятора…

echo $ARCH

echo $CROSS_COMPILE

$CC --version

echo $OECORE_SDK_VERSION


Ответы должны быть такими…


Если что-то не так, или вообще ничего не выводит, тогда нужно переустановить SDK.

Всё готово для создания приложений под А7.



Теперь перейдём сюда и создадим приложение которое там описано.


В папке SDK создадим папку MYAPP

mkdir MYAPP

Это будет папка, в которой будут собираться ваши приложения.

Перейдем в неё…

cd MYAPP


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

mkdir gtk_hello_world


Когда будете делать другое приложение, то создадите для него другую папку в папке MYAPP.

Как-то так…




Теперь перейдём в папку mkdir gtk_hello_world

cd gtk_hello_world





Далее воспользуемся каким-нибудь редактором и создадим там файл gtk_hello_world.c вот с таким содержимым…

#include <gtk/gtk.h>

static void print_hello(GtkWidget *widget, gpointer data)
{
  g_print("Hello World\n");
}

static void activate(GtkApplication *app, gpointer user_data)
{
  GtkWidget *window;
  GtkWidget *button;
  GtkWidget *button_box;

  window = gtk_application_window_new(app);
  gtk_window_set_title(GTK_WINDOW (window), "Window");
  gtk_window_set_default_size(GTK_WINDOW (window), 200, 200);

  button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
  gtk_container_add(GTK_CONTAINER(window), button_box);

  button = gtk_button_new_with_label("Hello World");
  g_signal_connect(button, "clicked", G_CALLBACK(print_hello), NULL);
  g_signal_connect_swapped (button, "clicked", G_CALLBACK(gtk_widget_destroy), window);
  gtk_container_add(GTK_CONTAINER(button_box), button);

  gtk_widget_show_all(window);
}

int main(int argc, char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
  status = g_application_run(G_APPLICATION(app), argc, argv);
  g_object_unref(app);

  return status;
}


И там же создаём Makefile вот с таким содержимым…

PROG = gtk_hello_world
SRCS = gtk_hello_world.c

CLEANFILES = $(PROG)

# Add / change option in CFLAGS and LDFLAGS
CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
LDFLAGS += $(shell pkg-config --libs gtk+-3.0)

all: $(PROG)

$(PROG): $(SRCS)
	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)

clean:
	rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))

Проверьте чтоб отступы были табуляцией.


В итоге папка gtk_hello_world будет выглядеть так…




Ну и остаётся создать наше приложение командой…

make


Готово…


Ошибок и варнингов нет.

Приложение появится в той же папке…



Когда будете делать новое приложение, тогда нужно перейти в его папку, и давать команду make уже оттуда. И обратите внимание что в новом Makefile нужно вписать другие имена (первые две строчки).

Важно
Помните, что после того как вы презагрузились/перелогинились или создаёте новое приложение, нужно из папки с исходниками дать команду…

. /home/dima/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi


То есть, допустим вы перезагрузили компьютер и решили изменить что-то в программе gtk_hello_world, тогда перейдя в папку с исходниками…

cd /home/dima/SDK/MYAPP/gtk_hello_world

… прежде чем давать команду make, нужно дать выше означенную команду.




Остаётся перекинуть приложуху на плату и посмотреть что вышло. Воспользуемся копированием по ssh

scp gtk_hello_world root@192.168.5.155:/usr/local




Копируем в папку /usr/local, там ещё всякие STMовские папки лежат. Впрочем если хотите, можете скопировать в папку /home/root, там у нас тоже много места сделано.


Заходим по ssh на плату, запускаем mc — вот и наш файлик…



Запускаем его…

/usr/local/gtk_hello_world

Должен быть подключён монитор, а то ошибки будет валить.

Впрочем одна ошибка не влияющая на работу будет…


Но она не страшная, и даже у них на сайте она показана.


В результате на экране мы увидим рук своих творение…


Если мышка подключена, то можно тыкнуть кнопку, если нет, то в терминале нажать Ctrl + c.


Ну и для закрепления материала создадим консольное приложение, которое будет просто печатать строчку в терминале.

В папке MYAPP создаём папку hello, а в ней файлы hello.c и Makefile.



Содержимое файла hello.c

#include <stdio.h>

int main(void)
{
  printf("Hello from istarik.ru\n");
  return 0;
}


Содержимое файла Makefile

PROG = hello
SRCS = hello.c

CLEANFILES = $(PROG)

# Add / change option in CFLAGS and LDFLAGS
CFLAGS += -Wall 

all: $(PROG)

$(PROG): $(SRCS)
	$(CC) -o $@ $^ $(CFLAGS) 

clean:
	rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))


Переходим в папку hello

cd /home/dima/SDK/MYAPP/hello/


Даём команду…

. /home/dima/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi


И собираем…

make




Файлик появился…



Закидываем его на плату…

scp hello root@192.168.5.155:/usr/local


И запускаем уже на плате…

/usr/local/hello


Вуаля…




Чтобы добавить своё приложение в systemd (система управления приложениями — запуск, остановка, добавление/удаление в/из автозапуска) нужно сделать следующее.

Для начала установим нормальный редактор…

apt-get install nano


А теперь добавим в systemd нашу программку hello.

Переходим в папку…

cd /etc/systemd/system


И создаём сервис hello.service, то есть это просто файл состоящий из названия программы с точкой и словом service

nano hello.service


Вставляем в него это…

[Unit]
Description=my_first_service

[Service]
Type=oneshot
ExecStart=/usr/local/hello

[Install]
WantedBy=multi-user.target


Ctrl + o нажать Enter — сохранить.
Ctrl + x — выйти.

Подробности про содержимое файла посмотрите тут.


Команды:

systemctl status hello.service — посмотреть статус.

systemctl start hello.service — запустить (запустится как демон, ничего выводить не будет).

systemctl stop hello.service — остановить.

systemctl enable hello.service — добавить в автозагрузку.

systemctl disable hello.service — убрать из автозагрузки.

systemctl is-enabled hello.service — узнать есть ли он в автозагрузке.




Kernel Linux

Это исходники ядра для работы на MP1.


Теперь копнём ещё глубже и научимся модифицировать и собирать само ядро Linux. Конечно модификация ядра это очень трудная задача, и под силу только спецам, однако описать процедуру в целом будет не лишним.

Итак, переходим вот сюда и в главе 2 Download the the Linux® kernel source code щёлкаем ссылку STM32MP15-Ecosystem-v1.2.0 Developer Package Sources


Мы уже переходили по этой ссылке когда скачивали SDK, однако сейчас у нас скачается архив с исходниками ядра — en.SOURCES-kernel-stm32mp1-openstlinux-20-02-19.tar.xz (так вот организовали сайт разработчики из ST).

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

Скачайте его в папку SDK и там распакуйте, появится папка stm32mp1-openstlinux-20-02-19. Внутри будет лежать папка source, в ней будет папка arm-ostl-linux-gnueabi, а в ней нужная нам папка linux-stm32mp-4.19-r0



Копируем её непосредственно в папку SDK, получится так…


Выделенное нужно удалить.

Я намеренно так заморачиваюсь, чтоб собрать всё в одном месте и при этом сократить пути.


Теперь в терминале переходим в папку linux-stm32mp-4.19-r0

cd $HOME/SDK/linux-stm32mp-4.19-r0/


И распаковываем ещё один архив…

tar xvf linux-4.19.94.tar.xz

На этом возня с распаковками закончена




В папке SDK/linux-stm32mp-4.19-r0/linux-4.19.94/ будет лежать всё необходимое для сборки ядра…




Переходим в эту папку…

cd linux-4.19.94/


Первым делом даём знакомую команду…

. /home/dima/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

Чтоб было понятно почему мы её везде суём — эта команда «подключает» нужное окружение (кросс-компилятор и всё такое).


Теперь соберём ядро. Чтоб потренироваться сделаем это не внося изменений.

Применяем патчи…

for p in `ls -1 ../*.patch`; do patch -p1 < $p; done


Применяем фрагменты…

make ARCH=arm multi_v7_defconfig "fragment*.config"

for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done

yes '' | make ARCH=arm oldconfig


Собираем ядро…

make ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040

Можно пойти попить чаю, кофе, и даже вздремнуть, процесс долгий.

Параметр LOADADDR указывает на адрес, по которому образ ядра будет находиться в U-Boot. Посмотреть этот адрес можно в файле SDK/linux-stm32mp-4.19-r0/README.HOW_TO.txt.


Собираем модули ядра…

make ARCH=arm modules

Можно ещё чаю попить.

Generate output build artifacts…

mkdir -p $PWD/install_artifact/

make ARCH=arm INSTALL_MOD_PATH="$PWD/install_artifact" modules_install



Если всё прошло без ошибок и предупреждений, значит ядро собралось.

Загружаем новое ядро на плату в папку /boot

scp arch/arm/boot/uImage root@192.168.5.155:/boot


Загружаем дерево устройств…

scp arch/arm/boot/dts/stm32mp157*.dtb root@192.168.5.155:/boot

Об этом дереве будет сказано ниже.

Удаляем ненужные ссылки…

rm install_artifact/lib/modules/4.19.94/build install_artifact/lib/modules/4.19.94/source


Уменьшаем размер модулей…

find install_artifact/ -name "*.ko" | xargs $STRIP --strip-debug --remove-section=.comment --remove-section=.note --preserve-dates


Загружаем модули на плату…

scp -r install_artifact/lib/modules/* root@192.168.5.155:/lib/modules



Теперь заходим по ssh на плату и даём две команды…

/sbin/depmod -a

sync


Теперь можно перегрузить плату, но прежде откройте  чтоб понаблюдать за процессом перезагрузки…

reboot



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

uname -a



Дата и время создания ядра (время начала сборки).



Если нужно внести изменения в ядро, тогда в той же папке даём команду…

make arch=ARM menuconfig




Делаем свои дела, сохраняем, собираем…

make ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040

… и отправляем на устройство.

Если добавляли модули, то и их нужно собрать.

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




Дерево устройств

В папке /boot на плате есть файлы с расширением .dtb


С помощью этих файлов конфигурируется различное оборудование на плате, например те же светодиоды. Сами по себе это бинарники, и отредактировать их нельзя, однако в папке SDK/linux-stm32mp-4.19-r0/linux-4.19.94/arch/arm/boot/dts/ лежат файлы с таким же названием но с расширением .dts, которые являются исходниками этих бинарников…



После внесения изменений файл собирается (компилируется) специальной командой и копируется на плату. Сейчас мы это проделаем на примере показанном здесь в главе 4 Modifying the Linux kernel device tree.

Открываем файл stm32mp157a-dk1.dts (у вас может быть другая плата) в каком-нибудь редакторе и добавляем включение зелёного светика как это описано в примере по ссылке выше…

...
	led {
		compatible = "gpio-leds";
		blue {
			label = "heartbeat";
			gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "heartbeat";
			default-state = "off";
		};
		
		green {
 			label = "stm32mp:green:user";
 			gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
 			default-state = "on";
  		};
	};
...

Кстати, как видите, там прописано мигание синеньким светиком.

Сохраняем файл и в терминале переходим в папку сборки ядра…

cd $HOME/SDK/linux-stm32mp-4.19-r0/linux-4.19.94/


Даём команду…

. /home/dima/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

Надо бы было с самого начала заменить /home/dima на $HOME, но что-то я про это забыл, так что либо замените сами, либо подставляйте своего пользователя.

Компилируем файлы…

make dtbs


И копируем на плату…

scp arch/arm/boot/dts/stm32mp157*.dtb root@192.168.5.155:/boot


Теперь если перегрузить плату будет гореть зелёненький светик (возле кнопки reset).

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



Создавать образы и записывать их еа карту мы научились, писать приложения для А7 тоже научились, и собирать ядро тоже теперь умеем. Остаётся последний пункт, это создать свой собственный дистрибутив (Distribution Package). Как это сделать, как добавлять свои слои, и прочее, описано здесь. Я же не буду рассказывать про это так как не очень то понимаю зачем это нужно рядовому, да и не только, разработчику (тем более, что первичная сборка заняла у меня около 10 часов и закончилась ошибкой), ему вполне достаточно уже готового дистрибутива, который мы установили в самом начале статьи, а дополнительные программы научились писать с помощью SDK. Так же я не стал описывать сборку U-Boot и ещё некоторых вещей. То есть, в этой части я постарался рассказать о том, что на мой взгляд действительно является важным на начальном уровне изучения и работы с ядром А7 микроконтроллера STM32MP1.


В следующей части речь пойдёт о программировании М4 и его взаимодействии с А7.


Да, ещё можно собрать дополнительные инструменты, но об этом потом — wiki.st.com/stm32mpu/wiki/How_to_build_Linux_kernel_user_space_tools


Это всё, всем спасибо


Телеграм-чат istarik

Телеграм-чат STM32


  • 0
  • 19892
Поддержать автора


Telegram-чат istarik

Задать вопрос по статье
Telegram-канал istarik

Известит Вас о новых публикациях






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

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.