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

 
 
6 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Работа с EEPROM STM8 в IAR, Дописываем библиотеки для работы модификатора __eeprom
VladislavS
сообщение Jul 21 2017, 20:54
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Привет, любители STM!

В последних версиях IAR уже почти нормально с модификатором __eeprom работает. Надо лишь реализовать три функции, которые в библиотеке не реализованы и на которые линкер ругается.
CODE
int __eeprom_wait_for_last_operation(void)
{
if(FLASH_IAPSR_bit.WR_PG_DIS) return 0;
while(!FLASH_IAPSR_bit.HVOFF);
return 1;
}

void __eeprom_program_byte(uint8_t __near * dst, uint8_t v)
{
*dst = v;
}

void __eeprom_program_long(uint8_t __near * dst, uint32_t v)
{
FLASH_CR2_bit.WPRG = 1;
*(dst++) = *((uint8_t*)(&v));
*(dst++) = *((uint8_t*)(&v) + 1);
*(dst++) = *((uint8_t*)(&v) + 2);
*dst = *((uint8_t*)(&v) + 3);
}

Ну и не забывать разблокировать запись.
CODE

void EEPROM_Unlock(void)
{
FLASH_DUKR = FLASH_RASS_KEY2;
FLASH_DUKR = FLASH_RASS_KEY1;
}

void EEPROM_Lock(void)
{
FLASH_IAPSR_bit.DUL=0;
}


А дальше как обычно определяем неинициализированные и инициализированные переменные с модификатором __eeprom и компилятор сам всё сделает.
CODE
__no_init __eeprom uint8_t x;
#pragma data_alignment=4
__no_init __eeprom uint32_t y;
__no_init __eeprom uint8_t z;
__eeprom uint8_t test[10]={ 1,2,3,4,5,6,7,8,9,10 };

int main()
{
EEPROM_Unlock();
x=test[5];
z=x+1;
y=0x12345678;
EEPROM_Lock();
for(;;);
}


И даже при отладке IAR сам прошивает инициализированные __eeprom переменные вместе с кодом. Удобно.

Следует обратить внимание на следующие вещи:
- почему-то компилятор смело при оптимизации выкидывает переменные с модификатором __eeprom. Мне кажется они должны быть по умолчанию volatile как и SFR, но нет. Ну нет, так нет. В приложенном проекте пришлось обтыкать их volatile.
- STM8 32-битные переменные шьёт за один присест, но для этого они должны быть выровнены по 4. Приходится компилятору напоминать о выравнивании.
- что-то мне с ходу не удалось получить два раздельных HEX с кодом и eeprom, но у меня опыт с STM8 аж один день sm.gif Только сегодня STM8L-Discovery получил. Может кто научит?

Прикладываю проект для дискавери (STM8L152C6), может кому пригодится.
Прикрепленный файл  STM8_IAR_EEPROM.rar ( 27.42 килобайт ) Кол-во скачиваний: 68
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 31 2017, 09:22
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Jul 21 2017, 23:54) *
Следует обратить внимание на следующие вещи:
- почему-то компилятор смело при оптимизации выкидывает переменные с модификатором __eeprom. Мне кажется они должны быть по умолчанию volatile как и SFR, но нет. Ну нет, так нет. В приложенном проекте пришлось обтыкать их volatile.

Выкидывает вероятно потому, что у Вас в коде к ним нет обращений? И выкидывает тогда не компилятор, а компоновщик (по этой причине). И правильно делает.
"Обтыкивать" в этом случае (если они нужны, но обращений почему-то нет) нужно не volatile, а добавлять префикс __root (см. доку на IAR).
Хотя - может подумать - почему переменная описана, а обращений к ней нет? Может что-то в консерватории структуре программы неправильно построено? laughing.gif

PS: И почему у Вас инициализированные данные
__eeprom uint8_t test[10]={ 1,2,3,4,5,6,7,8,9,10 };
без модификатора const? Предполагается, что при каждом старте устройства, эти данные должны переписываться в EEPROM заново??? wacko.gif
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jul 31 2017, 11:01
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(jcxz @ Jul 31 2017, 12:22) *
Выкидывает вероятно потому, что у Вас в коде к ним нет обращений?

Как это нет? main() смотрим внимательнее.

Цитата(jcxz @ Jul 31 2017, 12:22) *
"Обтыкивать" в этом случае (если они нужны, но обращений почему-то нет) нужно не volatile, а добавлять префикс __root (см. доку на IAR).

