Визуальная электроника

Два года назад мы пытались использовать Raspberry Pi B+ для запуска нашей системы Умная остановка. В прошлый раз результат нас особо не вдохновил, и мы на какое-то время приостановили наши эксперименты. Но как известно время не стоит на месте, производители выпускают новые продукты. И мы решились повторить наш эксперимент уже на новой плате: Raspberry Pi 3 Model B. На этот раз мы решили не искать простых путей, и занялись кросс-компиляцией кросс-платформенного инструментария разработки ПО на языке программирования C++ QT 5.11 на Linux Ubuntu 17.10. Что из этого получилось можно прочитать под катом.

Обновлено для Qt 5.11 и Raspbian-2018-03-13 Stretch для Raspberry PI3 ModelB.

1. Первым делом необходимо скачать образ ОС для малинки, это будет raspbian и залить её на SD карточку, которая уже должна быть воткнута.

Bash Code:
  1. mkdir ~/Projects/RaspberryPI
  2. cd ~/Projects/RaspberryPI
  3. wget https://downloads.raspberrypi.org/raspbian/images/raspbian-2018-03-14/2018-03-13-raspbian-stretch.zip
  4. unzip 2018-03-13-raspbian-stretch.zip
  5. sudo dd if=2018-03-13-raspbian-stretch.img of=/dev/mmcblk0 bs=4M
  6. sync

Что бы узнать адрес флэшки, наберите lsblk

Если так случалось, что нет картридера, то залить прошивку можно и на винде с помощью win32diskimager (запускать от рута)

2. Когда заливка завершиться, вытаскиваем СДшку и загружаем с неё малинку.

Теперь её немножко надо настроить, переходим Menu -> Preferences -> Raspberry Pi configuration

Жмём «expand filesyste», включаем «ssh», перезагружаемся.

Подключаемся к сети (можно по вафле), вбиваем в консольке (Menu->Accessories->Terminal) ifconfig, запоминаем айпишник, на этом пока что всё.

3. Приконнектимся к малинке по ssh, раскомментим получение исходников пакетов, установим нужные пакеты и создадим нужные папки

Bash Code:
  1. IP=192.168.1.201 # айпишник малинки
  2. ssh pi@$IP #(пароль по дефолту "raspberry")
  3. sudo nano /etc/apt/sources.list #расскомментить строчку с deb-src
  4. sudo apt-get update
  5. sudo apt-get install -y libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev
  6. sudo apt-get install -y libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev
  7. sudo mkdir /usr/local/qt5pi
  8. sudo chmod -R 777 /usr/local/qt5pi

4. Так, возвращаемся к хосту, качаем тулчейн:

Bash Code:
  1. mkdir raspi
  2. cd raspi
  3. git clone https://github.com/raspberrypi/tools

4.1. После git clone https://github.com/raspberrypi/tools узнаем версию полученного компилятора например /opt/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc -v и видим что-то типа gcc версия 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03). После этого заходим на малину по ssh, выполняем gcc -v и видим например gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1). Сами понимаете собирать компилятором версии 4.8.3 под систему с gcc версии 6.3.0 не самая лучшая идея :))))) Поэтому идем сюда https://releases.linaro.org/ components/toolchain/binaries качаем версиюю gcc совпадающую с той что стоит на малинке, правим CROSS_COMPILE=путь к новому компилятору bin/префикс команд.

В нашем случае нужно качать файл gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz.

И путь получится такой: CROSS_COMPILE=$BASEPATH/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-. Где $BASEPATH/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-6.3.1/bin/ - путь к файлам компилятора, а arm-linux-gnueabihf- -префикс команд. Вот теперь должно нормально собираться.

5. Создаём sysroot и через rsync синхронизируем его с малиновым, что бы оттуда взять заголовочники, либы и компилятор

Bash Code:
  1. rsync -avz pi@$IP:/lib sysroot  # опять идём пить кофе
  2. rsync -avz pi@$IP:/usr/include sysroot/usr
  3. rsync -avz pi@$IP:/usr/lib sysroot/usr # можно сходить перекусить
  4. rsync -avz pi@$IP:/opt/vc sysroot/opt

6. Дальше необходимо поправить символьные ссылки, что бы они были относительно нашей скопированной sysroot, для этого есть готовый скриптик, качаем и запускаем:

Bash Code:
  1. wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
  2. chmod +x sysroot-relativelinks.py
  3. ./sysroot-relativelinks.py sysroot

