Виртурилка для чайников - статья первая

Материал из virt2real wiki
Перейти к: навигация, поиск

(оригинал статьи был размещен 30 октября 2013 года по адресу http://virt2real.ru/content/145)

Всем привет!

В свое время мы писали на хабре http://habrahabr.ru/company/virt2real/blog/156491/ , что мы видим несколько уровней подготовки – начинающий, продвинутый и профи. Сейчас основные военные действия происходят в сфере «профи» и «продвинутых» - идут допилы линукса и делаются разные сборки, ковыряются драйвера, ловятся баги в работе шин и протоколов, кто-то разводит свои платы. И большинство пользователей с небольшим опытом программирования не знают, с какой стороны подступиться.

Поэтому я решил сделать первую статью для начинающих. Формат будет экспериментальный – мне важно услышать мнение пользователей, в том ли русле движемся или подачу материала нужно упростить/усложнить.

Манера статьи будет такая: мы возьмем один из продвинутых экспериментов с форума, и я расскажу как «с чистого листа» повторить эксперимент, какие инструменты-настройки понадобятся и зачем. А заодно пройдемся по имеющимся багам (несколько выловленных заботливо припасены для препарирования).

Итак, имеем: «базовый набор» виртурилки (плата + камера + WiFi) и чистую карточку MicroSD на 2 Гб, и хотим повторить эксперимент с трансляцией видео на устройство с Android.

Что будет в нашей статье:

  1. Делаем загрузочную карточку. Что это вообще, как работает, почему именно так.
  2. Загружаемся.
  3. Соединяемся с виртурилкой – что полезного в админке.
  4. Консоль – зачем нужна, с чем едят. Ловим первую багу. Делаем консоль, альтернативную консоли в админке, с помощью двух рецептов с форума.
  5. Gstreamer – что это такое, как упростить запуск. Тестируем передачу видео с виртурилки на компьютер.
  6. Приложение для Android – установка, настройка соединения с виртурилкой.


Работа будет идти в Ubuntu 12.04. В моем случае она живет на MacBook Pro в виде виртуальной машины (под Parallels 8), но это не сильно влияет на процесс.

Итак, поехали!


Содержание

Делаем загрузочную карточку.

Виртурилка – это маленький компьютер, на котором можно запускать операционную систему. Разумеется, систему эту нужно откуда-то загрузить. В нашем случае носителем будет выступать карточка MicroSD. Посмотреть актуальные версии прошивок всегда можно на форуме в специальной закрепленной теме "Свежие обновления в SDK и прошивках". Мы с вами сейчас работать мы будем вот с этой прошивкой: http://files.virt2real.ru/firmware/virt2real-board/1.1/04_10_2013_sdcard.img.zip от 04 октября.

Этот архив содержит в себе побитную копию карточки, сделанную специальным образом. Если брать аналогию с настольным компьютером, который умеет грузиться с HDD, компакт-диска или флэшки (иные способы не рассматриваем), то носитель должен быть специальным образом подготовлен. Например, если взять загрузочный образ CD или USB-флэшки и записать их на носитель как файл (например, просто «перетащив мышкой»), то система грузиться не будет. А все потому что загрузочный раздел, к которому обращается компьютер, должен располагаться в определенном месте носителя и правильно читаться компьютером.

Итак, что можно сделать неправильно на этом этапе: распаковать архив с прошивкой, подключить карточку через адаптер к компьютеру и просто скопировать файл на карточку. Виртурилка не загрузится.

Записать файл нужно правильным способом. Для Ubuntu, Windows и MacOS X процедура описана в вики Первое включение Виртурилки - Заливка прошивки.

Если вы будете использовать карточку MicroSD размером 2 Гб - обратите внимание на пометки в вики об известных проблемах.

Отмечу нюанс для маководов: на MacBook с ретиной кардридер реализован нестандартно – он в системе висит не как USB-устройство, а как pci-девайс. Выражается это в том, что запущенная под 8-м Parallels убунта не увидит кардридер, он туда просто «не пробрасывается».

Процедура записи карточки небыстрая – побитное копирование может занять больше 20 минут. Если извлечь карту раньше – она будет неработоспособна.

Важный момент: после окончания записи не забудьте корректно извлечь карточку («Извлечь» под Win, отмонтировать на маке или под убунтой).

Загружаемся

После того как карточка записана и корректно извлечена из компьютера – нужно установить ее в разъем на виртурилке. А затем подключить питание. Я во всех экспериментах буду питать виртурилку по USB от своего ноутбука.

Возможная проблема: постоянная перезагрузка виртурилки. Возникает из-за нехватки мощности источника питания. Случается на системах, в которых на USB висит несколько устройств. Чаще всего встречается на ноутбуках или старых настольных системах.

Через несколько секунд после подачи питания на виртурилке загорается синий светодиод – это значит, что система увидела питание и пошла загрузка. Зеленый светодиод показывает загруженность процессора – чем чаще мигает, тем выше загрузка.

V2r blue led.jpg


Информация для любознательных: а что будет, если сначала подать питание, а карточку с системой установить позже? Страшного ничего не будет. Поэкспериментируйте. ☺

Возможная проблема: синий светодиод не загорается, признаков жизни нет.

Все виртурилки перед отправкой тестируются на загрузку, поэтому рекомендуются следующие шаги по диагностике:

- извлечь карточку MicroSD и подключить ее к компьютеру. Она должна определиться и в системе должен появиться как минимум том с именем boot. Если не появился то, скорее всего, карточка прошилась некорректно. Нужно перепрошить карточку, повторив процедуру из раздела «Делаем загрузочную карточку»

- отключить от виртурилки модуль WiFi и шлейф камеры и попробовать загрузиться. Если загрузка прошла успешно – попробовать загрузиться только с WiFi и только с камерой. Вероятная проблема – «неполный» контакт WIFi или шлейфа камеры, когда либо модуль WiFi не до конца «вщелкнут», либо шлейф камеры не полностью или под легким углом установлен в разъем. Вот как выглядит запуск "раздетой" виртурилки:

V2r start nowifi nocamera 0.jpg


- экзотический случай – синий светодиод горит, а зеленый постоянно мигает с определенной периодичностью. Это один из случаев гибели карточки MicroSD – некоторые живут долго и счастливо, а некоторые «мрут» через день. В процессе загрузки попадается «битый» фрагмент – и идет постоянная попытка его прочитать. Спасает замена карточки на рабочую. Поэтому всегда рекомендую держать парочку карточек, одна из которых проверенная и «эталонная». Это сэкономит вам кучу времени при нестандартном поведении системы в будущем.


Соединяемся с виртурилкой

После того как виртурилка загрузилась, она включается в режим точки доступа WiFi. В эфире появляется WiFi сеть с именем virt2real

Вот как выглядит эта точка доступа в списке сетей (на андроиде):


V2r wifi network android 0.jpg


Или в списке сетей на Mac:


Wifi v2r mac 1.jpg


Подключиться к сети виртурилки можно с любого устройства.

Для этого нужно выбрать в списке точку доступа virt2real и ввести пароль 12345678


Итак, мы выбрали сеть WiFi с именем virt2real и ввели пароль - теперь мы на связи с виртурилкой.

Для подключения к админке достаточно в браузере ввести ее IP-адрес нашей платы virt2real. Как его узнать? На самом деле в этой прошивке он известен (ответ ниже), но давайте рассмотрим один простой рецепт, как его вычислить – на случай, если вы будете менять настройки WiFi на виртурилке в будущем.

Когда виртурилка работает в режиме точки доступа, она выдает подключившемуся устройству IP-адрес. При этом сама она имеет похожий IP-адрес, в котором последней цифрой является единичка. Т.е. чтобы узнать адрес виртурилки, достаточно посмотреть IP-адрес своего устройства, и заменить последнее число на «1».

Как посмотреть свой IP адрес на Android (в примере Android 4.1), присоединенном по WiFI к виртурилке

"Настройки" -> "О телефоне" -> "Общая информация", крутим вниз пока не увидим поле "IP-адрес":


V2r ip on android 2.jpg


Значит IP-адрес виртурилки 192.168.2.1


Как посмотреть свой IP-адрес на Ubuntu (помните что мы подключились к сети virt2real)

Запустите терминал и в нем наберите команду ifconfig.


Ubuntu.jpg


Стало быть, IP-адрес виртурилки 192.168.2.1

Как посмотреть свой IP на маке, если мы подключились по WiFi к виртурилке

На Mac можно воспользоваться терминалом как и на убунте, но для разнообразия дам "штатный" способ. Нажимаем на значок WiFi в статусной строке, выбираем самый нижний пункт "Открыть настройки сети...", видим:


Wifi macosx.jpg


И опять получаем, что IP виртурилки в данном случае 192.168.2.1

Заходим на виртурилку. В браузере набираем 192.168.2.1 и видим окошко, запрашивающее логин и пароль.


Adminka v2r.jpg


Вводим логин root и пароль root – и мы в админке.

В админке много полезного, но я сделаю акцент пока на одной вещи – встроенный редактор файлов. Он позволяет без лишних действий править файлы, находящиеся на карточке MicroSD, и сразу их сохранять. Живет он тут: "Управление" -> "Файл менеджер".

Консоль

Консоль это удобный инструмент для работы с системой в режиме командной строки. На настольных компьютерах многие операции быстрее и проще выполнить в консоли, чем искать нужное в графическом интерфейсе. В убунте достаточно запустить терминал, в Win-системах консоль вызывается запуском команды cmd (через «Пуск»-«Выполнить»). Линукс на борту виртурилки не включает в себя графическую оболочку, ибо виртурилка задумана как устройство, работающее «на удаленной стороне». Поэтому для выполнения большинства задач используется именно консоль.

В админку встроена консоль, которая позволяет без особых хлопот делать то, что нам понадобится. Давайте попробуем в нее зайти и выполнить, например, команду ls – посмотреть на файлики в директории, в которой мы находимся. Или команду top, показывающую список запущенных процессов.

Для этого идем в админке по ссылке "Управление" а затем "Консоль".

Мы должны увидеть черный фон консоли и строку-приглашение с мигающим курсором.

Как вы заметили, при переходе в консоль в админке некоторое время она не отображается – виден белый прямоугольник. Если подождать, то консоль наконец-то прорисуется.

Пробуем ввести команду ls. Ждем. Еще ждем. Дождались, ура! Консоль снова отображается, но только мы не видим выведенного результата работы. Пробуем команду top.

Опять ждем. Снова ждем. Готово! Только результата опять нет.

Поздравляю, мы с вами только что наткнулись на первый баг! :-) В следующих версиях прошивок он уже исправен. Суть такова: ява-скрипт, отвечающий за работу админки, прописан неверно и пытается подгрузиться с сайта google (https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js), а не локально с карточки. А так как виртурилка в базовой настройке к интернету не подключена – скрипт не подгружается и работает некорректно. Сразу скажу, что работающие с этой версией прошивки продвинутые юзеры на этот баг могли и не натолкнуться, т.к. обычно настраивают сетевое подключение несколько иначе (WiFi не в режиме точки доступа или через функционал usb Ethernet gadget – мы скоро к этому вернемся). Но мы с вами натолкнулись. Как быть?

