GSM/3G/4G-модемы во встраиваемых системах на примере LTE-модема Quectel EC21 и Yocto Project

от автора

image

Многим устройствам на базе встраиваемых систем необходим интернет. Проводное подключение к интернету для них не всегда возможно, и если устройства находятся в зоне действия сотовой связи, то к интернету можно подключиться с помощью GSM/3G/4G-модемов.

В этой заметке описан процесс создания дистрибутива ОС Linux для встраиваемой системы при помощи инструментария Yocto Project, позволяющий подключать устройство к интернету через GSM/3G/4G-модем и протокол PPP.

Содержание

Оборудование и программное обеспечение

Дистрибутив ОС Linux для встраиваемой системы будем собирать с помощью Yocto Project версии THUD 2.6.4 на ПК под управление ОС Ubuntu 18.04.

Роль встраиваемой системы будет играть устройство BeagleBone Black Rev. C с подключенным к нему LTE-модемом Quectel EC21-E. Для этого мы воспользуемся отладочным набором UMTS&LTE EVB для тестирования UMTS и LTE модулей Quectel. Структурная схема стенда, с которым мы будем экспериментировать, приведена на рис. 1.

image

Рисунок 1 — Структурная схема стенда

Подготовка ПК для сборки дистрибутива

Убедитесь, что на вашем ПК есть 50 ГБ свободного дискового пространства и на нем установлены:

  • Git версии 1.8.3.1 или новее;
  • Tar версии 1.27 или новее;
  • Python версии 3.4.0 или новее.

Установим необходимые пакеты:

$ sudo apt-get install gawk wget git-core diffstat unzip texinfo \                        gcc-multilib build-essential chrpath socat  \                        cpio python python3 python3-pip python3-pexpect \                        xz-utils debianutils iputils-ping libsdl1.2-dev xterm

На этом подготовка ПК для сборки дистрибутива с использованием инструментария Yocto Project закончена. Любопытные читатели могут получить более подробную информацию ознакомившись с Yocto Project Quick Build.

Создание проекта и сборка дистрибутива

Создадим в домашней директории каталог, где у нас будет хранится репозитории Poky и мета-слои с рецептами. Назовем его habr-yocto-lte:

~$ mkdir habr-yocto-lte

Перейдем в директорию habr-yocto-lte и создадим пустой git репозиторий:

~$ cd habr-yocto-lte ~/habr-yocto-lte$ git init

Добавим в созданный git-репозиторий, в виде подмодулей, проект Poky и слой meta-ti:

~/habr-yocto-lte$ git submodule add -b thud git://git.yoctoproject.org/poky.git ~/habr-yocto-lte$ git submodule add -b thud git://git.yoctoproject.org/meta-ti

Poky это как раз тот самый инструмент, с помощью которого мы будем собирать наш дистрибутив, а meta-ti – это слой, который объединяет в себе наборы рецептов, классов и конфигурационных файлов для процессоров Texas Instruments. Подробнее о том, что такое Poky и мета-слои можно узнать из Yocto Project Overview and Concepts Manual.

Создадим файл oe-init-build-env и сделаем его исполняемым:

~/habr-yocto-lte$ touch oe-init-build-env ~/habr-yocto-lte$ chmod +x oe-init-build-env

Добавим в него следующий код:

#!/bin/sh source $(pwd)/poky/oe-init-build-env build

Файл oe-init-build-env мы будем запускать всякий раз, при открытии нового окна терминала. Давайте запустим его командой:

~/habr-yocto-lte$ source ./oe-init-build-env

При первом выполнении скрипта в папке ~/habr-yocto-lte будет создана папка build, содержащая конфигурационные файлы и результаты сборки дистрибутива, а в окне терминала мы увидим нечто вроде этого:

### Shell environment set up for builds. ###  You can now run 'bitbake <target>'  Common targets are:     core-image-minimal     core-image-sato     meta-toolchain     meta-ide-support  You can also run generated qemu images with a command like 'runqemu qemux86'

