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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Начальная инициализация статических переменных.
Вячик13
сообщение Jul 9 2012, 06:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Среда - Keil Arm. Контроллер STM32F103.
В Keil имеется функция SystemInit(), которая выполняется перед main().

Описание эффекта.
В функции SystemInit() инициализируется несколько указателей-параметров объекта. При входе в функцию main() эти параметры обнуляются.

Вопрос.
Что это? Возможно начальная инициализация статических переменных происходит после выполнения SystemInit()? Не похоже. Какие-то "заморочки со стеком?" может я какую-то "галочку" в опциях проекта не поставил?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 06:49
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Вячик13 @ Jul 9 2012, 09:36) *
В функции SystemInit() инициализируется несколько указателей-параметров объекта.

Например?
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 07:09
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 09:49) *
Например?


typedef struct TExtADCResult {
bool Exist;
unsigned long Value;
} TExtADCResult;

typedef struct TExtADC {
TSPI *SPIPtr;
void (*Select)(void);
void (*Unselect)(void);
void (*Start)(void);
void (*Stop)(void);
bool (*Ready)(void);
void (*Reset)(void);
TExtADCResult Result[8];
bool Exist;
} TExtADC;

#define ExtADC_CHAN_NUMBER 2

TExtADC ExtADCChanel[ExtADC_CHAN_NUMBER];

void SystemInit(void) {
PeriferInit();
}

void PeriferInit(void) {
TExtADC_Create(&ExtADCChanel[0],&SPIChanel[0],&ExtADC1_Select,&ExtADC1_Unselect,&ExtADC_Start,&ExtADC_Stop,ExtADC1_Ready,ExtADC_Reset);
TExtADC_Create(&ExtADCChanel[1],&SPIChanel[0],&ExtADC2_Select,&ExtADC2_Unselect,&ExtADC_Start,&ExtADC_Stop,ExtADC2_Ready,ExtADC_Reset);
}

В TExtADC_Create() идёт обыкновенное присвоение указателям ссылок на функции. Смотрю объект ExtADCChanel[0].

Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 07:30
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Смотрите, что есть в startup.
Код
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

Видите __main - вот там все и устанавливается.
Вы сами добавили кода в SystemInit()? А чем не устроило сделать это в main?
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 07:36
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 10:30) *
Смотрите, что есть в startup.
Код
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

Видите __main - вот там все и устанавливается.
Вы сами добавили кода в SystemInit()? А чем не устроило сделать это в main?


Вот мой startup:

Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
По-моему не отличается ничем.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 07:50
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Вячик13 @ Jul 9 2012, 10:36) *
По-моему не отличается ничем.

И это правильно. Еще раз прочитайте мой ответ.

Цитата(Вячик13 @ Jul 9 2012, 09:36) *
Возможно начальная инициализация статических переменных происходит после выполнения SystemInit()? Не похоже.

Не "не похоже", а именно так!
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 08:05
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 10:50) *
И это правильно. Еще раз прочитайте мой ответ.


Не "не похоже", а именно так!


Не понял, а где именно выполняется инициализация переменных? Где вызов подпрограммы? В приведенном ассемблерном коде я его не вижу. Ну и что из того, что сначала выполняется SystemInit(), а потом main()? Или инициализация выполняется в начале работы main()?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 9 2012, 08:11
Сообщение #8


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Вячик13 @ Jul 9 2012, 11:05) *
Не понял, а где именно выполняется инициализация переменных? Где вызов подпрограммы? В приведенном ассемблерном коде я его не вижу. Ну и что из того, что сначала выполняется SystemInit(), а потом main()? Или инициализация выполняется в начале работы main()?

где же main(), если __main()?
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 9 2012, 08:20
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(ViKo @ Jul 9 2012, 11:11) *
где же main(), если __main()?


А... Теперь понял. Спасибо, учту в программе.
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 10 2012, 10:16
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



в 20х числах июня, Томас Дреслер из ST совместно с дистрибьюторами проводил семинары (Москва, Питер, Ебург) на тему STM32F4... и как раз это все разжевал. Многие при этом возмущались - зачем типа нам это все знать.
В том числе почему SystemInit вызывается до __main и что еще инициализируется в __main...

Сообщение отредактировал kan35 - Jul 10 2012, 10:17
Go to the top of the page
 
+Quote Post
Вячик13
сообщение Jul 11 2012, 04:58
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604



Цитата(kan35 @ Jul 10 2012, 13:16) *
в 20х числах июня, Томас Дреслер из ST совместно с дистрибьюторами проводил семинары (Москва, Питер, Ебург) на тему STM32F4... и как раз это все разжевал. Многие при этом возмущались - зачем типа нам это все знать.
В том числе почему SystemInit вызывается до __main и что еще инициализируется в __main...

С удовольствием съездил бы послушал. Но попасть на эти семинары в те города, которые Вы перечислили, из моего провинциального украинского городка и небольшой частной фирмы - это всё равно, что слетать на Луну. Так что пока единственное спасение - это вот такие конференции и бескорыстная помощь моих уважаемых коллег.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 11 2012, 05:19
Сообщение #12


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(kan35 @ Jul 10 2012, 13:16) *
В том числе почему SystemInit вызывается до __main и что еще инициализируется в __main...

И почему, и что? Как там на семинаре объясняли? Не доложите вкратце?
По-моему - зря функцию установки тактовой частоты назвали SystemInit.
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 11 2012, 06:01
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



SystemInit или собственно говоря установка частоты процессора и памяти делается в первую очередь так как происходящее в __main инициализация глобалных и статических переменных на дефолтной частоте может занять ощутимо много времени, если это критично конечно.
Еще, если вы используете массивы в RAM и если они значительные, то для экономии flash (из которой эти данные перегружаются) можно самостоятельно инициализировать их (не в __main), например применяя архивацию данных. Еще в __main инициализируется heap. это все что я вспомнил))
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 11 2012, 21:10
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А по-моему, всё гораздо проще.
SystemInit - это от ST, а __main - от кейла. И ST банально не может вызвать SystemInit после __main, потому что оттуда нет возврата laughing.gif
Косвенно это подтверждается тем фактом, что в стартапе для GCC (TrueSTUDIO) сделано по уму - сначала инициализация data и bss, и только потом - вызов SystemInit.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 12 2012, 04:11
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Цитата(AHTOXA @ Jul 12 2012, 01:10) *
А по-моему, всё гораздо проще.
SystemInit - это от ST, а __main - от кейла. И ST банально не может вызвать SystemInit после __main, потому что оттуда нет возврата laughing.gif

Эти рассуждения не выдерживают никакой критики. Почему бы тогда по вашей логиге банально не вызывать SystemInit в сомом main()? Инициализация на 16МГц и на 168МГц - чувствуете разницу?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 12 2012, 09:05
Сообщение #16


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(kan35 @ Jul 12 2012, 10:11) *
Почему бы тогда по вашей логиге банально не вызывать SystemInit в сомом main()?
Потому что main - это уже пользовательское приложение. А ST пыталась сделать шаблон. Как раз для того, чтобы пользователю в main ничего не надо было писать.
Цитата(kan35 @ Jul 12 2012, 10:11) *
Инициализация на 16МГц и на 168МГц - чувствуете разницу?

А при использовании GCC, по вашей "логиге", проц стартует сразу на 168МГц? sm.gif
Я понимаю, что вы послушали "спецов" из ST, и прониклись. Но голову-то включать иногда надо?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 12 2012, 11:45
Сообщение #17


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Вы сказали, что в GCC сначала происходит инициализация, а "SystemInit"после. Если это так, то это неправильно как раз. Производить инициализацию в 10 раз медленнее чем позволяет проц - не всегда позволительно.
А то, что это делается чтобы в main ничего не писать - хм... логики не вижу. Ну и пусть бы на 16МГц работал на старте, вообще бы никаких SystemInit не было - какой в этом криминал, в конце концов далеко не всем нужна максимальная частота (или не всегда максимальная). В общем я проникся, вы правы :-)
Go to the top of the page
 
