Глубоко уважаемые Коты и Кошки. Пишу вам по причине, того что у меня КАША в голове . Не смог найти систематизированного описания составления UsbHidReportDescriptor на русском языке, а в английском не особо силен , хотя и изучал его (и изучаю его до сих пор). Не понятно, что делает каждое из полей, и какое поле как заполнить в определенном случае. Например, мне нужно управлять портом ввода вывода Atmega16. (хочу зажигать и тушить восемь светодиодов по команде с компа). Для этого достаточно 8-и бит. Что нужно поменять в UsbHidReportDescriptor, чтобы все заработало. Я имею в виду, что нужно прописать в: USAGE_PAGE USAGE_MINIMUM USAGE_MAXIMUM LOGICAL_MINIMUM LOGICAL_MAXIMUM REPORT_COUNT REPORT_SIZE INPUT REPORT_COUNT REPORT_SIZE INPUT USAGE_PAGE USAGE USAGE LOGICAL_MINIMUM LOGICAL_MAXIMUM REPORT_SIZE REPORT_COUNT INPUT В какой последовательности это надо делать, что нужно менять в usbconfig.h и почему так, и почему именно это, и как потом это все правильно откомпилировать в WinAVR ?
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Для этого достаточно 8-и бит. Что нужно поменять в UsbHidReportDescriptor, чтобы все заработало
REPORT_COUNT = 1 REPORT_SIZE = 8
PS. У вас какой-то не правильный дескриптор. Зачем несколько описаний INPUT если в данном случае, одного достаточно? Да и вообще, конечная точка типа INPUT, это передача данных из устройства в комп, а я так понимаю что нужно из компа в устройство
В BASCOM-AVR, дескриптор будет такой:
Код:
_usb_hid_reportdescriptor: Data 21 Data &H06 , &H00 , &HFF ' Usage_page(vendor Defined Page 1) Data &H09 , &H01 ' Usage(vendor Usage 1) Data &HA1 , &H02 ' Collection(logical)
Data &H09 , &H01 ' Usage(pointer) Data &H15 , &H00 ' Logical_minimum(0) Data &H26 , &HFF , 0 ' Logical_maximum(255) Data &H75 , &H08 ' Report_size(8) Data &H95 , &H01 ' Report_count(1) Data &H91 , &H02 ' Output(data , Var , Abs)
Да я согласен с вашими замечаниями. Этот дескриптор я привел просто для примера (взял первый понравившийся с http://frank.circleofcurrent.com/cache/ ... rial_1.htm ). Но вот, например, дескриптор, описанный на http://avrhobby.ru/index.php?option=com ... &Itemid=53: 01. PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */ 02. 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) 03. 0x09, 0x01, // USAGE (Vendor Usage 1) 04. 0xa1, 0x01, // COLLECTION (Application) 05. 0x15, 0x00, // LOGICAL_MINIMUM (0) 06. 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 07. 0x75, 0x08, // REPORT_SIZE (8) 08. 0x95, 0x80, // REPORT_COUNT (128) 09. 0x09, 0x00, // USAGE (Undefined) 10. 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf) 11. 0xc0 // END_COLLECTION 12. }; Тут вот, например, что значит магическая фраза USAGE_PAGE (Generic Desktop) (переводится как, что то вроде, «обычный настольный» ) и соответствующий набор циферок 0x06, 0x00, 0xff? Или вот, например, 0x15, 0x00, // LOGICAL_MINIMUM (0) или 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)? В двух последних случаях это вроде типа, значения соответствующие положению каких то ручек (например X и Y оси на джойстике), хотя ни о каких ручках там в этой статье и речи не идет! Там просто он (автор статьи) пишет о записи и чтении EEPROM. И я так чуйствую, что он сам не очень хорошо понимает устройство usbHidReportDescriptor-а и просто пользуется случайно подошедшим под его девайс (если будет читать автор этой статьи то заранее прошу прощения за возможно резкую критику, и вообще не в коей мере не хочу ни кого обидеть, но этой инфы явно не достаточно ). А вот тут http://forum.easyelectronics.ru/viewtop ... w=previous например, вообще используется USAGE (Generic Indicator). Что это ? И еще, например, что значит 07. 0x75, 0x08, // REPORT_SIZE (8) 08. 0x95, 0x80, // REPORT_COUNT (128)? Это в смысле 128 раз по 8, или 128/8=16 раз по 8 ? Еще не понятно, что такое вообще COLLECTION (Application) и её (какой то коллекции) конец END_COLLECTION? Да и еще один вопрос! Как Вы так быстро мне составили этот дескриптор? В смысле, чем Вы при этом пользовались или руководствовались (всмысле например есть такая программа HID Descriptor Tool, лежит, если я не ошибаюсь на http://www.intel.com/intelpress/usb/Exa ... les/dt.htm или еще на http://www.usb.org/developers/hidpage/ ).
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Да и вот еще вдогонку вопросик! Когда я прописываю INPUT (ну или соответственно OUTPUT), я указываю соответственно INPUT или OUTPUT конечную точку, и далее идет ее описание? Ну, тут тогда море вопросов. Например, если это так, то что нужно делать (или не нужно) в usbconfig.h что бы такой девайс с несколькими конечными точками начал фунциклировать?
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
Значит что за раз будет передаваться или приниматься 128 восьми-битных значений, т. е. 128 байт.
Kvasshtain писал(а):
Как Вы так быстро мне составили этот дескриптор?
Взял из реально работающего устройства, которое принимает от компа 1 байт выводит его на порт контроллера для зажигания и гашения светодиодов.
Kvasshtain писал(а):
Да и вот еще вдогонку вопросик! Когда я прописываю INPUT (ну или соответственно OUTPUT)
В вашем примере (дескрипторе что вы выложили), не используются дополнительные конечные точки, данные передаются и принимаются через канал FEATURE нулевой, управляющей конечной точки.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Я кстати с Yellow Tiger не согласен. Не всегда, бывает так хорошо как он пишет . Дело в том, что все эти FT-шки (например FT232AM/BM) и другие микросхемы контроллеров мостов, это часто лишний огород в схеме. Они далеко не всегда так легко доступны. Я например живу в Саратове, и у нас в нашем «городе герое » эти самые FT-шки стоят от 300р. за штуку (и то только на заказ, во всяком случае в тех местах где я знаю – магазин «Радиодетали» на Сенном, и магазин «Электронные компоненты» на Московской, во всех остальных вообще такого как микроконтроллеры нет), а Atmega16 стоит всего 250р., а Attiny2313 (которая тоже «поддерживает» V-USB) стоит всего 100-150р. Закажешь эту FT-шку и еще нет гарантий что она приедет ! А Агуров в своей книге приводит пример устройства на AT89C5131 (если я название не перепутал), так у нас заказать сей чудо девайс будет стоить около 1000р (но это хоть и Atmel но не AVR, а Х51). Извините за выражение, ОФИГЕТЬ !!! А о AVR-ках с встроенным USB как правило либо вообще ни чего не знают, либо заламывают цену . Правда есть еще такие PIC-и, но с ними такая же история. Да и я всегда считал, хотя может быть я не прав, что диверсификация это всегда хорошо, во-первых есть из чего выбирать, во-вторых снижается риск что то что захотел купить нет, а другого просто не знаю (Гегемония это всегда плохо, нужен плюрализм ). Ну ладно, хватит лирики. Вот еще вопросик. Нашел вот тут http://forum.vingrad.ru/forum/topic-233737.html, приводится пример в котором записана следующая непонятная строка: 0x05, 0x08, // USAGE_PAGE (LEDs), это в смысле означает, что репорт говорит драйверу, что устройство представляет из себя контроллер зажигания и тушения диодов? Али нет? И чем тогда это все отличается от скажем того что Вы мне написали: Data &H06 , &H00 , &HFF ' Usage_page(vendor Defined Page 1)? Да, и там еще одна непонятная фраза: «Поскольку мы задали только один feature-репорт, мы не используем идентификаторы report-ID (которые должны быть в первом байте репорта). Весь репорт состоит из одного 8-ми битового блока неопределенных данных.» А если задать не feature-репорт, а другие (output и(или) input), как тогда будет выглядеть usbHidReportDescriptor?
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
На пальцах все это объяснить очень сложно. Сначала попытайтесь понять как работают имеющиеся примеры с FEATURE, а потом переходите на работу с дополнительными конечными точками. Теория без практики плохо усваивается.
А, ну ладно. Я понял. Лучше пока не пользоваться input и output репортами. Но тогда все же по поводу 0x05, 0x08, // USAGE_PAGE (LEDs). Все таки что же такое USAGE_PAGE и как эта самая пользовательская страница влияет на работу устройства?
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Про программу Descriptor Tools, я знаю, но все равно спасибо ! А за pdf-ку огромное спасибо , уважаемый md5sum , почитаю, по перевожу (если конечно получится ). Вот тут при ковырянии в каше (в своей голове то есть ), вылез еще один вопрос. В уже упоминавшемся форуме http://forum.vingrad.ru/forum/topic-233 ... _30_view_0, я обнаружил следующее: Там в репорт дескрипторе вот что: 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01 // REPORT_COUNT (1) А в программе на Delphi(прошу прощения, понимаю, что Радио Кот – сайт не по программированию, но все же…) вот что: TReportData = array [0..7] of Byte; , а потом эта переменная используется во как : FillChar(ReportData, SizeOf(ReportData), 0); // заполняем массив нулями ReportData[0]:= 0; // номер репорта ReportData[1]:= LEDs; // данные репорта Я чуйствую, что здесь явно чо то не правильно . Т.к. размер репорта (как мне разъяснил Мурик) равен 8-и битам, таких бит пересылается всёго одна штук. Программа на компе, почему то отводит под эти данные массив, аж из 8-ми (0-7) ячеек по 8-мь бит (он же одын байт), и потом в нулевой заносит номер репорта (ну как я понял это такая особенность feature репортов, что типа у них номер всегда 0, правда может я не прав ), а во второй вносит собственно то, что потом будет выведено в порт. А все остальные (оставшиеся 6-ть штук) просто заполняются нулями. Блин , а зачем так? Зачем эти оставшиеся 6-ть штук? А? Или я чего то не понял ?
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Для репортов имеющих REPORT-ID первым байтом передается номер репорта.. А вот для "безномерных" непонятно: надо 0 передавать или нет... Повторюсь - я hid дескриптор создавал методом тыка: если винда не ругается, то ОК. Но сам я под виндовс не пишу (да и не работаю с этой операционкой), так, что тут особо не помогу.. Под линуксом все проще:воткнул неизвестное устройство, ядро ругнется и успокоится, и уже дальше работаем с устройством посредством libusb
_________________ — Не говорите мне что делать и я не скажу куда Вам идти...
Ой, ну да правильно , в смысле не репорт, а его кусочек (как он там называется? в смысле REPORT_SIZE ) А сам репорт, понятно, что может быть 1 штук по 8 бит или более штук (указывается количество штук в REPORT_COUNT). Да, а по поводу "безномерных". Это в смысле feature репорты такие всегда? Или нет? А вообще, судя по тому что написано в http://www.avrhobby.ru/index.php?option ... &Itemid=53, а именно (в самом конце статьи): "Как видно, первым байтом у нас всегда стоит ReportID. В данном примере он равен 0, но в принципе его можно сделать любым, но при этом еще и прописать в ReportDescriptor. Сейчас там нет строки про ReportID, потому что нулевой прописывать не обязательно." то есть, значит можно типа того в репорт дескрипторе написать: PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */ мяу-мяу-мяу… 0x85, 0x77, // REPORT_ID (0x77) мяу-мяу-мяу… }; , а потом в управляющей программе (Delphi) написать мяу-мяу-мяу… fillchar(Raw,length(RAW),0); Raw[0]:=0x77; //ReportID мяу-мяу-мяу… , что собственно автор этой статьи и делает в следующей статье http://www.avrhobby.ru/index.php?option ... &Itemid=53, НО !!!, он это приводит для случая INPUT и OUTPUT репортов. Можно ли тоже самое сделать для FEATURE-репортов? И так и не понятно с теми лишними 6-тью байтами в примере из http://forum.vingrad.ru/forum/topic-233 ... _30_view_0?
_____ Прошу прощения за, возможно, чрезмерную настырность , но по моему у меня потихоньку все раскладывается по полочкам .
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Да, и еще вдогонку. Дело не в используемой операционке, или среде программирования, или используемых библиотеках (я то пользуюсь Delphi 7 + JVCL, а именно коипонентом HIDControl – классная штука, надо бы попробовать портировать ее в Lazarus, но я еще новичек), а в том, что может быть без этих шести лишних байт вощпе ни чего не заорбйтан (незафунциклирует то есть)? Я вот что имею в виду (заранее прошу прощения за возможные глупости, но я сразу сказал, что у меня каша в голове ).
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
И так и не понятно с теми лишними 6-тью байтами в примере
Судя по
Код:
function TForm1.WorkDevSetFeature(Buf: TReportData): Boolean; // Передача данных устройству WorkDev begin If Assigned(WorkDev) then Result:= WorkDev.SetFeature(Buf, WorkDev.Caps.FeatureReportByteLength) else Result:= False end;
функции WorkDev.SetFeature передается размер репорта полученный из дескриптора и лишние байты просто будут отброшены... Буфер в примере скорее всего один для разных типов (длинны) данных и потому он 8 байт, но это только предположение, а точный ответ даст только автор примера
_________________ — Не говорите мне что делать и я не скажу куда Вам идти...
А! Вот оно что ! Да, наверное, оно так и есть . Надо будет попробовать с моим, наконец-то с горем пополам заработавшим, девайсом так именно и сделать (т.е. лишние ячейки в буфере объявить). Вот кстати хочу поделиться своим опытом, заодно, и Вас посмешить, глубоко уважаемые коты и кошки . Я ни как не мог въехать как правильно компилить свои самодельные программы, т.е. чужие примеры копилятся нормально, а вот свои ни как. А если и компилятся, то только когда я ни чего не меняю в дескрипторе, и при этом что бы я не менял в usbconfig.h. (например, имя девайса), при компиляции это (то что я поменял), ни черта не меняется (сколько валерьянки ушло!!! хотя я - кот вроде и не пьющий ). Оказывается меня в заблуждение ввел автор статьи http://microsin.ru/content/view/613/44/, там этот товарисч, приводит пример компиляции и говорит во чо: «Для компиляции firmware нужно ввести make hex, что и сделаем: …», так вот оказывается при этом параметре (т.е. hex) перекомпилируются изменения, сделанные только в главном файле программы (например, main.c), а то чо я там в usbconfig.h сделал, на то ни какого внимания компилятор обращать не будет. Оказывается, хотя наверное вы это знаете, чтоб все скомпилировалось, надо в командной строке набрать make program или make flash (можть я правда зря на автора с когтями бросаюсь, т.к. просто внимательнее читать статьи надо ). Но вот тут сразу вопрос. Когда делаешь так, то компилятор мяукает ошибку, что типа не подключен программатор, но компилит все правильно. Как поменять makefile, что бы этого не происходило? Да и еще вопрос. У кого ни будь может есть инфа по правилам составления этих самых GCC-шных makefile-ов? А? (правда, не вообще, а применительно к WinAVR и желательно именно для V-USB). Для меня это пока что как китайская грамота. Тем более что md5sum - явно заядлый линуксоид и с GCC должен быть на ты .
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
«Для компиляции firmware нужно ввести make hex, что и сделаем: …», так вот оказывается при этом параметре (т.е. hex) перекомпилируются изменения, сделанные только в главном файле программы (например, main.c), а то чо я там в usbconfig.h сделал, на то ни какого внимания компилятор обращать не будет. Оказывается, хотя наверное вы это знаете, чтоб все скомпилировалось, надо в командной строке набрать make program или make flash
Странно, но в том примере make program или make flash заливают имеющийся hex в контроллер. А вот, для учета ВСЕХ изменений желательно делать make clean, а потом make hex Касательно правки Makefile, то четкой инструкции нет, т.к. для большей гибкости нет жестких рамок. Разве что название правила заканчиваются двоеточием, шаги правила начинаются с символа табуляции. Обычно в начале Makefile описываются переменные которые при желании и можно править:
Код:
DEVICE = atmega188 F_CPU = 12000000 # in Hz FUSE_L = # see below for fuse values for particular devices FUSE_H = AVRDUDE = avrdude -c usbasp -p $(DEVICE) # edit this line for your programmer CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
DEVICE собственно тип контроллера F_CPU - Частота МК. OBJECTS (или чаще OBJ) - список обьектных модулей которые должны быть скомпилированы и слинкованы CFLAGS флаги компилятора: тут добавляют при необходимости пути к заголовкам библиотек LDFLAGS флаги линковщика: тут добавляют при необходимости пути к библиотекам.
В данном Makefile есть еще COMPILE - описывает что запускать для компиляции/линковки и AVRDUDE описывает команду прошивки МК- тут НАДО поправить тип программатора и можно добавить параметр указывающий COM порт
Правка: Но эти вопросы для темы С/C++
_________________ — Не говорите мне что делать и я не скажу куда Вам идти...
Да я понимаю, что сайт не по программированию , НО к сожалению, а может и к счастью (скорее всего ) современная электроника вообще, а не только компьютеры, все чаще и чаще так переплетена с программированием, что ну ни как без него. Я то к программированию (в частности МК и всей современной электроники вообще) отношусь как к продлению электронного (т.е. самого что не есть ПАЯЛЬНОГО дела ), т.к. ни все ли равно чем проводки соединять, паяльником, али процедурами или функциями (в конечном счете, директивами ассемблера, или вообще машинными кодами, если совсем глубоко копать), т.к. это самое программирование как раз и было ИМХО изобретено, чтоб проводки вручную не соединять . Правда понятно, что не надо палку перегибать, и заводить здесь темы о, например, объектно-ориентированном программировании или программировании HTML или программировании вообще. Но факт остается фактом. Нам теперь без этих закорючек ни куда. Так что хватит лирики . Вот еще вопросик. Вы говорите, что OBJECTS (или чаще OBJ) - список обьектных модулей которые должны быть скомпилированы и слинкованы, т.е. если у меня программа состоит не из одного файла (модуля, говоря на языке Pascal), а из нескольких (например main0.c, main1.c, … мяу мяу мяу … mainN.c), то я типа должен написать в makefile наверное так: OBJECTS = main0.o main1.o … мяу мяу мяу … mainN.o ,или если они в разных директориях лежат то как то так: OBJECTS = main0/main0.o main1/main1.o … мяу мяу мяу … mainN/mainN.o? Или нет ? А если один из моих файлов – библиотека, например main1.c (ну понятно что там с ним еще какие то файлы будут, правда создание своих библиотек для WinAVR, вообще говоря отдельная тема для сюрьезного разговора), то я должен типа добавить строку: CFLAGS = -Imain1 -I. -DDEBUG_LEVEL=0? Или нет ? А что касается COMPILE, то вот как раз, как сделать так чтоб просто происходила компиляция и линковка, но все это хозяйство не пыталось прошить контроллер, а только создавало hex – файл. Хотя конечно все и так работает, но сообщение об ошибке коннекта с программатором глаза мазолит .
_________________ Говорят, что у него нет носа и рта, и что он общается телепатией. Говорят, что у него зеленая кожа, и он питается как растение, закопав ноги в землю и подставив спину солнцу. Все что знаем мы: его зовут Вовэн.
Вы говорите, что OBJECTS (или чаще OBJ) - список обьектных модулей которые должны быть скомпилированы и слинкованы, т.е. если у меня программа состоит не из одного файла (модуля, говоря на языке Pascal), а из нескольких (например main0.c, main1.c, … мяу мяу мяу … mainN.c), то я типа должен написать в makefile наверное так: OBJECTS = main0.o main1.o … мяу мяу мяу … mainN.o ,или если они в разных директориях лежат то как то так: OBJECTS = main0/main0.o main1/main1.o … мяу мяу мяу … mainN/mainN.o? Или нет ?
Можно так и так , а можно и просто в строке компиляции прописать все модули
Kvasshtain писал(а):
А если один из моих файлов – библиотека, например main1.c (ну понятно что там с ним еще какие то файлы будут, правда создание своих библиотек для WinAVR, вообще говоря отдельная тема для сюрьезного разговора), то я должен типа добавить строку: CFLAGS = -Imain1 -I. -DDEBUG_LEVEL=0? Или нет ?
Точнее CFLAGS = -Iпуть_к_заголовочным_файлам
Kvasshtain писал(а):
А что касается COMPILE, то вот как раз, как сделать так чтоб просто происходила компиляция и линковка, но все это хозяйство не пыталось прошить контроллер, а только создавало hex – файл. Хотя конечно все и так работает, но сообщение об ошибке коннекта с программатором глаза мазолит .
make clean а потом make hex, а make flash и make programm созданы автором именно для прошивки МК make clean - удалит все ранее скомпилированные модули и при выполнении make hex ВСЕ изменения ВСЕХ файлов проекта будут учтены и модули скомпилированы заново.
_________________ — Не говорите мне что делать и я не скажу куда Вам идти...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения