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

 
 
6 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> TNeo: тщательно протестированная РТОС для Cortex-M0/M0+/M3/M4/M4F, PIC24/dsPIC, PIC32MX.
dimonomid
сообщение Jan 18 2015, 01:41
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Представляю новое ядро реального времени: TNeo. Как можно догадаться из названия, изначально она основана на TNKernel, но в итоге код был переписан почти полностью (потому что оригинальный код, по моему мнению, далек от совершенства), написаны подробные юнит-тесты, исправлены ошибки и добавлено много новых фич.

Список найденных и исправленных ошибок в TNKernel 2.7 можно посмотреть тут: http://dfrank.bitbucket.org/tneokernel_api...implement__bugs

Код TNeo написан аккуратно и тщательно, документирован очень подробно. Документация генерируется автоматически посредством doxygen, таким образом, легко поддерживать документацию в актуальном состоянии:
Список новых возможностей:

* Dynamic tick (опционально): если системе нечего делать, эта опция позволяет действительно ничего не делать (уйти в sleep), и даже не просыпаться каждую миллисекунду для обработки системного тика. Подробнее: http://dfrank.bitbucket.org/tneokernel_api...time_ticks.html
* Timer: позволяет попросить ядро запустить пользовательскую функцию через определенный промежуток времени. Подробнее: http://dfrank.bitbucket.org/tneokernel_api...__timer_8h.html
* Event group connection: позволяет "соединить" группу флагов с другими объектами РТОС. Очень удобно в случаях, когда в задаче нужно ждать, скажем, сообщения из нескольких очередей, или ждать каких-то флагов плюс сообщения из очереди. Подробнее: http://dfrank.bitbucket.org/tneokernel_api...ventgrp_connect
* Profiler (опционально): позволяет узнать общее время работы каждой задачи, максимальное время работы задачи подряд и т.д. Полезно для отладки.
* Software stack overflow check (опционально) - программный контроль переполнения стека, очень существенно облегчает дебаг;
* Recursive mutexes (опционально) - позволяет вложенную блокировку мютексов;
* Mutex deadlock detection (опционально) - в случае deadlock, ядро сообщает об этом посредством callback-функции;
* Separate interrupt stack - на всех поддерживаемых платформах прерывания используют отдельный стек.

Полный список фич тут: http://dfrank.bitbucket.org/tneokernel_api...l/features.html
Отличия API TNeo от API TNKernel 2.7 тут: http://dfrank.bitbucket.org/tneokernel_api...ernel_diff.html

Чем не устраивает TNKernel: см. документацию: Why reimplement TNKernel, также можно посмотреть мой старый пост на этом форуме: http://electronix.ru/forum/index.php?s=&am...t&p=1280109

Кратко: ключевые проблемы TNKernel:
  • Самая основная проблема в том, что TNKernel - проект, написанный на коленке, т.е. в спешке. Огромное количество дублирования кода, непоследовательности и недостаточной продуманности.
  • Проект не тестировался (только "вручную", как это нередко делается в эмбеддинге, к сожалению). Среди найденных багов есть банальнейшие ситуации с мютексами, которые не обрабатываются ядром корректно (см. ссылку на список багов выше). Ну, учитывая первый пункт про спешку, отсутствие тестов неудивительно, т.к. на них нужно огромное количество времени. У меня на тесты ушло примерно столько же времени, сколько на само ядро.
  • Документация живет отдельной от самого ядра жизнью.
  • Проект не поддерживается. Я присылал Юрию исправления некоторых ошибок, мои сообщения были проигнорированы.


Любопытный читатель может спросить: если уж я так сильно ругаю TNKernel, почему же я взял это ядро за основу? С удовольствием отвечу: не смотря на то, что реализация TNKernel, по моему мнению, далека от совершенства, идеи, стоящие за реализацией, я считаю в целом очень достойными. Ядро компактное и быстрое, и данные организованы грамотно.

Я хотел переписать его так, чтобы на код было приятно смотреть и легко модифицировать (не боясь что-то сломать), хотел быть уверенным в отсутствии багов (посредством юнит-тестов), хотел достойную актуальную документацию. Все это готово.

Попутно я реализовал вещи, которых мне самому раньше не хватало, плюс реализовал пожелания людей, заинтересовавшихся проектом (я представил TNeo на семинаре Microchip MASTERS 2014, после чего и получил предложение реализовать порт для линейки Cortex-M и несколько других фич)

