Одноплатный компьютер для embedded программиста. Моргаем светодиодом на Qt +2


AliExpress RU&CIS

Введение

Цель - моргать светодиодом на GPIO одноплатного компьютера в своём Qt проекте.

Первое, что приходит в голову - использовать готовое решение, такое как wiringOP. Однако для меня, как программиста микроконтроллеров, странно устанавливать пакет для работы с GPIO. Но помимо этого сторонний пакет ещё и нужно динамически линковать (связывать) с моим приложением. А тут возникает и вопрос совместимости с новой версией пакета, и вопрос того, будет ли пакет этот в системе установлен. Таким образом, я решил прикрутить wiringOP к своему проекту на Qt статически, да и ещё иметь возможность редактировать wiringOP как проект статической библиотеки прямо в Qt Creator.

Как оказалось, кодовая база проекта wiringOP является явно избыточной. Например, мне не нужен код для работы со сдвиговыми регистрами. Так что возможность удобно редактировать библиотеку оказывается очень кстати. Ключевой функцией является wiringPiSetup(), которая выясняет у Ubuntu адреса GPIO и других регистров в памяти путем чтения файла /dev/mem. Забегая вперед скажу, что это - дырка в безопасности, потому что читая /dev/mem - можно получить доступ не только к портам ввода-вывода, но и ко всей ОЗУ.

После инициализации с помощью wiringPiSetup() можно приступать к работе. Так, функция pinMode задает режим работы вывода гребенки: вход, выход, генерация PWM. Пример кода моргания светодиодом на выводе PIN8.

wiringPiSetup();
pinMode(3, OUTPUT);
while(1){
  digitalWrite(3, LOW);
  delay(1000); //for(volatile uint64_t i=0;i<0xFFF;i++);
  digitalWrite(3, HIGH);
  delay(1000); //for(volatile uint64_t i=0;i<0xFFF;i++);
}

Сам светодиод должен быть подключен к гребенке. В случае Orange Pi 4B ситуация следующая.

Статическая линковка wiringOP

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

git clone https://github.com/orangepi-xunlong/wiringOP.git 

Далее необходимо создать новую Statically Linked Library. В качестве системы сборки я выбрал qmake.

Далее нужно из скачанной wiringOP в созданную библиотеку перенести некоторые файлы согласно рисунку ниже.

В файле .pro библиотеки можно настроить важные параметры, влияющие на сборку. Во-первых, указать модель SBC. Во-вторых, было бы удобно, чтобы результирующий файл libmy_wiringOP_v5.a помещался в отдельную папку wiringOP_build_artifacts. Это можно настроить следующим образом

DEFINES += CONFIG_ORANGEPI 
DEFINES += CONFIG_ORANGEPI_4  
DESTDIR = $$PWD/../wiringOP_build_artifacts

Подсказка. Знаком две точки требуем переход на каталог назад; переменная $$PWD предоставляет текущий путь к проекту.

Наконец можно собрать библиотеку. В случае успеха вы получите файл libmy_wiringOP_v5.a

Перейдём к тестовому проекту, в моём случае консольному. Необходимо добавить в проект нашу библиотеку как External Library согласно скриншоту.

Обратите внимание, что один и тот же файл wiringPi.h используется как при создании библиотеки, так и в тестовой программе. Наконец можно написать программу для моргания светодиодом. Далее перенесем исходные коды на целевую машину.

rsync -avz /home/andrei/Документы/mywiringOP/my_wiringOP_base/my_wiringOP_v5  a@192.168.0.112:/home/a/Documents/QtProj
rsync -avz /home/andrei/Документы/mywiringOP/my_wiringOP_base/wOP_Test1  a@192.168.0.112:/home/a/Documents/QtProj

Оборачиваясь назад, можно было просто поместить файлы wiringOP в дерево своего проекта и вызывать функции. Получается, что мы пошли по тернистому пути, однако приобрели навык создания своей библиотеки и использования её в проекте. Теперь соберем библиотеку и пример на целевой машине. Запускать приложение нужно или с sudo или осуществив предварительную настройку. У меня мигает, а у вас?

Теги:

qt



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

  1. Zuy
    /#22898996

    А без всяких библиотек просто через /sys/class/gpio чем не подошло? Или в Orange PI нету стандартных драйверов GPIO в линуксе?

    • ktod
      /#22899424

      Емнип, есть. Но, через gpio нормально не назначить альтернативные функции выводам. Т.е. все, на что годен gpio — это именно что подрыгать ножкой. Достаточно для «Hello, world!», но мало для.

  2. bombe
    /#22900672

    В качестве системы сборки я выбрал qmake.

    Без претензий лично к Вам, но начиная с Qt6 основной будет система сборки CMake: doc.qt.io/qt-6/qt6-buildsystem.html

    • DungeonLords
      /#22900678

      Вы совершенно неправы. Qt 6 уже доступен — сходите попробуйте, потом расскажете про qmake.

      • bombe
        /#22908668

        У меня установлен и пятый и шестой Qt. Я пробовал шестой. QtCreator и CLion по дефолту используют cmake при создании нового проекта. И если первой ссылки не достаточно: www.qt.io/blog/qt-6-build-system

        CMake is the build system for Qt 6

        The CMake build system is now the default one

        p.s. Я не утверждаю, что qmake нельзя. Я утверждаю, что Qt переходит на cmake вместо qmake

        • DungeonLords
          /#22911248

          Зайдите в Qt Creator в Kits. Что у вас прописано в "Qt Versions"?
          Какой-то не нужный qmake? Вот и удалите его, на CMake же перешли. Ну что, собирается?

          • bombe
            /#22911878

            По моему, Вы просто путаете понятия версий и системы сборки. А так же просто не открывали те два линка что я постил выше (оба с официального сайта Qt, попрошу заметить). Где английским по белому написано, что дефолтная система сборки — cmake. Даже написано, что в шестой версии что бы собрать проект с qmake — надо указать аргумент --qmake, иначе будет использована дефолтная (угадаете какая?).
            Вы же мне предлагаете заняться полной дичью и удалить компонент фреймворка (который, по факту мной не используется): у меня всё прекрасно собирается и с cmake

            Скрытый текст
            19:41:33: Running steps for project SomeQtProject...
            19:41:33: Starting: "/usr/bin/cmake" --build . --target all
            [0/2 ?/sec] Re-checking globbed directories...
            [1/6 2.5/sec] Automatic MOC and UIC for target SomeQtProject
            [2/6 5.0/sec] Generating ~/projects/tmp/SomeQtProject/SomeQtProject_en_US.ts
            Scanning directory '~/projects/tmp/SomeQtProject'...
            Updating '../../SomeQtProject/SomeQtProject_en_US.ts'...
            Found 3 source text(s) (0 new and 3 already existing)
            [3/6 0.8/sec] Building CXX object CMakeFiles/SomeQtProject.dir/SomeQtProject_autogen/mocs_compilation.cpp.o
            [4/6 1.0/sec] Building CXX object CMakeFiles/SomeQtProject.dir/main.cpp.o
            [5/6 1.1/sec] Building CXX object CMakeFiles/SomeQtProject.dir/include/Window/mainwindow.cpp.o
            [6/6 1.1/sec] Linking CXX executable SomeQtProject
            19:41:38: The process "/usr/bin/cmake" exited normally.
            19:41:38: Elapsed time: 00:06.