Давайте запустим консоль другим способом, не через админку. И не через WiFi. И не через Ethernet. Мы используем соединение по USB с нашим компьютером, на котором и запустим консоль.

Что нам понадобится сделать:

  • настроим виртурилку так, чтобы при подключении к компу по USB она отзывалась как usb-serial
  • на настольном компьютере запустим терминал и настроим его на появившийся в системе порт
  • подключимся к виртурилке через этот терминал.

Чтобы получить требуемый результат, обратимся к еще одной теме на форуме (которая уже вынесена в вики). Первые пользователи виртурилки заметили, что при подключении ее к компьютеру последний выводит сообщение о том, что найдено некое новое устройство USB Ethernet Gadget. Вот эта тема: RNDIS/Ethernet Gadget Дело в том, что имеющийся на борту линукс можно настроить так, что при подключении по USB виртурилка может выдавать себя за самые разные устройства – сетевую карточку, кардридер и т.д. и т.п. Большинство пользователей настроили виртурилку в режиме сетевой карточки и работают с ней по сети «в обход» вайфая, и даже делают настройки по автоматическому переходу виртурилки с вайфая на usb-сетку, если вайфай вдруг «отвалился» (вот ссылка на обсуждение). Но нас интересует режим USB-serial, который мы сейчас и включим.