Выражаю огромную благодарность Юрию за проделанную работу над TNKernel: без нее, конечно, TNeo никогда не появилась бы. Полный список благодарностей можно прочитать на странице Thanks.
Go to the top of the page
 
+Quote Post
Aner
сообщение Jan 18 2015, 11:11
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 869
Регистрация: 28-02-08
Из: СПБ
Пользователь №: 35 463



Под IAR c Cortex не планируется?
Go to the top of the page
 
+Quote Post
dimonomid
сообщение Jan 18 2015, 11:23
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Цитата(Aner @ Jan 18 2015, 15:11) *
Под IAR c Cortex не планируется?

Под IAR только добился того, что ядро собирается. Собранный бинарник в работе не тестировал. Должно работать, но сюрпризы от компилятора не исключены, конечно. В ближайших планах такого тестирования нет.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jan 18 2015, 12:30
Сообщение #4


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(dimonomid @ Jan 18 2015, 03:41) *
Попутно я реализовал вещи, которых мне самому раньше не хватало, плюс реализовал пожелания людей, заинтересовавшихся проектом (я представил TNeo на семинаре Microchip MASTERS 2014, после чего и получил предложение реализовать порт для линейки Cortex-M и несколько других фич)


Не могли бы вы показать примеры ваших разработок с использованием RTOS?

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

Скажем такие страсти вокруг мьютексов.
С виду нужная фича.
Но вот смотрю в MQX в основном дистрибутиве и не нахожу где бы вызывались сервисы мьютексов.
Хотя в RTOS они реализованы, хорошо документированы, развиты.
Но во всем промежуточном ПО включая файловую систему, USB стеки, TCP/IP стеки, сетевые сервисы, командные оболочки, драйверы нигде не применяются мьютексы.

Т.е. разработчики потратили на мьютексы уйму времени, а зачем они нужны в жизни не знают.
Комично однако. wink.gif
Go to the top of the page
 
+Quote Post
dimonomid
сообщение Jan 18 2015, 13:15
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Цитата(AlexandrY @ Jan 18 2015, 17:30) *
Не могли бы вы показать примеры ваших разработок с использованием RTOS?

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

Скажем такие страсти вокруг мьютексов.
С виду нужная фича.
Но вот смотрю в MQX в основном дистрибутиве мьютексы вообще! нигде не применяются.
Хотя в RTOS они есть, хорошо документированы, развиты.
Но во всем промежуточном ПО включая файловую систему, USB стеки, TCP/IP стеки, сетевые сервисы, командные оболочки, драйверы нигде не применяются мьютексы.

Т.е. разработчики потратили на мьютексы уйму времени, а зачем они нужны в жизни не знают.
Комично однако. wink.gif


Опен-сорсных разработок нет, только для конторы, так что показать примеры не могу. Может потом добавлю что-нибудь в examples, но вряд ли скоро.

То, что многие эмбеддеры не знают, зачем нужны мютексы, не новость: вот яркий пример http://www.microchip.su/showthread.php?p=1...near#post185067 . Да что там мютексы, многие не знают зачем нужна РТОС. Типа, и так можно написать. Спорить не буду - можно и без мютексов написать, и без РТОС, и без C, и т.д.

Вот очень хорошая небольшая статья на тему мютексов и семафоров http://www.barrgroup.com/Embedded-Systems/...Mutex-Semaphore

Вкратце, мютекс нужен для доступа к разделяемому ресурсу. Например, если в двух (или более) задачах используется, скажем, внешняя SPI-флешка, т.е. они обе эту флешку читают/пишут, то нужно быть уверенным в том, что они не будут друг другу мешать работать с флешкой. С этим не будете спорить?

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

То, что в большинстве библиотек не используются мютексы - логично, потому что в большинстве случаев мютексы должны уже использоваться в самом приложении, а не в библиотеке. Взять вот тот же пример с флешкой: допустим, я оформлю библиотеку для чтения-записи во флеш в виде библиотеки. Если в приложении эта библиотека будет использоваться, например, только из одной задачи, то и мютекс тут необязателен. Так зачем включать его использование в либу? Разумнее сделать так: обязать пользователя реализовать две функции: lock() / unlock(), и при работе с флешкой вызывать их. Если пользователь либы решит использовать мютекс, он будет его использовать в этих lock() / unlock(). А может, он решит как-то иначе обеспечивать атомарный доступ, а может вообще не нужна ему блокировка, тогда он оставит эти функции пустыми, и все.