+Quote Post
редактор
сообщение Jul 12 2012, 12:19
Сообщение #18


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



SystemInit() от STM приводит контроллер в исходное состояние (включает HSI, запрещает прерывания и проч). И правильнее это сделать до вызова main(), а не после этого.
Скорее всего прав АНТОХА. Вызывать свою функцию из библиотеки Keil нельзя, а вот перед ее выполнением легко. STM упростило себе и начинающим жизнь, а гуру все равно под себя переделают.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 12 2012, 13:17
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Цитата(редактор @ Jul 12 2012, 16:19) *
SystemInit() от STM приводит контроллер в исходное состояние (включает HSI, запрещает прерывания и проч).

А вы уверены что SystemInit делает то что вы написали?
Мне показалось я АНТОХу только что убедил, а тут Вы нарисовались smile3046.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 12 2012, 19:42
Сообщение #20


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(kan35 @ Jul 12 2012, 17:45) *
Вы сказали, что в GCC сначала происходит инициализация, а "SystemInit"после. Если это так, то это неправильно как раз. Производить инициализацию в 10 раз медленнее чем позволяет проц - не всегда позволительно.

Суть в том, что в трёх вариантах из пяти сделано так. То есть, при наличии возможности выбрать, что делать сначала, инициализацию переменных или вызов SystemInit() (это gcc_ride7, TASKING и TrueSTUDIO) -- сначала идёт инициализация переменных. А в двух случаях, где этого выбора нет (keil и IAR) - сделали как смогли.
И получилось, кстати, не по стандарту Си. (Но тут я не особо силён, и могу ошибаться.)

Так что товарищ из ST, который вам это обосновывал - скорее всего "импровизировал" sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 13 2012, 05:58
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Ну и отвлекаясь от обсуждения квалификации инженера из ST, с вашего позволения подытожу, что все перечисленные - gcc_ride7, TASKING и TrueSTUDIO в >10 раз медленнее выводят контроллер на рабочий код, чем компиляторы iar и keil, с этим вы спорить будете? ;-)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 13 2012, 08:08
Сообщение #22


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



То есть, по поводу квалификации инженера из ST у нас уже консенсус? sm.gif
Конечно буду sm.gif
В случае этой троицы разработчик имеет полный контроль. Надо ускорить запуск - ничто не мешает переписать стартап. По крайней мере это будет осознанное решение.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
редактор
сообщение Jul 13 2012, 11:50
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Цитата
А вы уверены что SystemInit делает то что вы написали?

Да уверен. Я посмотрел исходник от ST из комплекта Keil (v4.23) для серии ST32F10X.
Не особо вдаваясь в код, бегло просмотрел коментарии и сделал выводы.

Насчет HSI поторопился немного. Сперва сбрасывается на внутренний генератор, затем выставляется системная частота в зависимости от дефайна.

Цитата
И получилось, кстати, не по стандарту Си.

Поскольку стандарт описывает поведение программы, а не поведение железа, то предварительную (дефолтовую) ноастройку можно отнести как к подготовительным операциям (типа инициализации статических переменных), так и к исполнению пользовательского кода.
Инженеры ST придерживаются первого варианта.

Сообщение отредактировал редактор - Jul 13 2012, 12:25


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 14 2012, 15:07
Сообщение #24


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Напомню, что переменные могут располагаться и во внешней памяти. А встроенный контроллер к ней перед этим нужно еще инициализировать. Иначе - никак.
Поэтому объяснение инженера из ST мне представляется верным. Поддерживаю kan35.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 14 2012, 21:06
Сообщение #25


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ViKo @ Jul 14 2012, 21:07) *
Напомню, что переменные могут располагаться и во внешней памяти. А встроенный контроллер к ней перед этим нужно еще инициализировать. Иначе - никак.
Поэтому объяснение инженера из ST мне представляется верным. Поддерживаю kan35.