Для этого делаем следующее:

а) Указываем, чтобы при загрузке виртурилки грузился нужный нам модуль serial.

Для этого во встроенном редакторе в админке ("Управление" - > "Файл менеджер") открываем файл по адресу /etc/virt2real/autostart.sh (т.е. идем в папку /etc, затем в /virt2real, а там открываем файл autostart.sh). В нем добавляем строчки:

  modprobe musb_hdrc.ko
  modprobe davinci.ko
  modprobe g_serial 

В итоге содержимое файла autostart.sh у меня выглядит так:

  #!/bin/sh
  # mount debugfs
  mount -t debugfs debugfs /sys/kernel/debug
  # start 1-wire modules
  #modprobe wire.ko
  #modprobe w1-gpio.ko
  #modprobe w1_therm.ko
  
  # turn on wi-fi don't sleep script
  /etc/virt2real/dontsleep.sh &
  
  # path for NodeJS global modules
  export NODE_PATH=/usr/lib/node_modules
  
  # turn on USB0 interface
  modprobe musb_hdrc.ko
  modprobe davinci.ko
  #modprobe g_ether.ko
  
  modprobe g_serial
  
  #ifup usb0
  

б) Укажем виртурилке, что консоль отображать на настроенный нами порт

В редакторе файлов идем в папку "/etc" и в корне находим файлик "inittab". В нем находим строчку "S0::respawn:/sbin/getty -L ttyS0 115200 vt100 # GENERIC_SERIAL" и ставим перед ней знак # - т.е. комментируем. Следом добавляем строчку "S0::respawn:/sbin/getty -L ttyGS0 115200 vt100 # GADGET_SERIAL"