Причём тут __root ? Обращения есть, модификатор __eeprom стоит, этого должно быть достаточно для запрета выкидывать операции с этими переменными.


Цитата(jcxz @ Jul 31 2017, 12:22) *
PS: И почему у Вас инициализированные данные
__eeprom uint8_t test[10]={ 1,2,3,4,5,6,7,8,9,10 };
без модификатора const?

А с какой стати они const? Мои переменные, захочу - изменю. EEPROM для того и нужен. Почему вы мне это решили запретить?
В принципе, процессор позволяет и во flash писать, так что, чисто теоретически, можно было бы неконстантную переменную и во flash разместить, главное с компилятором "договориться".

Цитата(jcxz @ Jul 31 2017, 12:22) *
Предполагается, что при каждом старте устройства, эти данные должны переписываться в EEPROM заново??? wacko.gif

Формально да, должен. Но если почитать докуентацию, то там будет следующее:
Цитата
.eeprom.data
Description Holds static and global initialized and zero-initialized __eeprom variables. Eeprom
data is persistent, so this section should not be included in any initialize by copy
linker directive.

То есть, компилятор генерит сегмент данных для eeprom. Что с ним делать дальше решает пользователь.
При отладке в железке или симуляторе отладчик автоматически каждый раз загружает его в eeprom - тут всё чисто.
В случае релиза мы его прошиваем ручками один раз при программировании чипа. При следующих стартах гарантии что там будет прежнее значение нет. Формально - отступление от стандарта, а реально лишь особенность, привнесённая модификатором __eeprom. Это ни хорошо, ни плохо, а так есть и удобно!

Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 31 2017, 11:25
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Jul 31 2017, 14:01) *
Как это нет? main() смотрим внимательнее.
Причём тут __root ? Обращения есть, модификатор __eeprom стоит, этого должно быть достаточно для запрета выкидывать операции с этими переменными.

И что там в main()? Смотрим внимательнее. wink.gif
Какие-то присваивания, каких-то переменных, которые потом больше нигде не используются, не передаются ни в какие функции и не присваиваются никаким volatile переменным?
Вот это и называется "переменная не используется", по этой причине компилятор/линкер имеет полное право её выкинуть.
Компилятор всё сделал правильно, а Вам стоит повышать свой уровень в написании ПО wink.gif

Цитата(VladislavS @ Jul 31 2017, 14:01) *
А с какой стати они const? Мои переменные, захочу - изменю. EEPROM для того и нужен. Почему вы мне это решили запретить?

Я Вам ничего не запрещаю, я просто читаю что у Вас там написано. А написано у Вас инструкция компилятору, что нужно разместить test в модифицируемой памяти и при старте ПО startup-код должен проинициализировать её указанным значением. Вот именно это компилятор и будет делать.
Возможно Вы именно этого и хотели. Но возможно что и нет, ибо это - одна из распространённых ошибок начинающих при описании инициализированных переменных в ОЗУ laughing.gif
Здесь как бы неясно - возможно, что в IAR ключевое слово __eeprom включает в себя неявно и префикс const, но трудно сказать.

Цитата(VladislavS @ Jul 31 2017, 14:01) *
можно было бы неконстантную переменную и во flash разместить, главное с компилятором "договориться".

"неконстантная переменная" - это нонсенс. Может быть или переменная или константа. Тут как ни договаривайся - компилятор мзду не берёт biggrin.gif

Цитата(VladislavS @ Jul 31 2017, 14:01) *
Формально да, должен. Но если почитать докуентацию, то там будет следующее:

Вполне возможно, что префикс __eeprom неявно включает в себя const. Но не факт.
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jul 31 2017, 12:31
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(jcxz @ Jul 31 2017, 14:25) *
Вот это и называется "переменная не используется", по этой причине компилятор/линкер имеет полное право её выкинуть.

Как это не используется? Она хранится в EEPROM после выключения питания! И компилятор об этом знает, я же ему об этом и указал посредством __eeprom. Я считаю это достаточным, разработчики компилятора нет. Это лишь условность, которая определена для модификатора __eeprom и я просто обратил на неё внимание, чтобы новички не попались.

Цитата(jcxz @ Jul 31 2017, 14:25) *
А написано у Вас инструкция компилятору, что нужно разместить test в модифицируемой памяти и при старте ПО startup-код должен проинициализировать её указанным значением. Вот именно это компилятор и будет делать.

Нет, не будет. Будет делать то что написано в документации, а что там написано - смотрите предыдущий пост.

Цитата(jcxz @ Jul 31 2017, 14:25) *
Возможно Вы именно этого и хотели. Но возможно что и нет,

Предлагаю подумать над вопросом почему у меня в примере инициализированные и неинициализированные переменные разной размерности и выравнивания применены.

Цитата(jcxz @ Jul 31 2017, 14:25) *
ибо это - одна из распространённых ошибок начинающих при описании инициализированных переменных в ОЗУ laughing.gif
Здесь как бы неясно - возможно, что в IAR ключевое слово __eeprom включает в себя неявно и префикс const, но трудно сказать.

Ошибка - делать умозаключение не прочитав документацию.

Цитата(jcxz @ Jul 31 2017, 14:25) *
"неконстантная переменная" - это нонсенс. Может быть или переменная или константа. Тут как ни договаривайся - компилятор мзду не берёт biggrin.gif

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

Цитата(jcxz @ Jul 31 2017, 14:25) *
Вполне возможно, что префикс __eeprom неявно включает в себя const. Но не факт.

А может почитать документацию, а не гадать?

jcxz, ну всё же, почему вы хотите EEPROM сделать const насильно? Он для того и придуман чтобы в него писать. Во так, например:
Прикрепленное изображение

Хотелось бы посмотреть как вы будете писать в константную переменную и что вам на это компилятор скажет.
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jul 31 2017, 14:26
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(jcxz @ Jul 31 2017, 14:25) *
Тут как ни договаривайся - компилятор мзду не берёт biggrin.gif


Ну это как предложить sm.gif Следите за руками.
Размещаем переменную во FLASH. Хотите неинициализированную, хотите инициализированную, не важно.
И записываем в неё.

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


Упс! Компилятор даже не пискнул! Но это так, чисто поржать. sm.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 31 2017, 15:10
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Jul 31 2017, 15:31) *
Как это не используется? Она хранится в EEPROM после выключения питания! И компилятор об этом знает, я же ему об этом и указал посредством __eeprom. Я считаю это достаточным, разработчики компилятора нет. Это лишь условность, которая определена для модификатора __eeprom и я просто обратил на неё внимание, чтобы новички не попались.

Попробуйте создать константу во флешь. И присвоить её значение какой-то переменной, которая потом не используется.
Корректный оптимизирующий компилятор её не поместит в выходной образ.
Шок! да?? Ведь если следовать Вашей логике как он мог её удалить - ведь оно там хранится (переменная в ОЗУ или константа во flash - не важно).
Странно почему это разработчики компиляторов считают по другому, не находите? Может надо пересмотреть своё видение мира?
И с __eeprom всё то же самое.

Цитата(VladislavS @ Jul 31 2017, 15:31) *
Ошибка - делать умозаключение не прочитав документацию.

Странные умозаключения Вы оттуда почерпнули. И то что они противоречат логике работы оптимизирующего компилятора, Вас похоже даже не насторожило - они все дураки, я один умный biggrin.gif

Цитата(VladislavS @ Jul 31 2017, 15:31) *
Ну да, получается, что этот массив обычная переменная, только с модификатором __eeprom, который намекает компилятору что с ней надо как-то по особенному работать.

Вот, до Вас уже всё таки доходит истина! rolleyes.gif
То, как Вы описали test - это именно переменная, а не константа. Наличие данных справа от неё говорит, что она инициализированная. А инициализацией переменных в си занимается стартап-код, который выполняется при старте ПО. Вот он и должен будет при старте устройства, записать в эту переменную указанное значение.
Как уж он это будет делать - другое дело, он может например перед записью сравнить имеющиеся по этому адресу данные, и если они равны записываемым - ничего не делать.

Цитата(VladislavS @ Jul 31 2017, 15:31) *
А может почитать документацию, а не гадать?

Документацию на что? На язык си? Да, пожалуй Вам стоит её почитать laughing.gif

Цитата(VladislavS @ Jul 31 2017, 15:31) *
jcxz, ну всё же, почему вы хотите EEPROM сделать const насильно? Он для того и придуман чтобы в него писать. Во так, например:

Я ничего не хочу. Я всего лишь написал, что то как описан был Ваш массив, как бы намекает что там должно быть ключевое слово const скорей всего.
А если там реально нет этого слова, то я написал что будет делать компилятор в этом случае.