7. Теперь можно склонировать Qt, сконфигурировать и запустить на компиляцию

Bash Code:
  1. git clone git://code.qt.io/qt/qt5.git Qt511Sources
  2. perl init-repository
  3. git checkout 5.11
  4. git submodule update --recursive
  5.  
  6. cd Qt511Sources
  7. BASEPATH=~/Projects/RaspberryPI/raspi # базовый путь, где все наши манипуляции происходят (без слэша на конце)
  8. ./configure -skip wayland -skip webkit -skip script -qt-xcb -no-pch -no-use-gold-linker -nomake tests -nomake examples -reduce-exports -release -opengl es2 -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=$BASEPATH/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf- -sysroot $BASEPATH/sysroot -opensource -confirm-license -make libs -prefix $BASEPATH/qt5pi -extprefix $BASEPATH/qt5pi -hostprefix $BASEPATH/qt5 -v
  9. make -j 4 # и поспим часик (4 - количество ядер проца, для ускорения)
  10. make install

Для Qt < 5.9.1 нужен -device linux-rpi3-g++

Если возникли ошибки при сборке и нужно переконфигурировать с другими параметрами, не забудьте удалить предыдущий результат, набрав «git clean -dxf» и «make clean» иначе будет ещё хуже =)

При ошибке с JavaScriptCore/wtf/Platform.h:370:6: error: #error «Not supported ARM architecture» добавьте к конфигурации «-skip script» или добавьте к make флаг:»make CFLAGS=»${CFLAGS}-D__ARM_ARCH_7M__»» (взял из /3rdparty/javascriptcore/ JavaScriptCore/wtf/Platform.h)

При ошибке с PCRE2: PCRE2_CODE_UNIT_WIDTH, LINK_SIZE и прочие мессаджы с ней связанные (отвечает за регулярные выражения) можно либо отключить ( в конфиге «-no-pcre»), но почему-то у меня не было такого параметра, либо прописать все дефайны вручную: make CFLAGS=»${CFLAGS} -ldl -DPCRE2_CODE_UNIT_WIDTH=16 -DHAVE_INTTYPES_H=1 -DHAVE_MEMMOVE=1 -DHAVE_LIMITS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDINT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DLINK_SIZE=2 -DMATCH_LIMIT=10000000 -DMATCH_LIMIT_RECURSION=10000000 -DMAX_NAME_COUNT=10000 -DMAX_NAME_SIZE=32 -DNEWLINE_DEFAULT=2 -DPARENS_NEST_LIMIT=250 -DSUPPORT_UNICODE» причина этому — почему-то не подключается файл config.h (Расположен qtbase/src/3rdparty/pcre2/src/config.h), где прописаны все эти дефайны.

При ошибке с zlib, можно её отключить -no-zlib (скорее всего каких-то либ на хосте нехватает, но т.к. мне было не важно, не стал разбираться, остальных проблем хватило)

При ошибке «ERROR: The OpenGL functionality tests failed! You might need to modify the include and library search paths by editing QMAKE_INCDIR_OPENGL[_ES2], QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your platform.» ИЛИ «In function `QEGLPlatformContext::getProcAddress(char const*)’: qeglplatformcontext.cpp:(.text+0xa4): undefined reference to `dlsym'» для Raspbian Stretch нужно подредактировать nano ./qtbase/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf и изменить названия либ «-lEGL» и «-lGLESv2» на «-lbrcmEGL» и «-lbrcmGLESv2» так как названия в /opt/vc/lib/ отличаются. И make запускать так: «make CFLAGS=»${CFLAGS} -ldl»» или так: «LIBS=-ldl ./configure«. Хрен знает что из этого помогло, скорее первое.

В случае ошибки «error: invalid use of incomplete type ‘X509 {aka struct x509_st}’«, то это баг Qt: https://bugreports.qt.io/browse/QTBUG-52905. Исправления будут в версии 5.10, так что либо отключайте ssl при конфигурации: «-no-openssl» либо даунгрейдите openssl до 1.0

8. Теперь закинем на малинку скомпилированные библиотеки и заголовочники Qt:

Bash Code:
  1. cd ../
  2. rsync -avz qt5pi pi@$IP:/usr/local

9. Ну и можно собрать пример и закинуть на малинку:

Bash Code:
  1. cd Qt511Sources/qtbase/examples/opengl/qopenglwidget
  2. $BASEPATH/qt5/bin/qmake
  3. make
  4. scp qopenglwidget pi@$IP:/home/pi