А в случае с gcc_ride7, TASKING и TrueSTUDIO объяснения инженера из ST надо просто инвертировать? sm.gif
Если честно, то не ожидал, что моё очевидное наблюдение вызовет столько возражений.
Ещё раз: да, могут быть случаи, когда надо сначала инициализировать тактирование и/или внешнюю память, а уже потом - статические переменные. Но, (и это - соль моего наблюдения) программисты из ST совершенно не думали ни о чём таком. Если бы думали, то сделали бы во всех вариантах одинаковый порядок.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 15 2012, 05:20
Сообщение #26


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



АНТОХА, действительно, разница в шаблонах имеется, сейчас я специально тоже посмотрел. И обратил внимание, что в TASKING сделано как в IAR и KEIL, хотя можно было сделать как в GCC, но не было сделано!
Из всех тобою перечисленных только GCC (TRUEStudio и gcc_ride7 - одно и то же, даже sturtup у них практически копии). Итого пропорция складывается 3:1 не в твою пользу и не в пользу бесплатного средства. И, конечно остается вопрос, почему ST в варианте GCC сделали иной порядок, возможно для GCC пишут не те же программеры, что для коммерческих сред. Правдоподобно?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 15 2012, 06:15
Сообщение #27


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да, точно, с TASKING-ом я был невнимателен. Тогда соглашусь, скорее всего писали разные люди.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jul 15 2012, 18:13
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(AHTOXA @ Jul 15 2012, 00:06) *
да, могут быть случаи, когда надо сначала инициализировать тактирование и/или внешнюю память, а уже потом - статические переменные.

Почему "могут быть"?
Разве такая последовательность ( 1. инициализация тактирование, 2. инициализация внешней памятиб если она есть 3. инициализация переменых) не наиболее логична? Просто обычно не критично на какой тактовой она выполнится.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 15 2012, 19:58
Сообщение #29


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Потому что при вызове сишной функции SystemInit() мы должны обеспечить инициализированные статические переменные и обнулённые неинициализированные. Это вроде как по стандарту языка Си.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
редактор
сообщение Jul 16 2012, 05:34
Сообщение #30


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Если бы сишная функция была включена в стартап в виде ассемблерного модуля, этот диалог не состоялся бы.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 16 2012, 07:59
Сообщение #31


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Все, что делается до main, принадлежит операционной системе. В микроконтроллерах в данном случае от нее - только SystemInit() да __main. А мог бы быть и Линукс какой-нибудь. Или Keil RTX.
Вообще, не вижу предмета для разговора, тем более, спора.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 16 2012, 09:55
Сообщение #32


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ViKo @ Jul 16 2012, 13:59) *
Все, что делается до main, принадлежит операционной системе.

Язык Си совершенно ортогонален операционной системе. Вы наверное имели в виду что-то типа "принадлежит библиотеке времени исполнения языка си, aka CRT"? Тогда да. Но тут опять-таки возникает вопрос, допустимо ли писать эту библиотеку на си? Вернее, можно ли писать на си её функции, которые будут вызываться до инициализации статических переменных и bss? Мне кажется, что это не совсем корректно.
Цитата(ViKo @ Jul 16 2012, 13:59) *
Вообще, не вижу предмета для разговора, тем более, спора.

Но вы же зачем-то разговариваете? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 16 2012, 10:50
Сообщение #33


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(AHTOXA @ Jul 16 2012, 12:55) *
Язык Си совершенно ортогонален операционной системе. Вы наверное имели в виду что-то типа "принадлежит библиотеке времени исполнения языка си, aka CRT"? Тогда да. Но тут опять-таки возникает вопрос, допустимо ли писать эту библиотеку на си? Вернее, можно ли писать на си её функции, которые будут вызываться до инициализации статических переменных и bss? Мне кажется, что это не совсем корректно.

Имел в виду что-то типа http://en.wikipedia.org/wiki/Run-time_system
Насчет допустимости - если представить, что SystemInit - это часть RTS, а main и остальное - свой отдельный проект, то и противоречий не наблюдается.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 16 2012, 12:18
Сообщение #34


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Если SystemInit написать на ассемблере, то не наблюдается. Иначе - противоречие есть.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 16:47
Рейтинг@Mail.ru


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