Показаны сообщения с ярлыком ARM. Показать все сообщения
Показаны сообщения с ярлыком ARM. Показать все сообщения

четверг, 14 января 2010 г.

linux4sam: соображения о работе с TFT LCD

Идея о подключении экранчика к плате на AT91SAM9260 уже давно витает в воздухе. Товарищь alfamayonez.ru, героически повторив подвиг народных умельцев, показал возможность работы по SPI с дисплеем от телефона samsung s65. Однако, такое решение сложно использовать для дальнейших разработок из-за ограниценных размеров самого экрана, а во вторых, чтобы это"счастье" обновлялось с более/менее приемлемой скоростью ему надо отдавать шину SPI полностью, а она нам может ещё понадобится. Вопрос состоит в следующем: можно ли, и если да, то как подключить к нашей плате дисплей размером в несколько дюймов, доступный для покупки, без больших костылей и без большой загрузки ЦП.
После двух дней изучения гугла на предмет того, что у нас вообще бывает, получилась вот какая картина.

1. У нас бывает VGA. Есть чипы по преобразования цифры в VGA, но этот вариант я не рассматриваю т.к.  имеем мы дело не с аналоговым монитором, и как-то странно использовтаь для цифровой панели аналоговый интерфейс. К тому же, большинство панелей с цифровым интерфейсом, а с VGA уже идут мини-мониторы, которые существенно дороже.

2. Extended Bus Interface (EBI). Такая шина присутствует на нашем контроллере и предназначения для подключения переферии типа CompactFlash, SDRAM и много чего ещё (см. datasheet). На некоторых дисплеях, как правило до 3-5 дюймов, есть 16-ти битный параллельный интерфейс. И при беглом взгляде он совместим с EBI. Т.е. в таком случае получается всё просто, берём LCD с таим интерфейсом и напрямую вешаем на EBI. Проблема в том, что такая шина есть только у LCD с малой диагональю. По крайней мере я не видел этой шины у дисплеев с диагональю 7' и выше.

3. Ещё бывает RGB. Цифровой параллельный интерфейс, где используются несколько служебных сигналов, и шина данных, шириной в (разрядность одного цвета)х3, где за один такт передаётся значение R, G и B для одного пикселя. В подробности работы не вникал, но судя по всему, вывод на экран осуществляется просто последовательной передачей данных для каждого пикселя от первого до последнего. Если требуются большие расстояния, то можно постараться и найти чип для преобразования этой шины в LVDS и обратно. Ещё одна главная особенность состоит в том, что мы не можем напрямую подключить эту шину к нашему контроллеру, необходимо нечто вроде "видеокарты", которая и будет заниматься полной перерисовкой, а мы бы только записывали в память картинку, которую хотим отобразить. Первое, что пришло на ум, так это поискать интерфейс EBI<->RGB. Оказалось, что это вещь весьма экзотическая. Из того, что наиболее близко к этой задаче нашел решение на fpga от Altera (Avalon LCD Controller), но сомневаюсь что такую штуку будет легко достать. Т.о. в нашем случае остаётся практически один выход, это использование микроконтроллера со встроенным контроллером LCD. Благо, это уже не редкость, и имеется в МК тойже линейки AT91SAM9263.

Сухой остаток: если достаточно дисплея до 5-ти дюймов, то можно использовать EBI, если же хочется чего-то большего, то надо менять контроллер. Все остальные решения будут слишком хлопотными и дорогими.

пятница, 9 октября 2009 г.

Cross compiling toolchain своими руками

Любопытство, довольно затратная, но интересная штука. Если не отмахиваться от него, то можно давольно далеко зайти только от того, что тебе интересно. Just for fun, как говорят на западе :)

Необходимые пояснения
Когда я только-только начинал думать о кросс-компиляции, мне были непонятны самые элементарные вещи, наподобии того, как происходит эта компиляция, нужен ли специальный компилятор, если gcc знает разные архитектуры, то можно ли и как его научить собирать код под них?? Не помню, нашел ли я где-то прямой ответ, но если взять сухой остаток, то получим следующее:
Для сборки под другую платформу нам необходим компилятор, собранный таким образом, чтобы работать на нашей платферме, а генерить бинарники под целевую (target), что очевидно. Потом, есть архитектура как такавая (x86, ARM, etc..) и есть различные её модификации (или ядра, варианты, типы процессора, не знаю как точно назвать), это i386, i586, etc. Архитектура включает в себя модификации, т.е. компилятор, собранный под x86 теоретически умеет делать бинарник под любой процессор данной архитектуры. Что значит "компилятор, собранный под архитектуру"? Это значит, что тип архитектуры, под которую компилятор будет собирать бинарники, определяется при сборке компилятора. Есть комерческие кросскомпиляторы, которые, по всей видимости, представляют из себя обыкновенный gcc с особыми параметрами сборки и, может, какими специфическими патчами. Собственно вопрос, на который я хочу ответить - "можно ли, вряв исходники обычного компилятора, и того, что ему там ещё надо по зависимостям, собрать мало-мальски нормальный кросс-компилятор с нуля?". Ответ - да, и далее я приведу общую методику сборки, которая, я надеюсь, применима для сборки под любую другую архитектуру. В конце заметки есть ссылка на архив с поправленными/искалеченными spec-ами и дополнительными патчами. Я не буду отдельно расписывать параметры сборки, ибо это всё есть в spec-ах.

Используемые версии
И так, мы будем собирать rpm-based toolchain для ARM на базе ALTLinux. Пакеты, для сборки стянуты из актуальной версии branch 5.0. Вот то, что нам понадобится:
binutils-2.18.50.0.9-alt5.src.rpm
gcc3.4-3.4.5-alt8.src.rpm
glibc-kernheaders-2.6.27-alt3.src.rpm
glibc-2.3.5-alt5.src.rpm
gcc4.3-4.3.2-alt9.src.rpm
glibc-2.9-alt5.src.rpm

Собираем binutils
Тут всё просто, как оказалось в дальнейшем. Надо лишь дополнительноуказать опцию --target при сборке и указать пути. В нашем случае это arm-alt-linux-gnueabi-, если мы хотим получить eabi-компилятор. Везде далее в качестве target используется эта же цель. С путями получилась засада, с одной стороны я хз какие они должны быть, а с другой от версии к версии компилятора расположение файлов "по умолчанию" отличается, что тоже вносит путаницу. Я выбрал общий префикс для всех пакетов /usr/lib/arm, по которому располагается структура катологов компилятора. Похоже, что сами собираемые утилиты уже расчитаны на более тесную и корректную интеграцию с системой без дополнительного префикса, но я этот момент не осилил.

Собираем gcc-3.4
Отрезаем всё, что можно отрезать, и что мешается нам при сборке. Любой ценой собираем минимальный компилятор для С. Без плюсов, без библитек, без потоков. Для всего этого понадбятся glibc, которых у нас сейчас ещё нет. Почему версия 3.4, чуть позже.

Собираем glibc-kernheaders
Тут тоже практически без приключений, просто установка нужных исходников по нужному пути, совсем не большая правка spec-а.

Собираем glibc-2.3.5
Берём наиболее старую версию glibc, доступную в репозитории, исключительно из-за того, что онаотносительно легко собирается с потоками linuxthreads. Для сборки posix-потоков нужны glibc. Сборку надо пройти также любой ценой и любыми патчами/костылями. Более новую версию glibc-2.5.1 с linuxthreads мне собрать не удалось, а более старые не собираются gcc4 и выше, т.о. чтобы собрать glibc-2.3.5 нужен С-компилятор gcc-3.4.

Собираем gcc4.3
В черновую. Но тем не менее, сейчас нам окружение уже позволяет собрать C и C++ компиляторы с поддержкой потоков. При сборке компилятор ешё собирает какие-то свои либы, и возникли проблемы с передачей параметров этим либам. Кастыли в приложеном архиве эту проблему устраняют.

Собираем glibc-2.9
И наконец, делаем рывок, и собираем последнюю версию glibc. При первой сбрке придётся отрезать пару вещей (патчи прилагаются), чтобы эта сборка прошла. Неприятности вызваны тем, что gcc4 собран со старыми glibc, пересоберём его

