Вот и пролетело два месяц с моей последней публикации на блоге. Всё время отнимает моя новая работа, на которой я наконец-то полностью занимаюсь своим направлением, а именно — программированием. Да не просто программирование, а программированием железяк. Пока что их было две. Это две платы на процессорах ARM: sbc2440 (ARM9) и более мощная IDEA6410(ARM11). Они очень похожи на FriendlyARM MINI2440 и MINI6410 соответственно. Обе платы идут с набором некоторых операционных систем. Обе поддерживают как Linux так и WindowsCE, а на IDEA6410 пойдет и Ubuntu. Но как ни странно предустановлена на IDEA6410 оказалась операционная система WIndowsCE, а с sbc2440 всё нормально — не очень новенький Linux с Qtopia.
В данной статье рассматривается установка на плату QT версии 4.5. Необходимость в этом возникла когда окончательно было принято решение, что будем разрабатывать программы на эти платы под операционную систему Linux и в качестве фреймворка, а лучше сказать кросс-платформенной разработки\отладки выбрали QT. Версия QT на данный момент 4.8, но версия выбиралась от поддерживаемого компилятора на плате. Для сборки данной библиотеки под плату использовался компилятор arm-linux-g++ версии 3.4.1. По незнанию, я пытался собрать версию QT 4.5.2 с помощью компилятора 4.3.2, но при сборке благополучно сыпались ошибки. Установка компилятора не должна вызывать трудностей, надо лишь распаковать архив и прописать путь к нему:
tar -xjvf arm-linux-gcc-3.4.1.tar.bz2 export PATH=/usr/local/arm/3.4.1/:$PATH
В моем случае «3.4.1» это ссылка на папку в которой располагается содержимое архива компилятора. После того, как требуемый компилятор настроен можно начинать собирать библиотеку tslib, а затем Qt на ARM плату. tslib является драйвером тачскрина, с помощью него Qt будет отлавливать «клики» на экране.
tar xzvf tslib.tar.gz cd tslib/ ./autogen.sh
После чего необходимо редактирование файла «configure». В строке «ac_cv_func_malloc_0_nonnull=no» заменить «no» на «yes». Эта строка находиться в следующем блоке текста:
{ $as_echo " $as_me :$LINENO : checking for GNU libc compatible malloc " >&5 $as_echo_n "checking for GNU libc compatible malloc… " > &6 ; } if test "${ac_cv_func_malloc_0_nonnull+set} " = set ; then $as_echo_n "(cached) " > &6 else if test "$cross_compiling" = yes ; then ac_cv_func_malloc_0_nonnull=no
Осталось сконфигурировать и собрать:
./configure CXX=/usr/local/arm/3.4.1/bin/arm-linux-g++ CC=/usr/local/arm/3.4.1/bin/arm-linux-gcc --host=arm-linux --target=arm --prefix=/usr/local/tslib make sudo make install
После удачной сборки tslib можно собирать QT с подключеным tslb. Такая сборка длиться несколько часов, а в итоге весит примерно 70 мегабайт. Так что на плату QT влезет в полном объеме. Самое главное не забыть перед ./configure убрать оптимизацию и прописать путь к компилятору. Итак, первое распокавать архив и перейти в него:
tar zxvf ../qt-embedded-linux-opensource-src-4.5.2.tar.gz cd qt-embedded-linux-opensource-src-4.5.2/
Отредактировать файлы следующим образом:
./mkspec/common/g++.conf - заменить все -O2 -O1 и так далее на -O0 ./mkspec/qws/linux-arm-g++/qmake.conf - прописать путь к компилятору
Вот как выглядел мой файл qmake.conf:
# # qmake configuration for building with arm-linux-g++ # include(../../common/g++.conf) include(../../common/linux.conf) include(../../common/qws.conf) TOOLS_BIN = /usr/local/arm/3.4.1/bin # modifications to g++.conf QMAKE_CC = $$TOOLS_BIN/arm-linux-gcc QMAKE_CXX = $$TOOLS_BIN/arm-linux-g++ QMAKE_LINK = $$TOOLS_BIN/arm-linux-g++ QMAKE_LINK_SHLIB = $$TOOLS_BIN/arm-linux-g++ # modifications to linux.conf QMAKE_AR = $$TOOLS_BIN/arm-linux-ar cqs QMAKE_OBJCOPY = $$TOOLS_BIN/arm-linux-objcopy QMAKE_STRIP = $$TOOLS_BIN/arm-linux-strip QMAKE_CFLAGS_RELEASE ~=s/-O[123s]/-O0/ QMAKE_CXXFLAGS_RELEASE ~=s/-O[123s]/-O0/ load(qt_config) QMAKE_CFLAGS_RELEASE ~=s/-O[123s]/-O0/ QMAKE_CXXFLAGS_RELEASE ~=s/-O[123s]/-O0/
Ну и запустить конфигурацию, компиляцию и установку, которая у меня длилась не один час:
./configure -embedded arm -xplatform qws/linux-arm-g++ -prefix /usr/local/Qt -qt-mouse-tslib -L /usr/local/tslib/lib -I /usr/local/tslib/include make sudo make install
Если вы дождались окончания и увидели, что всё прошло успешно, то можно брать библиотеки QT и tslib и кидать их на плату. Найти всё можно тут:
/usr/local/Qt/lib/libQt* /usr/local/tslib
Теперь можно попробовать на плате. При тестировании очень удобно если плата загружается по сети. Так сделано и у меня, расшарил папку по nfs, закинул туда файловую систему. Для того, чтобы плата смогла загрузиться по nfs надо остановить загрузчик Uboot и изменить его параметры загрузки. Делается это следующим образом: плата подключается по последовательному порту к компьютеру, далее через терминал соединяемся с платой и включаем её. Обычно на таких платах несколько COM-портов и эта не исключение, на ней их 4. С каким портом по умолчанию общается плата надо смотреть в инструкции, там же написано и параметры подключения через терминал:
- Скорость: 115200
- Данные: 8
- Стоп-биты: 1
- Четность: None
- Управление: None
После включения платы на терминале будет информацию о загрузчике и сообщение информирующее о том, что если вы хотите прервать загрузку нажмите любую клавишу. При этом сообщение обычным делом является отсчет обратного времени до продолжения загрузки. Вот в этот момент и надо нажать любую клавишу, чтобы попасть в загрузчик и изменить способ загрузки. Если вы успели нажать, то у вас должно быть что-то подобное как у меня на моей sbc2440:
U-Boot 2008.10 (Jun 18 2009 - 17:34:23) DRAM: 64 MB Flash: 1 MB NAND: 128 MiB In: serial Out: serial Err: serial Hit any key to stop autoboot: 0 mini2440 #
Когда в первый раз увидел тут «mini2440» сразу подумалось про FriendlyARM Mini2440, с которой у SBC2440 очень много сходств. Собственно и искался аналог или сама mini. Тут следует ввести команду help и получить список всех команд поддерживающихся загрузчиком:
mini2440 # help ? - alias for 'help' autoscr - run script from memory base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol bootvx - Boot vxWorks from an ELF image cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation date - get/set/reset date & time dcache - enable or disable data cache auto testecho - echo args to console erase - erase FLASH memory flinfo - print FLASH memory information go - start application at address 'addr' help - print online help icache - enable or disable instruction cache iminfo - print header information for application image imls - list all images found in flash imxtract- extract a part of a multi-image itest - return true/false on integer compare loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nand - NAND sub-system nboot - boot from NAND device nfs - boot image via network using NFS protocol nm - memory modify (constant address) ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables protect - enable or disable FLASH write protection rarpboot- boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage setenv - set environment variables sleep - delay execution for some time tftpboot- boot image via network using TFTP protocol version - print monitor version mini2440 #
Как видно список не очень то и маленький. Но из всего пригодятся только две команды:
printenv - print environment variables setenv - set environment variables
Командой setenv необходимо изменить переменную bootargs имеющую первоначальный вид:
bootargs=noinitrd root=/dev/mtblock2 init=/linuxrc console=ttySAC0,115200
Заменить следующим образом и начать загрузку:
mini2440 # setenv bootargs console=ttySAC0 init=linuxrc root=/dev/nfs nfsroot=192.168.1.21:/armnfs/s3c2440_recover/nfs-nogui ip=192.168.1.168:192.168.1.21:192.168.1.1:255.255.255.0:www.embedinfo.com:eth0:off mini2440 # boot
После успешной загрузку файлы имеющие имена libQt были скинуты в папку lib файловой системы, а все из папке /usr/local/tslib скопировать в корень файловой системы. Для правильной работы tslib надо добавить в файл /etc/ts.conf строку «module_raw h3600». То есть выглядеть должно примерно так:
module_raw h3600 module pthres pmin=1 module variance delta=30 module dejitter delta=100 module linear
И добавить следующие переменные в файл «/etc/qt4_env.conf»:
export TSLIB_TSEVENTTYPE=H3600 export TSLIB_CONSOLEDEVICE=none export TSLIB_FBDEVICE=/dev/fb0 export TSLIB_TSDEVICE=/dev/h3600_tsraw export TSLIB_CALIBFILE/etc/pointercal export TSLIB_CONFFILE=/etc/ts.conf export TSLIB_PLUGINDIR=/lib/ts export QWS_MOUSE_PROTO=tslib:/dev/h3600_tsraw
Теперь самое интересное, набрал в командной строке ts_calibrate и получил:
Далее можно поиграться с калибровкой:
Далее написал GUI приложение на qt под linux desktop скомпилировал под плату, скопировал в файловую систему расшареную по nfs и запустил через терминал:
В завершение фото самой платы:
Также это самое приложение было еще скомпилировано под настольную версию Linux (а именно Ubuntu), эмулятор qvfb и Windows 7. Всё заработало без проблем.
Как найду сделанные скриншоты на разных платформах: убунту, кьювбф и виндовс так сразу выложу
Тестирование скорости работы приложения написанного на Qt в двух разных вариантах: когда файловая система загружена по nfs и когда она располагается во флеш. Первое — загружена по nfs:
Второе — располагается во флеш:
Для меня было удивлением когда разница в скорости очень заметна на глаз. Ведь приложение при его запуске копируется в ОЗУ платы и исполняется оттуда. Следовательно, скорость работы должна быть одинакова, отличаться должен старт самого приложения, то есть загрузка его в ОЗУ пройдет намного быстрее из внутреннего флеша (памяти) платы, чем по сети.