В итоге содержимое моего файла inittab выглядит следующим образом:

  # /etc/inittab
  #
  # This inittab is a basic inittab sample for sysvinit, which mimics
  # Buildroot's default inittab for Busybox.
  id:1:initdefault:
  proc::sysinit:/bin/mount -t proc proc /proc
  rwmo::sysinit:/bin/mount -o remount,rw / # REMOUNT_ROOTFS_RW
  dpts::sysinit:/bin/mkdir -p /dev/pts
  moun::sysinit:/bin/mount -a
  host::sysinit:/bin/hostname -F /etc/hostname
  init::sysinit:/etc/init.d/rcS
  1:1:respawn:/sbin/getty 38400 tty1
  2:1:respawn:/sbin/getty 38400 tty2
  #S0::respawn:/sbin/getty -L ttyS0 115200 vt100 # GENERIC_SERIAL
  S0::respawn:/sbin/getty -L ttyGS0 115200 vt100 # GADGET_SERIAL
  
  # Logging junk
  mess::sysinit:/bin/touch /var/log/messages
  sysl:1:respawn:/sbin/syslogd -n -m 0
  klog:1:respawn:/sbin/klogd -n
  
  # Stuff to do for the 3-finger salute
  rebo::ctrlaltdel:/sbin/reboot
  
  # Stuff to do before rebooting
  sklo:6:wait:/usr/bin/killall klogd
  ssys:6:wait:/usr/bin/killall syslogd
  umou:6:wait:/bin/umount -a -r
  swap:6:wait:/sbin/swapoff -a
  

в) Теперь перезагружаем виртурилку.

Маленькое замечание для тех, кто работает в убунте из-под макоси и parallels – при подсоединении виртурилки parallels спросит куда коннектить девайс – в макось или в запущенную виртулалку с убунтой. Нужно выбрать убунту.

Итак, мы все подключили. Убунта лишнего не скажет – устройство просто подключилось и работает. ☺ Теперь нам надо понять, подключилось ли оно и как его зовут в системе. Напомню, что в линуксе устройства видны как файлы, поэтомы мы сейчас заглянем куда следует и найдем то что нам нужно.

Для этого открываем командную строку и запускаем инструмент пролетариата – Midnight Commander. Запускаем терминал, далее в нем вводим mc. Если у вас не установлен mc, то сначала пишем sudo apt-get install mc, и наступает счастье.

Идем в папку /dev, внутри видим папку /serial (она появится, если система увидела виртурилку). В ней видим две подпапки /by-id и /by-path - заходим в первую, и ставим курсор на единственный файлик, и снизу в статусной строке видим системное название порта:


V2r serial name.jpg


Итак, виртурилка отзывается моей убунте в качестве serial-устройства и получает имя ttyACM0. В вашем случае выданное имя может отличаться.