Цитата(VladislavS @ Jul 31 2017, 15:31) *
Хотелось бы посмотреть как вы будете писать в константную переменную и что вам на это компилятор скажет.

Такого бреда я делать не буду. Ибо "константная переменная" - это Ваше изобретение. Вы сами то разве не понимаете бредовость этого термина??? wacko.gif
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jul 31 2017, 16:34
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(jcxz @ Jul 31 2017, 18:10) *
А если там реально нет этого слова, то я написал что будет делать компилятор в этом случае.

И попали пальцем в небо, потому что делать этого он не будет. Почему, читайте документацию на компилятор, я уже давал цитату.

Цитата(jcxz @ Jul 31 2017, 18:10) *
Ибо "константная переменная" - это Ваше изобретение.

Рекомендую ознакомиться с трудами Бьёрна Страуструпа. Можете даже оспорить их, а я пасс, пожалуй, понаблюдаю со стороны.

PS: я тут файлик внизу оставлю, не вздумайте его читать!
Прикрепленный файл  24._Constant_varyables.pdf ( 180.95 килобайт ) Кол-во скачиваний: 142
Go to the top of the page
 
+Quote Post
juvf
сообщение Aug 1 2017, 11:38
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



2VladislavS
Цитата(jcxz @ Jul 31 2017, 14:22) *
Предполагается, что при каждом старте устройства, эти данные должны переписываться в EEPROM заново??? wacko.gif

вопрос остался. у меня тоже этот вопрос возник и не нашел(не придумал) на него ответ


и ещё вопрос.... на сколько модификатор __eeprom съедает меньше флеша, чем spl?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2017, 13:08
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Aug 1 2017, 14:38) *
вопрос остался. у меня тоже этот вопрос возник и не нашел(не придумал) на него ответ

Товарищ противоречит сам себе, но даже этого не замечает. rolleyes.gif
При описании переменных, которые не должны ничем инициализироваться (даже нулями) он объявляет переменную как:
__no_init __eeprom uint8_t z;
что уже как бы намекает, что если её объявить без __no_init, то стартап-код её должен обнулить (как для обычных RAM-переменных) записью в EEPROM,
но при этом объявляет массив с начальным значением в __eeprom и упорно твердит что он не будет переписываться в EEPROM при каждом рестарте устройства.
Значит - где-то обманывает laughing.gif

Цитата(juvf @ Aug 1 2017, 14:38) *
и ещё вопрос.... на сколько модификатор __eeprom съедает меньше флеша, чем spl?

Ну так если:
__eeprom char const x[N] = {...};
то флеша ==0, только EEPROM.
А если:
__eeprom char x[N] = {...};
то как минимум N байт во флешь для хранения инициализационных данных {...} и ещё сколько-то байт на хранение процедуры записи EEPROM.
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Aug 1 2017, 14:09
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(juvf @ Aug 1 2017, 14:38) *
вопрос остался. у меня тоже этот вопрос возник и не нашел(не придумал) на него ответ

Инициализированные переменные с модификатором __eeprom не будут переписываться при каждом старте программы.
jcxz не слушайте, он неадекватен. Про сегменты EEPROM в документации IAR очень хорошо всё написано.
Смотрите, в конфигурационном файле линкера это всё отлично видно
CODE
/////////////////////////////////////////////////////////////////
// Example ILINK command file for
// STM8 IAR C/C++ Compiler and Assembler.
//
// Copyright 2017 IAR Systems AB.
//
/////////////////////////////////////////////////////////////////

define memory with size = 16M;

define region TinyData = [from 0x00 to 0xFF];

define region NearData = [from 0x0000 to 0x07FF];

define region Eeprom = [from 0x1000 to 0x13FF];

define region BootROM = [from 0x6000 to 0x67FF];

define region NearFuncCode = [from 0x8000 to 0xFFFF];

define region FarFuncCode = [from 0x8000 to 0xFFFF];

define region HugeFuncCode = [from 0x8000 to 0xFFFF];


/////////////////////////////////////////////////////////////////

define block CSTACK with size = _CSTACK_SIZE {};

define block HEAP with size = _HEAP_SIZE {};

define block INTVEC with size = 0x80 { ro section .intvec };