В принципе, теперь у нас все готово для сборки дистрибутива, но мы сделаем еще несколько «штрихов»:

  • Добавим слой meta-ti и удалим слой meta-poky-bsp. Для этого запишем в переменную BBLAYERS, которая находится в файле ~/habr-yocto-lte/build/conf/bblayers.conf, следующее значение:

BBLAYERS ?= " \         /home/alex/habr/poky/meta \         /home/alex/habr/poky/meta-poky \         /home/alex/habr/meta-ti \         "

  • В качестве целевой системы, на которой будет работать наш дистрибутив выберем beaglebone. Разрешим запись истории сборки, это поможет нам понять какие пакеты были установлены в дистрибутив, узнать их размер и др. Формат пакетов сделаем ipk и разрешим модули ядра. Вместо sysvinit будем использовать systemd. Обновим конфигурацию дистрибутива, добавив в конец файла ~/habr-yocto-lte/build/conf/local.conf следующие строки:

MACHINE = "beaglebone" INHERIT += "buildhistory" BUILDHISTORY_COMMIT = "1" PACKAGE_CLASSES = "package_ipk" CORE_IMAGE_EXTRA_INSTALL += " kernel-modules" DISTRO_FEATURES_append = " systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit" VIRTUAL-RUNTIME_init_manager = "systemd" VIRTUAL-RUNTIME_initscripts = "systemd-compat-units"

Запустим сборку дистрибутива:

~/habr-yocto-lte/build$ bitbake –k core-image-base

Пока собирается дистрибутив можете пойти вздремнуть, у вас есть на это часа 4 :). Потом будет собираться всё гораздо быстрее.

Дистрибутив сохранится в каталоге ~/habr-yocto-lte/build/tmp/deploy/images/beaglebone

Добавление поддержки протокола PPP в ядро ОС

Устройство, на котором будет установлен дистрибутив, созданный в предыдущем разделе, уже сможет распознать LTE-модуль Quectel EC21-E, т.к. его драйвера есть в ядре Linux. Однако для подключения устройства к интернету нам необходимо добавить поддержку протокола PPP в ядро Linux, а также добавить в наш дистрибутив пакет ppp и написать для него файл расширения рецепта, который «расскажет» bitbake как и куда установить в нашем дистрибутиве необходимые файлы для pppd и chat, являющиеся частью пакета ppp.

Для конфигурирования ядра выполним команду:

~/habr-yocto-lte/build$ bitbake virtual/kernel -c menuconfig

Откроется стандартное окно menuconfig в котором надо выбрать:

Device drivers --->     [*] Network device support --->         <M> PPP (point-to-point protocol) support             <M> PPP BSD-Compress compression             <M> PPP Deflate compression             <*> PPP filtering             <M> PPP MPPE compression (encryption)             <*> PPP multilink support             <M> PPP over Ethernet             <M> PPP support for async serial ports             <M> PPP support for sync tty ports 

Сохраняем конфигурацию и выходим из menuconfig. Учтите, что эта конфигурация будет применяться только на том ПК, на каком она была сохранена. Для того что бы она применялась на любом ПК при клонировании проекта из репозитория, необходимо сохранить конфигурацию в файле defconfig и написать рецепт расширения для recipes-kernel.

Сохраним конфигурацию ядра в файле defconfig:

~/habr-yocto-lte/build$ bitbake virtual/kernel -c savedefconfig

Файл defconfig сохранится в каталоге ~/habr-yocto-lte/build/tmp/work/beaglebone-poky-linux-gnueabi/linux-ti-staging/4.19.94+gitAUTOINC+5a23bc00e0-r22a/build

Все рецепты расширения и рецепты, написанные нами, будем хранить в отдельном мета-слое. Создадим и назовем его meta-habr:

~/habr-yocto-lte/build$ bitbake-layers create-layer ~/habr-yocto-lte/meta-habr

В каталоге ~/habr-yocto-lte появится директория meta-habr – это и есть наш мета-слой. В этой директории будет пример рецепта recipes-example, он нам не нужен, удалим его, а затем добавим наш мета-слой в файл bblayers.conf:

