реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Кросс-компиляторный шаблон (EC++, IAR, GCC), Попытка правильного проектирования сверху
uni
сообщение Jul 17 2011, 21:07
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809



Доброго, уважаемый форумчане.

Хочу предложить вашему вниманию пробный проект на C++ для объединения в одно целое процесса проектирования для микроконтроллеров AVR.

Я пытаюсь «подружить»: SVN (VisualSVN для VS2008), Proteus 7.6 (ISIS), Enterprise Architect, VS2008, IAR 5.51, WinAVR-20100110, AVR Studio 4 и AVR Studio 5… ух, короче, всё это в одном проекте.

Думается мне, что если писать на чистом C++, без особых выкрутасов, то можно иметь кросс-компиляторный проект в одном почти флаконе. Конкретно этот у меня компилируется и в IAR 5.51 и в WinAVR-20100110.

Цели:
1. Проектирование сверху (UML2).
2. Использование удобной IDE VS2008.
3. Рабочая виртуальная модель для тестов.

Ссылка на хранилище (svn): https://mysvn.ru/cop/Example/ (доступ: чтение)
Клиент для SVN под Windows: TortoiseSVN

Краткое описание есть там в readme.txt.

Отлаживаю одновременно в: ISIS, IAR и AVR Studio (через ubrof8, который генерится IAR'ом специально для этого).

Я пишу «образ» проекта в EA, используя редактор UML2, потом генерю образ(ы) класса(ов) в виде исходников и подключаю их в VS2008. Там же в студии через Makefile компилирую. Отладку, симуляцию можно делать где угодно.

Переключение компилятора в Defines.h (одном месте).
Моделируемая схема: Example.dsn — Proteus ISIS 7.6.

Вся необходимая инфа по сборке исходника в плане используемых портов и пинов находится в файле: Configuration.h

Хочу собрать вирутальную модель модуля АСУТП, работающего по MODBUS (припомощи com2com или аналога).
После этого:
- найти свободный OPC сервер и установить на компе;
- подключить модель Proteus к OPC серверу через COM-порт и MODBUS;
- взять китайску подделку а-ля iPad с версией Android не менее 1.6;
- найти OPC-клиент на Java для Android;
- написать самопальный HMI, который по WiFi будет подсоединяться через OPC-клиент к OPC-серверу;
- повесить планшетник на стенку, приделать в модели Протеуса 1-Wire термометр и любоваться на планшетнике температуру в модели.

------------------------------------

Кто-нить занимался чем-то подобным? В смысле кросс-компиляторности. Интересует использование строк, которые хранятся в памяти программ, т.е. универсальный подход для IAR и GCC.

Прикрепленное изображение
Прикрепленное изображение

Прикрепленное изображение
Прикрепленное изображение


Просто когда-то я был привлёчён вот к такому проектик для AVR'ки. Мягко говоря, он мне показался слегка запутанным и кроме самого кода никаких больше доков. Эту схемку нарисовала уже студия 2008.
Самый крайний правый класс - это пример того как не надо проектировать классы sm.gif он у меня в несколько экранов даже в таком виде не помещается.


Прикрепленное изображение
Прикрепленное изображение


Сообщение отредактировал uni - Jul 17 2011, 21:07


--------------------
Россия навсегда!
Go to the top of the page
 
+Quote Post
uni
сообщение Jul 19 2011, 11:14
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809



Пример чуть усложнился. Привык я к винде, поэтому написал небольшой движок с обработкой очереди сообщений. Код по написанию окон интерфейса практически один в один теперь будет. Сейчас у меня только один "поток" (WinMain) и одно окно (hWnd = 100). Функция окна "обрабатывает" два сообщения: SW_SHOW и WM_PAINT. Обработчик второго сообщения и рисует эту картинку.

Хотя проект компилится под IAR и GCC, в GCC я пока не нашёл опции по увеличению стека. Вложенных функций стало больше. С этими очередями есть небольшая проблемка, которую я придумал как решить только одним способом - резервированием под себя внешнего прерывания 0, т.к. оно самое приоритетное. Дело в том, что я пока не понял как добавлять в очередь сообщения из прерываний. Я использую две очереди, которые переключаются время от времени. ISR от EI0 нужно для заполнения второй очереди. Посмотрим как получится это реализовать.

Те, кто программит под винду, найдут много знакомого в коде sm.gif
Я очень расточителен в плане организации очереди, главное - работает, а жирок обрезать всегда успею.

Прикрепленное изображение


--------------------
Россия навсегда!
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 19 2011, 12:15
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(uni @ Jul 18 2011, 00:07) *
ух, короче, всё это в одном проекте.

А это зачем????????
Уж если это - простое решение, то я тогда не знаю.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 19 2011, 12:16
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(uni @ Jul 19 2011, 14:14) *
в GCC я пока не нашёл опции по увеличению стека.
А его в большинстве случаев некуда увеличивать. В avr-gcc стек один, указатель инициализируется верхушкой внутреннего ОЗУ, а все переменные располагаются от начала. Таким образом стек автоматически получается максимально возможного размера.

p.s. с prog_char лучше расстаньтесь, avr-libc и документация нуждаются в правке.
http://savannah.nongnu.org/bugs/?33716
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38342
Для С оно ещё катит, в С++ нет. Когда перестанет проходить в С -- неизвестно.
Лучше сразу привыкать давать PROGMEM переменным :-(


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
neiver
сообщение Jul 20 2011, 14:15
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(uni @ Jul 18 2011, 01:07) *
Кто-нить занимался чем-то подобным? В смысле кросс-компиляторности. Интересует использование строк, которые хранятся в памяти программ, т.е. универсальный подход для IAR и GCC.

У меня есть статейка на эту тему:
http://we.easyelectronics.ru/Soft/avr-s-i-...-ukazateli.html
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 20 2011, 14:54
Сообщение #6


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(neiver @ Jul 20 2011, 17:15) *
У меня есть статейка на эту тему:

Код
        inline const T operator *()const
        {
                union
                {
                        T value;
                        uint8_t bytes[sizeof(T)];
                }data;

                for(unsigned i = 0; i<sizeof(T); ++i)
                        data.bytes[i] = Accessor::Read(_address + i); // <--------  ??? reinterpret_cast<uint8_t*>(_address) + i
                return data.value;
        }
private:
        T * _address; // указатель-то на тип, _address+i полетит далеко
};


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
uni
сообщение Jul 20 2011, 15:41
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809



Таак... попробую ответить по-порядку.

Раз уж я объял тему AVR, то классику - нужно знать, т.е. ассемблер и Ассемблер от самой фирмы. Ну, хотя бы в общих чертах, чтобы не спрашивать, а где это в инструкциях там операция XOR и как бы её имитировать? sm.gif

Тут дело вот в чём. Посмотрев кучу разных сайтов около-радиолюбительской тематики, где обсуждают различные подходы к программированию AVR'ок (да и других mcu тоже)... в общем выглядит это всё какий-то стихийным разнобоем. А ведь существуют наработки по красивому написанию кода, по понятному написанию кода, по правильному написанию и т.д.

Вот мне тут про prog_char сказали, что от него нужно уходить. Честно говоря у меня в коде он упоминается только раз 5, наверное. Дело в том, что я ещё не устаканился в выборе define'ов, которые были бы общепринятыми и понятными для обозначения аттрибутов памяти. Нужно сделать так, чтобы было удобно и для IAR и для GCC. В доке к GCC есть макро FLASH_DECLARE() - вполне удобная вещь, я её оставил и использую. Там разница только в очередности: у IAR [ __flash имя ] , а у GCC [ имя __attribute__((...)) ].

Так вот. Я пока использую gcc обозначения для аттрибутов памяти. Все типы, по возможности, обявляют как uintN_t. Кроме аналогов типов из windows.h - это экспериментальная поделка, чтобы можно было народ если что даже к MSDN отсылать для справки. Если Вы посмотрите работу схемы в Proteus, то увидите как работает очередь сообщений и идёт их доставка в окно. Вроде, достаточно понятно. Но не это главное, это больше для красоты и универсальности. Многие знают винду изнутри и код будет как бы знакомым.

Есть ещё такие вещи, как инициализация регистров IO. Я давно искал красивое и понятное решение для этого и лет эдак 5 тому назад нашёл таковое:
Код
    // MCU Control Register
    // [ Регистр управления микроконтроллером ]
    //           00000000 - Initial Value
    MCUCR = BIN8(10000000);
    //           ||||||||
    //           |||||||+- 0, rw, IVCE:   - Interrupt Vector Change Enable
    //           ||||||+-- 1, rw, IVSEL:  - Interrupt Vector Select
    //           |||||+--- 2, rw, SM2: -+ - Interrupt 1 Sense Control
    //           ||||+---- 3, rw, SM0: _|
    //           |||+----- 4, rw, SM1:    - Бит 1 выбора режима сна
    //           ||+------ 5, rw, SE:     - Разрешение режима сна
    //           |+------- 6, rw, SRW10:  - Бит выбора режима ожидания
    //           +-------- 7, rw, SRE:    - Включение внешней SRAM/XMEM
    // Примечание:

Вот так это выглядит. Наверное заметили в коде. Когда у меня был один монитор, мне было в лом постоянно переключаться между доками и кодом. Я бы вообще хотел бы себе 4 монитора: дока, рунет, IDE, симуляция (+ещё один для фильма wink.gif ). А то заколебало уже. Вот и подумал я тогда, что не плохо бы как-то по-умному документировать код вот таким образом. Пошукал и нашё на RSDN. Теперь вовсю пользуюсь. Даже лет через 10, когда я взгляну на такой код, я пойму что он означает, не глядя в даташит.

Вот... А зачем всё вместе столько IDE. На самом деле это не так уж и много. Вот прикиньте, приходит к Вам в отдел новый сотрудник, Вы его сажаете за свой проект какой-нить, чтобы он "втягивался". Вот что Вы ему покажите? Код? Заголовочники? А дока есть на код? С UML2 можно показать "вид сверху", т.к. структуру кода. Это EA, кстати, достаточно удобен. Он поддерживает реверс кода из исходников и генерацию в заголовочники и код (заголовки, без тела функций), а также синхронизацию с кодом.

Я сам прикладник ещё и долго пользовался VS2008. Когда я первый раз сел за IAR, то подумал, что большего убожества ещё не видал. Хотя в плане остального он хорош. Меня его работа с кодом просто достала. Даже 5.51 какая-то глючная в этому смысле. Поэтому я давно уже мечтал от другой среде, но чтобы компилировать можно было в IAR. У меня обычно обе среды открыты, т.к. модификацию они подхватывают сразу, только VS2008 требует подтверждения, а IAR тупо обновляет.

Вообще же, в VS2008 есть много разных фич, которые очень удобны для программера, особенно под C++. Например, fullscreen, разные подсветки, подсказки, деревья кода, классов... куча хрени всякой. или ВОТ - подсветка условной компиляции в коде! Вещь здоровская. Мне уже ещё удобна тем, что я пользую SVN и у меня есть плагин к VS2008 - VisualSVN и я могу коммитить проект в SVN нажатием пары кнопок прямо из VS2008. К EA тоже есть плагин. В общем - must have. Единственно, что плохо - это нету перехода к строкам ошибок после компиляции в avr-gcc, т.к. форматы обозначения у VS2008 и gcc компиляторов отличаются (это можно полечить, но нужно знать как). Зато там есть таблица ошибок и ворнингов в виде окошка, что тоже удобно, там видны строки с ошибками.

Вот и получается такая взаимодополняющся связь. А AVRStudio получается автоматом, т.к. умеет создавать проекты из отладочных файлов IAR. Иногда я их создаю, чтобы посимулировать там, но 5-я версия уж очень тяжела и умна слишком.

Итого: ТЗ -> Enterprise Architect (UML2) <-> VS2008 (C++, SVN) <-> IAR, GCC, Proteus <-> SVN -> ТЗ

Очень не плохо получается. Как-то даже по-другому на весь процесс смотришь. А ведь есть ещё удобные тулзы для VS2008.

А код, что привели, я ещё не ознакомился... буду разбирать. Мне ещё Modbus приделать надо, с COM портами разобраться и написать специальную хрень-переходник для Конфигуратора. Дело в том, что интерфейс Конфигуратора я буду писать на C# (VS2008), а вот Modbus будет в отдельной dll, но поскольку управлять я потоками буду в неуправляемом коде, а отображать в управляемом, то для этих целей существует такая приблуда как C++\CLI - на нём можно писать, как бы это сказать, управляемо-неуправляемый код. Это для того, чтобы обернуть уже имеющийся код Modbus-класса в управляемую обёртку, доступную из C#.

Короче, дело не простое, но и не шибко сложное. Ах, да. Хоть я кое-что и писал на яве под Андроид, то вот OPC как делать пока вообще не в теме. Тут может быть стопор, не искал ещё.

Давно мечтаю что-нить у себя дома довести именно до вот такого вида.


--------------------
Россия навсегда!
Go to the top of the page
 
+Quote Post
neiver
сообщение Jul 20 2011, 15:45
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(ReAl @ Jul 20 2011, 18:54) *
Код
// <--------  ??? reinterpret_cast<uint8_t*>(_address) + i

Код
pgm_read_byte((const uint8_t*)(_address + i));
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 20 2011, 17:07
Сообщение #9


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(uni @ Jul 20 2011, 19:41) *
Хоть я кое-что и писал на яве под Андроид, то вот OPC как делать пока вообще не в теме. Тут может быть стопор, не искал ещё.

Смысла в этом нету никакого, поскольку ОРС под андроид нету вообще. Ввиду нахренникомуненужности.
Видал статейку однажды, как в андроид встраивают драйвера FTDI. Вот это ещё можно прикрутить. Либо через ВТ.
Ещё раз повторюсь: смысл ОРС сервера в стандартном сопряжении с ОРС-клиентами. При отсутствии готовых клиентов смысл сервера теряется напрочь.
Или возможно я чего-то недопонял.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ig_z
сообщение Jul 20 2011, 19:09
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551



QUOTE (uni @ Jul 18 2011, 00:07) *
Цели:
1. Проектирование сверху (UML2).
2. Использование удобной IDE VS2008.
3. Рабочая виртуальная модель для тестов.


При таком подходе следовало бы опереться на методологию TDD.
Пунктом 1.а создавать тест, пунктом 1.б создавать тестируемый модуль.
Пунктом 2.а запускать сборку модульных тестов и выполнять их. При успешном прохождении модульных тестов, делать тестовую сборку всего приложения, и опять запускать тесты (или тестера sm.gif).
Go to the top of the page
 
+Quote Post
uni
сообщение Jul 21 2011, 04:03
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809



Цитата(ig_z @ Jul 21 2011, 01:09) *
При таком подходе следовало бы опереться на методологию TDD.
Пунктом 1.а создавать тест, пунктом 1.б создавать тестируемый модуль.
Пунктом 2.а запускать сборку модульных тестов и выполнять их. При успешном прохождении модульных тестов, делать тестовую сборку всего приложения, и опять запускать тесты (или тестера sm.gif).

Принято sm.gif По поводу тестирования. Понятия не имею как писать тесты под МК, но думается мне, что если что-то подобное делать, то можно тестировать ПО через Proteus (эмулируемый COM порт), либо через реальный интерфейс с реальным железом. Не знаю как это будет выглядеть. Не тестировать же классы на ПК - среда не та.

--------------------------------

neiver, я прочитал Вашу статью про указатели. Получается, что перегрузка методов в avr-gcc не пашет именно для такого случая? В IAR'е я могу написать просто дополнительный метод с другим типом параметра для чтения, без использования шаблонов.

Жалко, однако, это больше на костыль похоже для моего случая. Буду думать.

--------------------------------

Что касаемо OPC, то он нужен не для Android, а для Java. Какая разница вообще платформа. Это открытый интерфейс для работы в промышленности. Я потому к нему и веду. Если будет завязка: MODBUS + OPC, то можно будет эту поделку вполне реально применять совместо с огромной кучей имеющегося софта АСУТП верхнего уровня. Вот в чём смысл то. Поделки на AVR типа зажигания светодиодов, чтения температуры и т.д. уже пора оставить в прошлом sm.gif Давай-те чё-нить посерьёзней.

К тому же, если я смогу реализовать эту свою задумку, то применение такого "шаблона" проектирования на C++ можно будет использовать и в простых проектах. Не обязательно совмещать такую кучу всего в одном проекте. Зато, если ты знаешь, что ЭТО работает в сложном проекте, то в малом будет и подавно.

Цитата(MrYuran @ Jul 20 2011, 23:07) *
Смысла в этом нету никакого, поскольку ОРС под андроид нету вообще. Ввиду нахренникомуненужности.
Видал статейку однажды, как в андроид встраивают драйвера FTDI. Вот это ещё можно прикрутить. Либо через ВТ.
Ещё раз повторюсь: смысл ОРС сервера в стандартном сопряжении с ОРС-клиентами. При отсутствии готовых клиентов смысл сервера теряется напрочь.
Или возможно я чего-то недопонял.

Сервер будет не на планшетнике, а на стационарном компе. Смысл в том, чтобы использовать дешёвый ПК с тачскрином (можно КПК, хотя он и есть смартфон на Линуксе) в качестве клиента OPC. Там на борту есть всё: тачскрин, ява, wifi - что ещё нужно для написания юзабельного интерфейса для доступа к промышленной сети? Никто не мешает купить нормальную панель с Windows для тех же целей и писать на WinCC или Intouch. Без разницы будет. Дело в том, что я хочу показать на "простом" примере. А WinCC и Intouch - это не совсем просто sm.gif


--------------------
Россия навсегда!
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 21 2011, 05:10
Сообщение #12


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Мне Ваш подход нравится. Молодчина!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 21 2011, 06:14
Сообщение #13


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(uni @ Jul 21 2011, 07:03) *
Получается, что перегрузка методов в avr-gcc не пашет именно для такого случая? В IAR'е я могу написать просто дополнительный метод с другим типом параметра для чтения, без использования шаблонов.
В GCC атрибут progmem касается конкретной переменной, а не типа, наравне с attribute(section()) . Поэтому и невозможно сделать перегрузку (как и в IAR для переменных с #pragma section).



Цитата(neiver @ Jul 20 2011, 18:45) *
Код
pgm_read_byte( (const uint8_t*)(_address + i) );
Ну тогда уже
Код
pgm_read_byte( (const uint8_t*)(_address) + i );
И вообще пусть Accessor::Read() сразу принимает указатель на uint8_t, раз уж он по-uint8_t-шно читает.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
neiver
сообщение Jul 21 2011, 06:18
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(uni @ Jul 21 2011, 08:03) *
Не тестировать же классы на ПК - среда не та.

Почему нет? БОльшую часть встроенного приложения можно успешно тестировать на ПК - модульные тесты рулят. На целевой платформе нужно тестировать тоько низкоуровневый код, работающий непосредственно с железом. Тестирование на целевой платформе должно быть сведено к разумному минимуму.

По поводу OPC и COM/DCOM в частности, те, кто использовал эти технологии 10 лет назад сейчас активно от них избавляются в пользу веб служб. У DCOM очень большие проблемы обеспечения безопасности в распределённых сетях - админы с него волками воют. COM/DCOM, которые лежат в основе OPC слишком сложные и "замшелые" технологии.
То для чего Вы хотите использовать MODBUS + OPC + Android сейчас обычно делается так:
Промышленное устройство, которым нам надо управлять удалённо, имеет какой либо стандартный сетевой интерфейс (Ethernet, Wi-fi или еще что-нибудь) и подключено к корпоративной сети. На нём работает веб-служба (не путать в веб пользовательским итерфейсом), позволяющая управлять устройством. Далее, имеется большой и масштабируемый веб-сервер, который знает все устройства в сети и умеет с ними работать. Он предоставляет веб пользовательским итерфейс (WEB-UI), которым работают пользователи. Клиент такой системы может быть на любой платформе - главное, чтоб был браузер, а что это будет не важно - ПК, Android, iPhone, что угодно.


Цитата(ReAl @ Jul 21 2011, 10:14) *
И вообще пусть Accessor::Read() сразу принимает указатель на uint8_t, раз уж он по-uint8_t-шно читает.

Согласен.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 21 2011, 06:29
Сообщение #15


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(uni @ Jul 20 2011, 18:41) *
Вот мне тут про prog_char сказали, что от него нужно уходить. Честно говоря у меня в коде он упоминается только раз 5, наверное. Дело в том, что я ещё не устаканился в выборе define'ов, которые были бы общепринятыми и понятными для обозначения аттрибутов памяти. Нужно сделать так, чтобы было удобно и для IAR и для GCC. В доке к GCC есть макро FLASH_DECLARE() - вполне удобная вещь, я её оставил и использую. Там разница только в очередности: у IAR [ __flash имя ] , а у GCC [ имя __attribute__((...)) ].
В GCC можно и до.
Код
__attribute__((__progmem__)) char foo[] = "foo";



Цитата(neiver @ Jul 20 2011, 17:15) *
У меня есть статейка на эту тему:
http://we.easyelectronics.ru/Soft/avr-s-i-...-ukazateli.html
А вообще надо будет походить на easyelectronics, раз Вы там свои статьи прописали :-)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01571 секунд с 7
ELECTRONIX ©2004-2016