Повторная сборка gcc4.3 и glibc-2.9
И последний этап - "чистовая" сборка компилятора и glibc. На этом этапе проблем быть практически не должно, а некоторые кастыли, которые мы подставили по glibc на прошлом этапе, сейчас можно убрать.
Да, я не говорю о том, что после очередной сборки пакета мы сначала должны его установить, и лишь после этого продолжать сборку другого пакета.
И так, сухой остаток, мы имеем  arm-binutils-2.18.50.0.9-alt5, arm- glibc-kernheaders-2.6.27-alt3, gcc4.3-4.3.2-alt9, arm-glibc-2.9-alt5, т.е. весьма свеженькие версии в toolchain, которые ещё и могут быть собраны с нашими специфическими опциями. Работа данного toolchain пока проверена только на сборке ядра 2.6.27 и busybox. Сборка этих компонент прошла успешно, вылезел ли что при дальнейшей эксплуатции - неизвестно.

Известные проблемы
При сборке пакетов не работает AutoReq, пришлось отключить. Пути, по которым устанавливается toolchain, хоть и являются болееменее рабочими, но не являются правильными. При сборке glibc нет возможности корректно запустить тесты, но вроде работает без них (знаю что косяк, но осилить не могу).
Спасибо за внимание, надеюсь что мой небольшой опыт сможет кому-нить помочь.
P.S. Да, обещанная ссылка - http://galilley.at.nsu.ru/toolchain-addon.tar.bz2

понедельник, 16 марта 2009 г.

linux4sam: загрузка по сети

И так, начинаем осуществлять обозначенный ранее план.
Очевидно, было бы глупо сразу бросаться и перепрошивать флешку, или, что ещё хуже, сам контроллер. Операции эти весьма рискованны, и потому будем начинать с наименее рискованных, тем более что u-boot предоставляет широкие возможности.
Речь пойдёт о загрузке по сети.
Сразу скажу, что более подробную информацию о опциях u-boot и его возмжностях можно найти в соответствующей вики на http://www.denx.de/wiki/DULG/Manual, а дальше же пойдёт описание того, с чем мне непосредственно пришлось столкнуться. И так, с помощью u-boot, похоже, можно загрузиться с чего угодно: встроенной NAND Flash, внешней MMC (слабо могу представить), COM-порта, Ethernet. Сама процедура загрузки состоит в следующем - с помощью команд u-boot копируем ядро и корневую файловую систему в память, и передаём управление на первый адрес. Чтобы ядро прошло эту процедуру, его после сборки надо обработать одной утилитой, идущей вместе с u-boot. О тонкостях компиляции ещё будет написано, по этому сейчас в это не углубляемся.
U-boot-у можно установить различные переменные окружения и последовательность команд, которые он выполнит перед тем, как передаст управления ядру. При этом загрузчик умеет сохранять внесённые параметры... видимо во флеш МК. И так, что же мы имеем:
U-Boot> printenv

bootcmd=run boot_df
bootdelay=3
baudrate=115200
tftp_update=tftpboot 20400000 zlinux; cp.b 20400000 c0038000 170000; tftpboot 20400000 rf
tftp_boot=tftpboot 20400000 zlinux; tftpboot 21100000 rootfs; bootm 20400000
boot_df=cp.b c0038000 20400000 170000; cp.b c01a8000 21100000 277fff; bootm 20400000
ipaddr=192.168.0.136
netmask=255.255.255.0
ethaddr=00:1f:f2:00:00:00
serverip=192.168.0.2
stdin=serial
stdout=serial
stderr=serial
- по сути, для нас подготовили три режима. 

    1. режим по-умолчанию - boot_df - копирования ядра и корневой фс в память с флешки и запуск. 
    2. tftp_boot - загрузка по сети - копирования ядра посредством tftp в память и запуск. tftp настроен в эмуляторе, но перенос его на локальную машину не составляет никакого труда - надо лишь установить сервер, настроить xinetd, положить образ ядра и фс в папку tftp. В принципе, пожно даже подцепить к этому делу dhcp, при этом вместо tftpboot следует пользовать bootp. 
    3. tftp_update - обновление ядра на плате - копирование с фтп в память, а из памяти во флеш, просто и удобно.

Надо сказать, что всё это скорее всего описано на соответствующем форуме, куда также можно обратиться.
Кроме таких плясок с перекидыванием ядра и rootfs туда-сюда есть ещё возможность подключить корневую фс прямо по сети посредством nfs, при условии что ядро сконфигурировано соответсвующим образом. Это наиболее интересный вариант, т.к. позволяет полностью избавиться на девайсе от всех устройств хранения, а сборку и отладку вести на "большой машине" оперативно контролируя результат.
И в заключении, ещё одна деталь - параметры ядра. Их также можно скормить u-boot, но разработчики почему-то пошли другим путём, и указали необходимые параметры непосредственно в ядро при сборке. По этому, скажем, если вы захотите изменить в памяти адрес расположения rootfs, то ядро будет в панике.

#cat /proc/cmdline
root=/dev/ram0 rw initrd=0x21100000,0x500000 console=ttyS0,115200 mem=32M
Продолжение следует.

суббота, 14 марта 2009 г.

linux4sam: введение

И так, не доведя до какого-либо конца ни одного из ранее начатых проектов, я подумал, что уже как-то тесновато на x86-ой архитектуре, и пора бы уже посмотреть в сторону чего-нить этакого.. И так, не вникая в детали и предыстории, в руках у меня оказалась оценочная плата на основе МК AT91SAM9260 архитектуры ARM с 32 Mb RAM и 4 Mb flash, с USB, Ethernet, COM, SPI и кучей DIO на борту. В качестве ОС на девайсе стоит Linux, а размеры платы всего 75x90 мм, что в совокупности открывает огромные возможности для практических применений. Но перво-наперво необходимо обеспечить базу, иначе говоря - производство подобных девайсов. Т.о. план на ближайшие 6-18 месяцев, это освоить производство подобных девайсов, прошивку и сбору ОС с нуля.
В комплекте с платой идёт компашка, на которой можно найти софт для прошивки (под винду, к сожалению, у нас-то весь процех будет построен на пингвине), софт для разработки и виртуальную машину с RHEL. Последнее представляет наибольший интерес. Внутри виртуалки находим архивы компилятора, u-boot, кое-какие патчи, настроенный tftp, и вроде какие-то ещё приятные мелочи. Т.е. в принципе, ничего того, чего нельзя было бы установить к себе в систему собственноручно из официальных источников.
По железу, прежде всего надо понять, как вообще всё это дело устроено. Если в плане написания софта и сборки дистриба всё более/менее понятно, то вот железо вызывает у меня много вопросов.
AT91SAM9260, контроллер с большим количеством встроенных интерфейсов, встроенным интерфейсом SRAM, CompactFlash, NAND Flash, ECC, и производительностью до 200 MIPS, т.е. проще говоря - "зверь-машина". Внешние интерфейсы являются определёнными, в том смысле, что USB он в любом случае USB, в отличии от количества памяти, которой может быть 32, 64 а может и больше, а может там ещё и флешка есть, а может и ещё какое устройство. Всё что касается подобных вопросов, отнесём к системной конфигурации МК. В datasheet эта часть называется EBI - External Bus Interface. Её настройка производиться путём установки нужных битов в нужных регистрах МК на самой начальной стадии после включения, т.е. на самом низком уровне. В этом состоит самая главная задача - привести схему в состояние, пригодное для дальнейшей работы, "опознать оборудование". Отвечающий за это код вынесен в отдельный проект - bootstrap. BootStrap собирается кроссплатформенным компилятором и прошивается непосредственно во внутреннюю память МК. После того, как bootstrap отработал, необходимо определить, откуда дальше вести загрузку, найти ядро, передать ему параметры и всё дальнейшее управление, сформировать адресное пространство. Этим занимается загрузчик u-boot. Его конфигурации будет посвящена отдельная заметка, когда до этого дойдёт дело. Сам же u-boot предоставляет возможность загрузки с NAND Flash, MMC, и даже по Ethernet. Прошивается загрузчик также во внутреннюю память МК, и принимает управление от bootstrap. И наконец, после того как отработает u-boot, уже начнётся загрузка ядра linux, а тут всё становится уже совсем просто и почти как на "большой машине".
Т.о. схема загрузки следующая bootstrap -> u-boot -> linux kernel.
Разбирать эту цепочку будем с хвоста, освоим загрузку по сети, пересборку ядра, создание окружения для кросскомпиляции.
Продолжение следует.