У меня в среднего размера проекте обычно 5-7 задач и около 10 мютексов, если что. Вообще, рассуждать на эти темы нет особого желания. Если человек утверждает, что мютексы-де не нужны, то обычно получается просто религиозный спор. Как я уже сказал, да, можно все написать и без мютексов, и без РТОС, и т.д.
Go to the top of the page
 
+Quote Post
nill
сообщение Jan 18 2015, 13:58
Сообщение #6


Частый гость
**

Группа: Validating
Сообщений: 124
Регистрация: 10-08-05
Пользователь №: 7 502



Планируете переносить TN NET на своё ядро? И есть ли вообще планы по реализации интерфейсов?
Go to the top of the page
 
+Quote Post
dimonomid
сообщение Jan 18 2015, 14:14
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Цитата(nill @ Jan 18 2015, 17:58) *
Планируете переносить TN NET на своё ядро? И есть ли вообще планы по реализации интерфейсов?

Пока нет таких планов. Честно говоря я TN NET и не использовал, не было необходимости, так что я его пока в глаза не видел и не могу сказать, насколько это сложная работа. Но все свои поддерживаемые проекты уже, конечно, перенес с TNKernel на TNeo, даже один чужой кортексовый проект перенес, особых проблем не было. API не 100% совместим, но если включить режим совместимости с TNKernel (TN_OLD_TNKERNEL_NAMES, TN_OLD_EVENT_API) , то изменения API тривиальные, логику работы приложения продумывать заново не нужно.

Ссылку на отличия API уже приводил в первом посте.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jan 18 2015, 14:30
Сообщение #8


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(dimonomid @ Jan 18 2015, 04:41) *
Представляю новое ядро реального времени: TNeo.


А скачать-то ее откуда-нибудь можно? Или отсюда по одному файлику вылавливать? (там их десятка три, да еще и по разным директориям хитрО разложены)
Go to the top of the page
 
+Quote Post
dimonomid
сообщение Jan 18 2015, 14:39
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Цитата(Xenia @ Jan 18 2015, 18:30) *
А скачать-то ее откуда-нибудь можно? Или отсюда по одному файлику вылавливать? (там их десятка три, да еще и по разным директориям хитрО разложены)

Вот в том самом предложении, которое вы процитировали:
Цитата(dimonomid)
Представляю новое ядро реального времени: TNeo

Нажимаете на TNeo - попадаете на bitbucket. Можете или клонировать Mercurial-репозиторий, или зайти там в "Downloads" и просто скачать там последний собранный релиз.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jan 18 2015, 15:09
Сообщение #10


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(dimonomid @ Jan 18 2015, 17:39) *
Вот в том самом предложении, которое вы процитировали:
Нажимаете на TNeo - попадаете на bitbucket. Можете или клонировать Mercurial-репозиторий, или зайти там в "Downloads" и просто скачать там последний собранный релиз.


Спасибо! Получилось.

Тогда уж позвольте задать вам еще два вопроса. Один умный, а другой глупый. sm.gif

1. Известно, что TNKernel поддерживает MSP430x (по крайней мере, такой проект у них был), тогда так TNeo его не поддерживает, хотя и позиционирует себя, как дальнейшее развитие TNKernel. Что стряслось? Возросли требования к архитектуре? Или возникло презрение к MSP430x, как к "вымирающему" виду? sm.gif

2. Может ли TNKernel или TNeo быть портированы на ... AVR? sm.gif Понятно, что не на Tiny или Mega, а хотя бы на Xmega? Если нет, то что этому мешает? Мало памяти, гарвардская архитектура, недостаточно уровней вложения прерываний? Или что-то еще?
Go to the top of the page
 
+Quote Post
dimonomid
сообщение Jan 18 2015, 15:32
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Цитата(Xenia @ Jan 18 2015, 20:09) *
1. Известно, что TNKernel поддерживает MSP430x (по крайней мере, такой проект у них был), тогда так TNeo его не поддерживает, хотя и позиционирует себя, как дальнейшее развитие TNKernel. Что стряслось? Возросли требования к архитектуре? Или возникло презрение к MSP430x, как к "вымирающему" виду? sm.gif

Если TNeo и позиционирует себя как развитие TNKernel, то безотносительно конкретных поддерживаемых архитектур. Так что ничего особо не стряслось: ни требования не возросли, ни презрения не появилось.

Когда я только начинал работать над TNeo, я честно говоря и не думал что получится так глобально. Просто запилил себе порт под PIC32, потому что существующие порты меня категорически не устраивали тем, как там организован стек для прерываний. По ходу перепиливания ядра, это ядро нравилось мне все меньше и меньше, и я решил "сделать хорошо". Чтобы ничего не сломать, сначала написал подробные юнит-тесты. Пока писал тесты, нашел ошибки в оригинальном ядре. Потом пошло-поехало: давно хотел таймеры, давно хотел то да сё.

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

В итоге понравилось как оно получилось, решил перенести существующие проекты на PIC24 на него. Запилил порт под это дело.

Потом на семинаре Microchip рассказал про свое ядро, некоторые товарищи заинтересовались и сделали мне деловое предложение запилить порт под линейку Cortex-M и еще несколько плюшек. Я отказываться не стал. sm.gif

Если кто-нибудь сделает аналогичное предложение запилить порт под MSP430x, я вряд ли откажусь. Но и предложение тоже вряд ли сделают, я думаю. sm.gif

Цитата(Xenia @ Jan 18 2015, 20:09) *
2. Может ли TNKernel или TNeo быть портированы на ... AVR sm.gif. Понятно, что не на Tiny или Mega, а хотя бы на Xmega? Если нет, то что этому мешает? Мало памяти, гарвардская архитектура, недостаточно уровней вложения прерываний? Или что-то еще?


Я никогда не работал с AVR и не могу точно сказать, но почти уверен, что технически ничего не мешает. Так что тут та же ситуация что и с MSP430x: если мне кто-то сделает интересное предложение запилить порт под AVR, я вряд ли откажусь.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jan 18 2015, 16:10
Сообщение #12


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(dimonomid @ Jan 18 2015, 18:32) *
Просто запилил себе порт под PIC32,... В итоге понравилось как оно получилось, решил перенести существующие проекты на PIC24 на него. Запилил порт под это дело. ... Потом ...сделали мне деловое предложение запилить порт под линейку Cortex-M и еще несколько плюшек.

Понятно. Я примерно так и предполагала: вы один, а контроллеров много - на все вас просто не хватило. sm.gif

Цитата(dimonomid @ Jan 18 2015, 18:32) *
Я никогда не работал с AVR и не могу точно сказать, но почти уверен, что технически ничего не мешает. Так что тут та же ситуация что и с MSP430x: если мне кто-то сделает интересное предложение запилить порт под AVR, я вряд ли откажусь.

А как бы вы прокомментировали шансы "АНТИпредложения", когда какой-то человек (или человечка sm.gif) хотел бы запилить вашу TNeo на Xmega сам? Т.е. мой вопрос сводится к следующему - какой из двух путей портирования этой RTOS вы оценили бы, как более сложный?
1. Когда вы сами портируете TNeo (все нюансы которой вы знаете) на совершенно неизвестный вам контроллер.
или
2. Когда этим занимается человек, в совершенстве тот контроллер знающий, но почти ничего не знающий про TNeo?

Т.е. для успешного выполнения такой работы, в какой области требуется иметь больше знаний/опыта: по части данной RTOS или по части железа МК?
Go to the top of the page
 
+Quote Post
dimonomid
сообщение Jan 18 2015, 16:31
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Цитата(Xenia @ Jan 18 2015, 20:10) *
А как бы вы прокомментировали шансы "АНТИпредложения", когда какой-то человек (или человечка sm.gif) хотел бы запилить вашу TNeo на Xmega сам? Т.е. мой вопрос сводится к следующему - какой из двух путей портирования этой RTOS вы оценили бы, как более сложный?
1. Когда вы сами портируете TNeo (все нюансы которой вы знаете) на совершенно неизвестный вам контроллер.
или
2. Когда этим занимается человек, в совершенстве тот контроллер знающий, но почти ничего не знающий про TNeo?

Т.е. для успешного выполнения такой работы, в какой области требуется иметь больше знаний/опыта: по части данной RTOS или по части железа МК?

Субъективно кажется что вариант 2 проще, конечно. Ничего там в TNeo сложного нет, вот документация почти всего architecture-dependent интерфейса: http://dfrank.bitbucket.org/tneokernel_api...n__arch_8h.html , все банально. "Почти" - потому что есть еще несколько макросов, не включенных в этот файл, но там так вообще ерунда. По аналогии с другими архитектурами делается элементарно.

Ну и если человек, кроме Xmega, хотя бы примерно знает любую из уже поддерживаемых архитектур (т.е. PIC24 / PIC32 / Cortex-M), то все еще проще: всегда можно посмотреть, как то или иное сделано в других архитектурах, и сделать аналогично.

И если всерьез кто-то этим займется - подсказать что-то по TNeo я всегда рад. Для облегчения совместной работы еще очень желательно чтобы коллега пользовался Mercurial - потом на bitbucket просто с помощью pull-request все сольем без гемора.

Так что ничего особо сложного, если есть желание - главное начать! sm.gif

Правда, отдельный гемор будет с юнит-тестами: и код там далеко не такой хороший как в ядре, и API не документирован, нужно по аналогии с другими архитектурами смотреть. Вылизывать проект юнит-тестов времени уже не хватило; задачу свою выполняют - и хорошо.

Но, конечно, все решаемо.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jan 18 2015, 21:42
Сообщение #14


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(dimonomid @ Jan 18 2015, 15:15) *
То, что многие эмбеддеры не знают, зачем нужны мютексы, не новость: вот яркий пример http://www.microchip.su/showthread.php?p=1...near#post185067 . Да что там мютексы, многие не знают зачем нужна РТОС. Типа, и так можно написать. Спорить не буду - можно и без мютексов написать, и без РТОС, и без C, и т.д.

Вот очень хорошая небольшая статья на тему мютексов и семафоров http://www.barrgroup.com/Embedded-Systems/...Mutex-Semaphore

Вкратце, мютекс нужен для доступа к разделяемому ресурсу. Например, если в двух (или более) задачах используется, скажем, внешняя SPI-флешка, т.е. они обе эту флешку читают/пишут, то нужно быть уверенным в том, что они не будут друг другу мешать работать с флешкой. С этим не будете спорить?


Да, на форуме microchip.su некто клаccно отмахнулся.
Дескать нет таких примеров где абсолютно необходим мьютекс.
Как и нет таких примеров где нельзя без RTOS.

Да вот примеров где нельзя без RTOS навалом. Намедни я вон даже у ардуино RTOS обнаружил.

Статья на barrgroup.com в принципе правильная. И указывает однозначно, что необходимость в мьютексах возникает при наличии некой третьей мешающей задачи.
В сценарии SPI я не вижу третьей задачи которая вмешалась бы и нарушила работу планировщика на основе Rate Monotonic Algorithm (RMA)

Более того если задача обращается к разделяемому ресурсу я ее сразу же перестаю считать realtime задачей, а следовательно и принцип RMA на нее не распространяю.
Т.е. ей и мьютекс уже как бы не требуется.

Тут я вижу некое противоречие.

Вот скажите честно, вы применяете теорию RMA на практике? Оцениваете точно длительности выполнения всех задач? У вас все задачи всегда выполняются в строго отведенное известное время?
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jan 18 2015, 22:14
Сообщение #15


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(dimonomid @ Jan 18 2015, 19:31) *
Так что ничего особо сложного, если есть желание - главное начать! sm.gif


Есть обстоятельства, охлаждающие такое желание. Например, этой ночью появилась (точнее - была выложена на сайт) очередная версия FreeRTOS V8.2.0. По этому случаю я заглянула в список поддерживаемых ею МК и очень удивилась его широте. Вероятно, там не один человек работает, а целая компания.

Так вот я вижу в том списке среди многих прочих типов интересующие меня архитектуры МК (AVR и Cortex-R4F), которые в настоящий момент не поддерживает ни TNKernel, ни TNeo. А психика любого человека, как и психика разработчика, такова, что когда есть что-то готовое, и к тому же бесплатное, то очень трудно решиться на самостоятельные проекты, достигающие той же цели, но только другим путем. Опять же колеблешься, опасаясь возможных трудностей или возникающих проблем в процессе самостоятельного творчества, тогда как перед тобой уже находится готовый халявный вариант, который нахваливает целая толпа народа. sm.gif

В этой связи у меня к вам просьба похаять FreeRTOS, указав на присущие ей недостатки, но которые отсутствуют у TNKernel/TNeo. Т.е. что в принципе можно выиграть, если использовать TNeo вместо FreeRTOS? Полагаю, что даже в том случае, если бы я не задала вам этот вопрос, то его обязательно задал бы кто-то другой, т.к. конкуренция между различными RTOS/OS - типичное дело. Да и вы сами, надо полагать, имели в голове какие-то свои соображения, если в самом начале сделали ставку на TNKernel, даже в ее недоработанном виде. Тем более что здесь и без FreeRTOS других конкурентов полно, и всяк себя в захлеб хвалит.
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 Текстовая версия Сейчас: 6th July 2025 - 15:58
Рейтинг@Mail.ru


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