Ну что-же, виртурилка видна в системе – это уже маленькая победа. Давайте теперь с ней соединимся.

Для коннекта предлагаю использовать программу minicom. Если таковая не установлена – набираем в консоли

  sudo apt-get install minicom

вводим пароль и программа установлена.

Запускаем minicom. Программе необходимо указать, с каким портом работаем, и сохранить настройки – в будущем достаточно просто запустить программу, и она сразу будет работать с нужным портом.

Для этого:

- выполняем команду sudo minicom -s (после этого ввоим пароль)

- выбираем пункт "Serial port setup"

- жмем латинскую букву A

- вписываем наше название порта (в моем случае это /dev/ttyACM0), вот как выглядят у меня настроки порта:


V2r minicom settings.jpg


- жмем Enter, далее выбираем пункт "Save setup as dfl" и сохраняем настройки - теперь minicom помнит, какой порт ему "слушать"

- Выбираем в меню пункт "Exit" ( НЕ "Exit Minicom") и видим надпись "Initializing modem..." и приглашение для ввода логина и пароля.

- Вводим root и root, получаем слудующую картинку:


Minicom v2r console.png


Для чистоты эксперимента закрываем терминал и отключаем USB шнурок с виртурилкой от компьютера. При этом minicom ругнется, что порт исчез. Потом заново подключаем плату к компьютеру и ждем пока она загрузится. В консоли увидим приглашение.

Ну и теперь возвращаемся к прерванному эксперименту - вводим в консоли, например, команду top. Насмотревшись, можете прервать выполнение нажав клавишу q или сочетанием клавиш Ctrl c.

Gstreamer – что это такое, как упростить запуск. Тестируем передачу видео с виртурилки на компьютер.

Gstreamer это инструмент для захвата видео с камеры, сжатия и отправки, а также получения и отображения его пользователю. Таким образом, в простейшем случае нам нужно запустить gstreamer на виртурилке - он будет забирать картинку с камеры и слать куда мы ему скажем, а также на принимающем устройстве - например на компьютере, который будет принимать поток от виртурилки, распаковывать его и показывать пользователю. Инструмент достаточно мощный, позволяющий настроить большое количество параметров. Все они задаются в виде текстовых параметров при запуске, что делает несколько неудобным его запуск. Давайте глянем, как все это работает, и добавим себе комфорта. Попробуем передать видео на компьютер с Ubuntu. Как мы недавно посмотрели, соединенная с виртурилкой убунта получила IP- адрес 192.168.2.13. Поэтому для запуска гстримера на виртурилке нужно использовать следующую команду:

  gst-launch v4l2src always-copy=false chain-ipipe=true ! video/x-raw-yuv,format='(fourcc)'NV12, width=640, height=480, 
  framerate='(fraction)'30/1 ! dmaiaccel ! dmaienc_h264 ddrbuf=true rcalgo=0 bytestream=true encodingpreset=2 
  ratecontrol=1 intraframeinterval=46 idrinterval=46 targetbitrate=1000000 !  rtph264pay !  udpsink port=3000 
  host=192.168.2.13 sync=false

Страшно? Неудобно? Ну, если каждый раз набирать ее вручную, или вставлять из буфера в терминал - да, это некомфортно. Поэтому мы заранее записали всю эту длинную команду в файлик, который находится в корне файловой системы и называется h264.sh

Поэтому чтобы с комфортом запустить gstreamer на виртурилке, нужно сделать всего два действия:

а) Через файловый редактор в админке зайти в файл h264.sh и указать там IP адрес устройства, на который вы хотите передавать видеопоток. В моем случае это 192.168.2.13, поэтому файл выглядит таким образом:

Gstreamer launch v2r.jpg

б) В терминале (в нашем случае minicom под Ubuntu) набрать команду sh ../h264.sh

Собственно, гстример стартовал. В терминале при этом будет выведена надпись такого рода:

V2r gstreamer started.png


А теперь давайте примем картинку на настольном компьютере.