10. На девайсе необходимо дать знать линковщику о наших либах, а так же создать qt.conf в папке, откуда будем запускать все Qt приложения:

Bash Code:
  1. ssh pi@$IP #пароль по дефолту "raspberry"
  2. echo /usr/local/qt5pi/lib | sudo tee /etc/ld.so.conf.d/00-qt5pi.conf
  3. echo QT_PLUGIN_PATH=/usr/local/qt5pi/plugins/ | sudo tee -a /etc/environment
  4. echo QT_QPA_FONTDIR=/usr/share/fonts/truetype/dejavu | sudo tee -a /etc/environment
  5. printf "[Paths]\nPlugins=/usr/local/qt5pi/plugins\nQml2Imports=/usr/local/qt5pi/qml" | sudo tee ~/qt.conf
  6. cd /usr/local/qt5pi/lib
  7. sudo ldconfig

При проблеме «QFontDatabase: Cannot find font directory /home/pi/lib/fonts. Note that Qt no longer ships fonts. Deploy some (from http://dejavu-fonts.org for example) or switch to fontconfig.» нужно указать, где лежат шрифты, для этого добавим переменную окружения (выше уже добавлена) : «echo QT_QPA_FONTDIR=/usr/share/ fonts/truetype/dejavu | sudo tee -a /etc/environment» видимо какую-то опцию забыл в конфиге добавить, наверное «-fontconfig«.

Перезагружаем малинку.

11. Но запускать ещё рано, у rasbian по дефолту грузиться mesa драйвер и opengl пахать не будет по нормальному, поэтому заставим её использовать нужный:

Не факт! Сначала всё таки лучше попробовать запустить =)

Bash Code:
  1. sudo rm /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0 /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0
  2. sudo ln -s /opt/vc/lib/libEGL.so /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0
  3. sudo ln -s /opt/vc/lib/libGLESv2.so /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0
  4. sudo ln -s /opt/vc/lib/libEGL.so /opt/vc/lib/libEGL.so.1
  5. sudo ln -s /opt/vc/lib/libGLESv2.so /opt/vc/lib/libGLESv2.so.2

Вот теперь наконец-то можно запустить пример! Он на малинке /home/pi/qopenglwidget

Если не запускается, в консольке прописываем

Bash Code:
  1. export QT_LOGGING_RULES=qt.qpa.*=true
  2. ./qopenglwidget

И гуглим ошибки. Если совсем не запускается, то прописываем:

Bash Code:
  1. ldd ./qopenglwidget

И смотрим по правильному адресу ли лежат библиотеки и всех ли хватает. Потом гуглим на тему ldconfig.

12. С этим разобрались, теперь настроим QtCreator что бы можно было компилить и запускать на малинке в один клик:

pic1

12.1. Инструменты->Параметры->Устройства->Добавить

Обычное Linux-устройство

название на свой вкус и цвет

вводим айпишник, логин и пароль

завершить

pic2

Если все хорошо, то увидим следующее сообщение:

pic3

12.2. Инструменты->Параметры->Сборка и запуск->Компиляторы->Добавить

GCC->C++

Название: Raspberry PI3 GCC

Путь: /opt/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-g++

pic4

12.3. Инструменты->Параметры->Сборка и запуск->Отладчики->Добавить

Название: Raspberry PI3 GDB

Путь: /opt/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-6.3.1/bin/arm-linux-gnueabihf-gdb

pic5

12.4. Инструменты->Параметры->Сборка и запуск->Профили Qt->Добавить

Название: Qt 5.11.0 Raspberry PI3

Путь: /opt/raspi/qt5/bin/qmake

pic6

12.5. Инструменты->Параметры->Сборка и запуск->Комплекты->Добавить

Название: Raspberry PI3

Тип устройства: Обычное Linux-устройство

Устройство: выбираем добавленное из первого шага

Компилятор C++: Raspberry PI3 GCC

Отладчик: Raspberry PI3 GDB

Профиль Qt: Qt 5.11.0 Raspberry PI3

pic7

12.6. Нажимаем «Применить».

13. Создаём новый проект, в *.pro файл добавляем:

Bash Code:
  1. INSTALLS = target
  2. target.path = /home/pi

Компилим и после завершения проект должен запуститься на малинке.

Вот как-то так в общем =)

P.S. Большая часть была взята с http://pavelk.ru с моими небольшими правками — думал всё сложнее будет =)

Ниже можно наблюдать видео работы нашей системы Умная остановка на Raspberry Pi 3 Model B.

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