~/habr-yocto-lte/build$ rm -r ~/ habr-yocto-lte/meta-habr/recipes-example/ ~/habr-yocto-lte/build$ bitbake-layers add-layer ~/habr-yocto-lte/meta-habr

Пришло время сделать рецепт расширения для ядра Linux. Создаем необходимые каталоги и файлы:

~/habr-yocto-lte$  mkdir – p meta-habr/recipes-kernel/linux/linux-ti-staging/beaglebone ~/habr-yocto-lte$  touch meta-habr/recipes-kernel/linux/linux-ti-staging_%.bbappend

Копируем ранее созданный файл defconfig в каталог ~/habr-yocto-lte/meta-habr/recipes-kernel/linux/linux-ti-staging/beaglebone

~/habr-yocto-lte$ cp ~/habr-yocto-lte/build/tmp/work/beaglebone-poky-linux-gnueabi/linux-ti-staging/4.19.94+gitAUTOINC+5a23bc00e0-r22a/build/defconfig  meta-habr/recipes-kernel/linux/linux-ti-staging/beaglebone

и добавляем в файл linux-ti-staging_%.bbappend следующий код:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" SRC_URI += "file://defconfig"

Теперь конфигурация ядра, определенная в файле defconfig будет применяться всегда при сборке дистрибутива. Соберём его и убедимся, что требуемые модули PPP установлены:

~/habr-yocto-lte/build$ bitbake –k core-image-base ~/habr-yocto-lte/build$ cat buildhistory/images/beaglebone/glibc/core-image-base/installed-packages.txt | grep "ppp" -------------------------------------------------------- kernel-module-ppp-async-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk kernel-module-ppp-deflate-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk kernel-module-ppp-generic-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk kernel-module-ppp-mppe-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk kernel-module-pppoe-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk kernel-module-pppox-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk kernel-module-ppp-synctty-4.19.94-g5a23bc00e0_4.19.94+git0+5a23bc00e0-r22a_beaglebone.ipk

Добавление в дистрибутив пакета ppp

Пакеты программ добавляются в дистрибутив с помощью переменной IMAGE_INSTALL_append. Добавим её в конец файла local.conf и присвоим ей значение соответствующее имени пакета:

IMAGE_INSTALL_append = " ppp"

Соберём дистрибутив и убедимся, что пакет ppp установлен:

~/habr-yocto-lte/build$ bitbake –k core-image-base ~/habr-yocto-lte/build$ cat buildhistory/images/beaglebone/glibc/core-image-base/installed-packages.txt | grep "ppp_" -------------------------------------------------------- ppp_2.4.7-r0_beaglebone.ipk

Теперь в нашем дистрибутиве есть все для того чтобы подключить устройство к интернету через LTE-модем. Однако мне лично не очень хочется настраивать pppd и chat, входящие в пакет ppp, непосредственно на устройстве. Поэтому давайте добавим необходимые скрипты для этих программ в наш дистрибутив с помощью расширения рецепта ppp.

Скрипты для pppd и chat

Создадим три файла скриптов habrppp, habr-chat-connect и habr-chat-disconnect со следующим содержимым:

  • habrppp
    /dev/ttyUSB3 921600 user "beeline" password "beeline" connect 'chat -s -v -f /etc/ppp/peers/habr-chat-connect' disconnect 'chat -s -v -f /etc/ppp/peers/habr-chat-disconnect' hide-password noauth debug defaultroute noipdefault persist
  • habr-chat-connect
    ABORT "BUSY" ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" TIMEOUT 30 "" AT OK ATE0 OK ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;&D2 OK AT+CGDCONT=1,"IP","static.beeline.ru",,0,0 OK ATD*99# CONNECT ""
  • habr-chat-disconnect
    ABORT "ERROR" ABORT "NO DIALTONE" "" +++ "" +++ "" +++

Несколько комментариев по представленным выше скриптам.
LTE-модуль Quectel EC21-E определятся в системе в виде четырёх последовательных портов:

  • ttyUSB0 – порт отладки
  • ttyUSB1 – порт для сообщений GPS NMEA
  • ttyUSB2 – порт для AT-команд
  • ttyUSB3 – порт для установления соединения PPP