Для этого в Ubuntu открываем терминал, и вводим, например, команду (команда взята из этого примера на форуме):

  gst-launch udpsrc port=3000 ! "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, sprop-parameter-sets=(string)\"Z2QAKK2EBUViuKxUdCAqKxXFYqOhAVFYrisVHQgKisVxWKjoQFRWK4rFR0ICorFcVio6ECSFITk8nyfk/k/J8nm5s00IEkKQnJ5Pk/J/J+T5PNzZprQFAeyA\,aO48sA\=\=\", payload=(int)96, ssrc=(guint)2498431066, clock-base=(guint)297251943, seqnum-base=(guint)34949" ! rtph264depay ! queue ! ffdec_h264 ! ffmpegcolorspace ! videoscale ! ximagesink sync=false show-preroll-frame=false 

Как и на виртурилке, вы можете создать файл и разместить в нем эту команду, чтобы запуск был легким и приятным.

После запуска этой команды у меня появляется новое окно, которое показывает картинку с камеры. Вот что я вижу:

Gstreamer test v2r ubuntu.png

Левое верхнее окошко терминала - это запущенный minicom, с которого я стартовал скрипт запуска трансляции. Правое верхнее окошко терминала - это терминал настольного компьютера, в котором я запустил gstreamer на прием видеопотока. Ну и нижнее окошко появилось самостоятельно и отображает картинку с камеры виртурилки. Я направил ее на ноутбук.

Приложение для Android – установка, настройка соединения с виртурилкой.

Некоторое время назад мы обратились к сообществу владельцев виртурилок помочь нам с написанием нативных приложений под iOS и Android, и сделали по этому поводу тему на нашем форуме. Давайте приобщимся к авангарду разработки и попробуем повторить эксперимент автора под ником merofeev, который первым собрал тестовые приложения. Итак, вот здесь автор дает ссылку на первое тестовое приложение: https://www.dropbox.com/s/vw6pno7ao8yrw25/v2r_test.apk Его необходимо скачать с вашего Android-устройства и установить. Не забудьте в настройках андроида разрешить установку программ из сторонних источников.

Ну что, пробуем повторить эксперимент автора. Для этого:

а) Соединяемся по WiFi с виртурилкой с вашего Android-устройства

б) Смотрим IP-адрес вашего Android-девайса (см. раздел 3 этой статьи) - на него виртурилка будет слать видеопоток

в) В браузере на вашем андроиде набираем 192.168.2.1, вводим логин root и пароль root

г) В редакторе файлов открываем файл h264.sh и в нем вбиваем IP адрес вашего Android-девайса. Не забудьте нажать кнопку "сохранить" внизу экрана

д) На настольном компьютере в minicom запускаем sh ../h264.sh

е) На устройстве Android запускаем скачанное ПО.


Я вижу такую вот картинку:


Gstreamer android test.png


Ну и подтверждается утверждение автора - пока видео очень тормозит (это одна из первый собранных версий), видимо не включилось аппаратное декодирование h264 или есть иная проблема.

Но чуть позже автор выложил еще один тест - попробовав передавать видео со сжатием MP4, а не h264. Вот это сообщение. Ну давайте посмотрим на более шуструю трансляцию!

а) Устанавливаем на ваше android-устройство второй пример для работы с видео mp4 Обратите внимание, что приложение имеет такое же имя, что и предыдущее (для тестов h264), поэтому предыдущее будет удалено.

б) Подключаемся к виртурилке с компьютера, через админку открываем в редакторе файлов файлик h264.sh и заменяем команду гстримера на новую:

  gst-launch v4l2src always-copy=FALSE ! video/x-raw-yuv,format=\(fourcc\)NV12,width=640,height=480 ! dmaiaccel ! dmaienc_mpeg4 encodingpreset=2 targetbitrate=1000000    ratecontrol=2 intraframeinterval=23 ! queue ! rtpmp4vpay ! udpsink port=3000 host=ip_телефона

где ip_телефона - это IP адрес вашего Android-устройства после подключения его к виртурилке.

Вот как выглядит отредактированный файл у меня:


Gstreamer mp4 android.png


в) Отключаемся от WiFi виртурилки компьютером и подключаемся вашим устройством Android г) Запускаем на Android приложение д) Запускаем с настольного компьютера через minicom наш скрипт sh ../h264.sh

У меня получается плавное видео, по задержке сравнимое с трансляцией на настольный компьютер из 5-го раздела статьи.


Собственно, на этом пока все. Я очень жду ваших комментариев по формату статьи - с учетом их будем искать идеальный формат статей для начинающих.

обсуждение на форуме: http://forum.virt2real.ru/viewtopic.php?f=38&t=13381