// Initialization
initialize by copy { rw section .far.bss,
rw section .far.data,
rw section .far_func.textrw,
rw section .huge.bss,
rw section .huge.data,
rw section .huge_func.textrw,
rw section .iar.dynexit,
rw section .near.bss,
rw section .near.data,
rw section .near_func.textrw,
rw section .tiny.bss,
rw section .tiny.data,
ro section .tiny.rodata };

initialize by copy with packing = none {section __DLIB_PERTHREAD };

do not initialize { rw section .eeprom.noinit,
rw section .far.noinit,
rw section .huge.noinit,
rw section .near.noinit,
rw section .tiny.noinit,
rw section .vregs };

// Placement
place at start of TinyData { rw section .vregs };
place in TinyData { rw section .tiny.bss,
rw section .tiny.data,
rw section .tiny.noinit,
rw section .tiny.rodata };

place at end of NearData { block CSTACK };
place in NearData { block HEAP,
rw section __DLIB_PERTHREAD,
rw section .far.bss,
rw section .far.data,
rw section .far.noinit,
rw section .far_func.textrw,
rw section .huge.bss,
rw section .huge.data,
rw section .huge.noinit,
rw section .huge_func.textrw,
rw section .iar.dynexit,
rw section .near.bss,
rw section .near.data,
rw section .near.noinit,
rw section .near_func.textrw };

place at start of NearFuncCode { block INTVEC };
place in NearFuncCode { ro section __DLIB_PERTHREAD_init,
ro section .far.data_init,
ro section .far_func.textrw_init,
ro section .huge.data_init,
ro section .huge_func.textrw_init,
ro section .iar.init_table,
ro section .init_array,
ro section .near.data_init,
ro section .near.rodata,
ro section .near_func.text,
ro section .near_func.textrw_init,
ro section .tiny.data_init,
ro section .tiny.rodata_init };

place in FarFuncCode { ro section .far.rodata,
ro section .far_func.text };

place in HugeFuncCode { ro section .huge.rodata,
ro section .huge_func.text };

place in Eeprom { section .eeprom.noinit };

place in Eeprom { section .eeprom.data };

place in Eeprom { section .eeprom.rodata };

/////////////////////////////////////////////////////////////////


Цитата(juvf @ Aug 1 2017, 14:38) *
и ещё вопрос.... на сколько модификатор __eeprom съедает меньше флеша, чем spl?

Библиотеки IAR для работы с EEPROM какие-то монстроидные. Прикладываю .map с моего примера. Вроде как 199 байт занимает.
Прикрепленный файл  st8test.zip ( 2.45 килобайт ) Кол-во скачиваний: 48

Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2017, 15:23
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Aug 1 2017, 17:09) *
Смотрите, в конфигурационном файле линкера это всё отлично видно

Товарищ одыкватный, в какую из приведённых в Вашей портянке секций компоновщика попадает ваше творение строкой ниже ?:
__eeprom uint8_t test[10]={ 1,2,3,4,5,6,7,8,9,10 };
и почему?
Go to the top of the page
 
+Quote Post
DS
сообщение Aug 1 2017, 16:02
Сообщение #13


Гуру
******

Группа: СуперМодераторы
Сообщений: 3 096
Регистрация: 16-01-06
Из: Москва
Пользователь №: 13 250




Прекратите хамить собеседнику. При повторении будет предупреждение.



--------------------
Не бойтесь тюрьмы, не бойтесь сумы, не бойтесь мора и глада, а бойтесь единственно только того, кто скажет - "Я знаю как надо". А. Галич.
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Aug 1 2017, 16:11
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Инициализированные переменные с модификатором __eeprom попадут в секцию .eeprom.data и будут размещены линкером в региона Eeprom. И всё это согласно "IAR C/C++ Development Guide Compiling and Linking for the STMicroelectronics STM8 Microcontroller Family" страница 372.

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

К сообщению приложил HEX с прошивкой, полученной из этого проекта. Найдите там во FLASH последовательность 1,2,3,4,5,6,7,8,9,10 которой по вашему при старте должен инициализироваться массив.

Страуструпа то переспорили?

Прикрепленный файл  stm8_eeprom.zip ( 824 байт ) Кол-во скачиваний: 36




Go to the top of the page
 
+Quote Post
Эдди
сообщение Aug 1 2017, 16:19
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250



Подтверждаю, никаких const писать не надо. Вот так вполне работает, ничего при старте не копируется.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th April 2024 - 08:37
Рейтинг@Mail.ru


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