Если в вашей системе есть другие USB-устройства, то нумерация портов, возможно, будет отличаться от приведенной выше, но последовательность останется та же. Поскольку в нашей системе нумерация портов соответствует выше приведенной, то в скрипте habrppp мы указали в качестве порта для соединения по протоколу PPP порт /dev/ttyUSB3.

Обратите внимание на поля user и password в скрипте habrppp, а также на APN в команде AT+CGDCONT в скрипте habr-chat-connect, они должны быть установлены согласно рекомендациям сотового оператора.

Рецепт расширения для пакета ppp

Осталось совсем чуть-чуть. Создадим каталоги и файл для рецепта расширения ppp:

~/habr-yocto-lte$ mkdir –p meta-habr/recipes-connectivity/ppp/ppp/beaglebone ~/habr-yocto-lte$ touch meta-habr/recipes-connectivity/ppp/ppp_%.bbappend

Скопируем скрипты, написанные в предыдущем разделе в папку ~/habr-yocto-lte/meta-habr/recipes-connectivity/ppp/ppp/beaglebone и добавим следующее содержимое в файл ppp_%.bbappend:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"   SRC_URI += "file://habrppp \                          file://habr-chat-connect \                          file://habr-chat-disconnect \                          file://20-habr-modem.rules \                          "   do_install_append () {           install -m 0755 ${WORKDIR}/habrppp ${D}${sysconfdir}/ppp/peers/habrppp           install -m 0755 ${WORKDIR}/habr-chat-connect ${D}${sysconfdir}/ppp/peers/habr-chat-connect           install -m 0755 ${WORKDIR}/habr-chat-disconnect ${D}${sysconfdir}/ppp/peers/habr-chat-disconnect             mkdir -p ${D}${sysconfdir}/udev/rules.d              install -m 0755 ${WORKDIR}/20-habr-modem.rules ${D}${sysconfdir}/udev/rules.d/20-habr-modem.rules  } 

Вы, наверное, заметили, что к тем трем файлам скрипта добавился файл 20-habr-modem.rules. Это правило для udev, согласно которому при возникновении в системе порта ttyUSB3 будет автоматически запущена служба pppd с нужными нам настройками. Таким образом наше устройство будет всегда подключаться к интернету при подключении модема к USB-порту. Содержимое файла 20-habr-modem.rules:

SUBSYSTEM=="tty", KERNEL=="ttyUSB3", TAG+="systemd", ENV{SYSTEMD_WANTS}="ppp@habrppp.service"

Заключение и ссылка на проект

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

~$ ifconfig lo        Link encap:Local Loopback           inet addr:127.0.0.1  Mask:255.0.0.0           inet6 addr: ::1/128 Scope:Host           UP LOOPBACK RUNNING  MTU:65536  Metric:1           RX packets:0 errors:0 dropped:0 overruns:0 frame:0           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0           collisions:0 txqueuelen:1000           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)  ppp0      Link encap:Point-to-Point Protocol           inet addr:XXX.XXX.XXX.XXX  P-t-P:XXX.XXX.XXX.XXX  Mask:255.255.255.255           UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1           RX packets:13 errors:0 dropped:0 overruns:0 frame:0           TX packets:17 errors:0 dropped:0 overruns:0 carrier:0           collisions:0 txqueuelen:3           RX bytes:432 (432.0 B)  TX bytes:611 (611.0 B)

Подключением к интернету через протокол PPP можно управлять вручную, с помощью команд pon и poff. Для установления соединения выполните команду:

~$ pon habrppp

Для завершения соединения:

~$ poff habrppp


Проект доступен по адресу https://gitlab.com/amamaev/habr-yocto-lte. Для клонирования репозитория выполните команду:

~$ git clone --recursive https://gitlab.com/amamaev/habr-yocto-lte.git

Не забудьте скорректировать пути к слоям в файле bblayers.conf

ссылка на оригинал статьи https://habr.com/ru/post/494838/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *