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

 
 
11 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> libopencm3, Неплохая либа для кортексов...
demiurg_spb
сообщение Mar 15 2013, 06:35
Сообщение #1


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

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



https://github.com/libopencm3/libopencm3

ИМХО хорошая альтернатива стандартной библиотеке от ST и не только.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zhevak
сообщение Mar 15 2013, 07:04
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(demiurg_spb @ Mar 15 2013, 12:35) *
https://github.com/libopencm3/libopencm3

ИМХО хорошая альтернатива стандартной библиотеки от ST и не только.

TNX!
Посмотрю потом, но все равно спасибо!


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Apr 3 2015, 08:06
Сообщение #3


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Тут есть пользователи этой библиотеки?

Первое впечатление - написано заметно приятнее, чем Cube/SPL. Можно читать и не плеваться каждые 15 секунд.
Склонность, правда, авторов к созданию своих велосипедов (почему бы не использовать родные определения регистров?..) несколько удивляет. Ну да ладно...

Собственно, у меня задача - сделать USB-Device.
Что-то как-то работает, однако мне сильно не нравится реализация USB без прерываний, опросом. Попытка запихать usbd_poll() в прерывание с разрешением такового пока к результатам не привела...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Apr 3 2015, 10:38
Сообщение #4


Ally
******

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



Цитата(demiurg_spb @ Mar 15 2013, 09:35) *
https://github.com/libopencm3/libopencm3

ИМХО хорошая альтернатива стандартной библиотеке от ST и не только.


Детская поделка.
А остальная половина файлов просто пустые.
Аккуратней надо быть с такими ссылками.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 3 2015, 13:24
Сообщение #5


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

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



Цитата(esaulenka @ Apr 3 2015, 11:06) *
Тут есть пользователи этой библиотеки?
Нет пользоваться не стал, т.к. у них тогда сильно менялись интерфейсы библиотеки.
Цитата
Первое впечатление - написано заметно приятнее, чем Cube/SPL. Можно читать и не плеваться каждые 15 секунд.
Склонность, правда, авторов к созданию своих велосипедов (почему бы не использовать родные определения регистров?..) несколько удивляет. Ну да ладно...
Абсолютно такое же впечатление и у меня осталось.

Цитата(AlexandrY @ Apr 3 2015, 13:38) *
Детская поделка.
А остальная половина файлов просто пустые.
Аккуратней надо быть с такими ссылками.
Не понял вашего юмора. Да эта либа пока не претендует на полноту. Да есть что пилить. Но уже сейчас глазу гораздо приятнее смотреть на неё нежели на творения ST (SPL).


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
klen
сообщение Apr 4 2015, 07:36
Сообщение #6


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



голосую за libcm3
Spl еще както было похоже на чтото , со скидкой что первый раз в первый класс.... но куб извините это говнокод. перевожу все проекты на куб а в результате поцесса получается что перевожу на регистры... при попытке воткнуть FreeRTOS обнаружил что куб использует системный таймер - пришлось перекостыливать куб, куда не плюнеш -ПЕРЕКОСТЫЛИВАТЬ.... а че они творят в яко бы дефолтных обработчиках прерываний... за каждый if else не по делу растреливать нада. куб это либа для школоты. единственное что понравилост - включение выключение переферии, макрос через регисты rcc

да libcm3 не полная, но... лучше я в этот проект комитить буду то чо недоделано
вобщем каждому по вкусу..
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 6 2015, 14:49
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(esaulenka @ Apr 3 2015, 11:06) *
Собственно, у меня задача - сделать USB-Device.
Что-то как-то работает, однако мне сильно не нравится реализация USB без прерываний, опросом. Попытка запихать usbd_poll() в прерывание с разрешением такового пока к результатам не привела...

у меня та же задача, msc. но поллинг пока устраивает.
уже моск выкипел, определяется стабильно с 3 раза, это секунд 40, затыкается на отдаче scsi готов/неготов... хз как его отловить.

Цитата(demiurg_spb @ Apr 3 2015, 16:24) *
Не понял вашего юмора. Да эта либа пока не претендует на полноту. Да есть что пилить. Но уже сейчас глазу гораздо приятнее смотреть на неё нежели на творения ST (SPL).

че там за полнота дожна быть? f3 f4 и хватит. в мелких вообще неясно нахрена эти обертки.

Цитата(klen @ Apr 4 2015, 10:36) *
голосую за libcm3

да libcm3 не полная, но... лучше я в этот проект комитить буду то чо недоделано
вобщем каждому по вкусу..

+100500
там тоже иногда аццки хочется показать, шо так не делают, но в целом нормально.
Только мне непонятно, чего они автогенерированные части, которые инклюдятся, с расширением *.c оставили - это ж бардак..надо каждый файлик перебирать и смотреть что включать в проект а что нет.
Цитата
куда не плюнеш -ПЕРЕКОСТЫЛИВАТЬ

меняю клок инит через куб на регистры - минимум 2 кб кода уходит. Мама миа!

Сообщение отредактировал _Pasha - Apr 6 2015, 14:51
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Apr 7 2015, 10:45
Сообщение #8


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(_Pasha @ Apr 6 2015, 17:49) *
у меня та же задача, msc. но поллинг пока устраивает.
уже моск выкипел, определяется стабильно с 3 раза


Определяется стабильно.
Прерывание тоже нормально работает вот с таким нехитрым кодом:
Код
extern "C"
void OTG_FS_IRQHandler (void)
{
    usbd_poll(usbd_dev);
}

Почему не взлетело сразу, я так и не понял...

Сейчас борюсь с граблей - некорректно работает прием по control endpoint.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
kan35
сообщение Apr 12 2015, 15:50
Сообщение #9


Знающий
****

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



Цитата(klen @ Apr 4 2015, 10:36) *
голосую за libcm3
Spl еще както было похоже на чтото , со скидкой что первый раз в первый класс.... но куб извините это говнокод. перевожу все проекты на куб а в результате поцесса получается что перевожу на регистры... при попытке воткнуть FreeRTOS обнаружил что куб использует системный таймер - пришлось перекостыливать куб, куда не плюнеш -ПЕРЕКОСТЫЛИВАТЬ.... а че они творят в яко бы дефолтных обработчиках прерываний... за каждый if else не по делу растреливать нада. куб это либа для школоты. единственное что понравилост - включение выключение переферии, макрос через регисты rcc

да libcm3 не полная, но... лучше я в этот проект комитить буду то чо недоделано
вобщем каждому по вкусу..

Запускаю свой первый проект на HAL через CubeMX, не соглашусь, что это говнокод. Косяков, конечно, еще довольно много, но в целом все это собирается более менее небольшими усилиями и с FreeRTOS состыкуется хорошо, прерывания с обработкой всех флагов - if else меня не сильно напугали, понятно, что за универсальность приходится платить. На SPL код был оптимальнее, на какую то долю % быстрее и на какие то единицы % копактнее, но делал я его на порядок дольше, а памяти и мегагерцев и так некуда девать.
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 12 2015, 17:17
Сообщение #10


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(kan35 @ Apr 12 2015, 18:50) *
Запускаю свой первый проект на HAL через CubeMX, не соглашусь, что это говнокод. Косяков, конечно, еще довольно много, но в целом все это собирается более менее небольшими усилиями и с FreeRTOS состыкуется хорошо, прерывания с обработкой всех флагов - if else меня не сильно напугали, понятно, что за универсальность приходится платить. На SPL код был оптимальнее, на какую то долю % быстрее и на какие то единицы % копактнее, но делал я его на порядок дольше, а памяти и мегагерцев и так некуда девать.

В этом HALе куда ни плюнь while (какой-то бит); то есть затачивать реально подо РТОС они это будут ещё как минимум очень долго.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 13 2015, 06:45
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А какая связь наличие или отсутствия while (бит) и долготы затачивания под РТОС?

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

Но это мои рассуждения, а что вы хотели сказать? я без стеба, мне интересно.
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 13 2015, 07:27
Сообщение #12


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(Golikov A. @ Apr 13 2015, 09:45) *
А какая связь наличие или отсутствия while (бит) и долготы затачивания под РТОС?

Под Винду вы тоже пишете с while (bit) ?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 13 2015, 09:28
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



строго говоря я не под что не пишу while(условие). У меня все ожидания с таймаутами.

Но пока я все равно не понял. Хотите сказать что при while(bit) не будет переключаться задачи?
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 13 2015, 09:44
Сообщение #14


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(Golikov A. @ Apr 13 2015, 12:28) *
строго говоря я не под что не пишу while(условие). У меня все ожидания с таймаутами.

Но пока я все равно не понял. Хотите сказать что при while(bit) не будет переключаться задачи?

Я хотел сказать ровно то, что сказал. Считать такой стиль годным для РТОС так же странно, как и годным для Винды. Если никто не пишет так даже под Винду, то странно писать так подо РТОС.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Apr 13 2015, 09:52
Сообщение #15


Ally
******

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



Цитата(Golikov A. @ Apr 13 2015, 12:28) *
строго говоря я не под что не пишу while(условие). У меня все ожидания с таймаутами.

Но пока я все равно не понял. Хотите сказать что при while(bit) не будет переключаться задачи?


Да, не будут.
Но к вашему случаю с двумя задачами это не относится.

Реальная проблема возникнет когда будет несколько десятков задач и вы перестанете всех их помнить. Хотя думаю и семи хватит.
Тогда while приведут к полному краху всей системы приоритезации.
Скажем во всех задачах есть диагностика. Она пишет лог. А тот лог в свою очередь пишет в файл. А в драйвере файловой системы стоит while да хоть и с таймаутом.
И все, кранты вашей риалтаймности.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 13 2015, 09:56
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



понятно, спасибо...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 13 2015, 10:00
Сообщение #17


Гуру
******

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



Вы знаете, но честно говоря меня напрягают оценки результатов труда одного программиста, другим. Прога это такая субъективная вещь ...
Я правда тоже тут с одним образчиком творчества работаю .... Тоже разговариваю одними междометиями и нецензурными словами, но всё же ...
Можно понять и тех кто делал тот же stdlib или куб. Когда я последний проект начинал был только stdlib - посмотрел, что он для меня обладает избыточной функциональностью. И отказался от него.
Особенно меня напрягла работа с портами. Для инициализации порта требуется ввести три енума потом три массива и работать через процедуры. Короче на первый взгляд значительный и неоправданный оверхед. Особенно в сравнении с тем как я привык писать. Но когда потом смотрел некоторые части понимаешь смысл написанного. Так как у меня написано - не стандартизуешь. Мы разные цели ставим перед собой. Они изначально закладывают избыточность и пишут библиотеки, чтобы максимально перекрыть все возможные применения. А я строю реальное приложение, устраняю избыточность, нацелен на локальное использование.
В общем объёме приложения - объём драйверов у меня составляет единицы процентов. Учитывая что я их пишу в 2 - 3 уровня, то получается драйвера камнезависимые вообще копейки. Поэтому я могу себе позволить их написать. Хоть каждый раз. А стандартными воспользоваться как примером в каких то случаях.
Это общие моменты, а конкретно ... Я вижу что куб был рассчитан на применение в составе ОСи. Причём обкатывался с разными. Приведу пример.
Я использовал драйвер Ethernet из куба. Поскольку у меня не было заведено прерывания на обрыв линии, как это реализовано в кубе, то мне пришлось это сделать опросом в другой задаче...
Я посмотрел их код и вижу например heth->State ...
Это для чего написано? Для разруливания работы с устройством из под разных задач. И некоторые другие вещи.
И как результат подключение не вызвало никаких проблем. У меня всё заработало устойчиво.
Наверняка там тоже есть что оптимизировать. Так этим никто не запрещает заниматься.
Даже механизм блокировки вы можете привести в соответствие с применяемой осью.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 13 2015, 11:10
Сообщение #18


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(SasaVitebsk @ Apr 13 2015, 13:00) *
Особенно меня напрягла работа с портами. Для инициализации порта требуется ввести три енума потом три массива и работать через процедуры. Короче на первый взгляд значительный и неоправданный оверхед.


Мне вот тоже не всегда понятна логика программеров на разных процах при работе с портами. Вот сам пишу процедуры таким образом:
Настройка порта на вывод, с параметрами ножки(там 0 или 1) на ввод(пуллап, даун, 3е сост.) и процедуры опроса линии, BitIsSet() BitIsClear()
Вот что еще надо для работы с ними? А как ни посмотришь, в творения от СТ, фрискала и пр ... жуть какая-то crying.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 14 2015, 11:16
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А вот теперь я задумался, а как с учетом заточености под RTOS правильно делать передачу данных, допустим по SPI в режиме мастера, допустим с какой-нибудь FRAM? Ведь там есть послать данные, подождать бита готовности памяти и принять их. Как бита ждать?

Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 14 2015, 14:21
Сообщение #20


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

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



Тут всё просто. Если ждать долго, то надо на окончение ожидания настраивать прерывание, и ждать флага. Если недолго, то ждать, опрашивая в цикле.
В частности, FRAM работает быстро, поэтому есть вероятность, что от попыток переноса ожидания в прерывания будут только дополнительные тормоза.
Естественно, ожидание в цикле опроса желательно производить в менее приоритетной задаче, чтобы более важные задачи могли этот цикл прервать.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 14 2015, 14:35
Сообщение #21


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(AHTOXA @ Apr 14 2015, 17:21) *
Если ждать долго, то надо на окончение ожидания настраивать прерывание, и ждать флага.

Кто вам создаст это прерывание? А "флаг" как ждать? Чем его ожидание отличается от ожидания бита?

Цитата(AHTOXA @ Apr 14 2015, 17:21) *
Если недолго, то ждать, опрашивая в цикле.

Это ничего в принципе не меняет. Просто вечный while переходит из HALа в вашу программу.
Можно сделать while (нет бита) шедьюлинг();
правда тогда период опроса будет много миллисекунд, что может быть долго.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 14 2015, 14:51
Сообщение #22


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Golikov A. @ Apr 14 2015, 14:16) *
А вот теперь я задумался, а как с учетом заточености под RTOS правильно делать передачу данных, допустим по SPI в режиме мастера, допустим с какой-нибудь FRAM? Ведь там есть послать данные, подождать бита готовности памяти и принять их. Как бита ждать?


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

Сообщение отредактировал mantech - Apr 14 2015, 14:52
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 14 2015, 17:01
Сообщение #23


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

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



Цитата(Dr.Alex @ Apr 14 2015, 19:35) *
Кто вам создаст это прерывание? А "флаг" как ждать? Чем его ожидание отличается от ожидания бита?

Прерывание мне никто не создаст, придётся самому :-)
Под флагом я имел в виду какой-нибудь объект синхронизации операционной системы (event, mutex). Соответственно, ожидание такого флага -- усыпляет ожидающий процесс.
Цитата(Dr.Alex @ Apr 14 2015, 19:35) *
Это ничего в принципе не меняет. Просто вечный while переходит из HALа в вашу программу.
Можно сделать while (нет бита) шедьюлинг();

Ну зачем же вечный? Можно с тайм-аутом. Мысль моя была о том, что если период ожидания бита ожидается короткий (например, гарантирован в даташите на FRAM), то такое ожидание ничем не отличается от просто небольшого цикла по ходу выполнения. Поэтому принимать специальные меры для перевода процесса в сон на время этого ожидания вряд ли целесообразно. Например, я не усыпляю процессор на время передачи пары байт по SPI. А вот на время передачи блока из 512 байт в SD-карту - уже усыпляю, ибо уже успею за это время сделать что-нибудь ещё полезное.
ЗЫ. В вытесняющей оси "while (нет бита) шедьюлинг();" ничего не даст, потому что вернёт управление тому же самому процессу. Лучше тогда while (нет бита) sleep(1);


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 14 2015, 17:04
Сообщение #24


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(AHTOXA @ Apr 14 2015, 20:01) *
Ну зачем же вечный? Можно с тайм-аутом.

С тайм-аутом или без не важно, всё равно это "вечный цикл" с точки зрения операционки.

Цитата(AHTOXA @ Apr 14 2015, 20:01) *
ЗЫ. В вытесняющей оси "while (нет бита) шедьюлинг();" ничего не даст, потому что вернёт управление тому же самому процессу. Лучше тогда while (нет бита) sleep(1);

Осёвый "sleep" это и есть функция, вызывающая шедьюлинг..
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 14 2015, 17:59
Сообщение #25


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

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



Цитата(Dr.Alex @ Apr 14 2015, 22:04) *
С тайм-аутом или без не важно, всё равно это "вечный цикл" с точки зрения операционки.

Нет. С тайм-аутом цикл не вечный. Это просто несколько шагов выполнения алгоритма. То, что они оформлены в цикл - ничего не меняет. Так можно договориться до того, что и вычисление математических функций тоже придётся признать "вечным циклом", неприменимым в программировании с ОС. А что, какой-нибудь atan2() - вон как долго вычисляется! Значительно дольше, чем я буду ожидать флага опустошения передатчика SPI перед отправкой туда символа.
Цитата(Dr.Alex @ Apr 14 2015, 22:04) *
Осёвый "sleep" это и есть функция, вызывающая шедьюлинг..

Нет. Осёвый "sleep" не просто вызывает шедулинг, он ещё перед этим переводит текущий процесс в состояние ожидания.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 14 2015, 18:16
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

это плохой ответ, не о чем...

Цитата
А вот на время передачи блока из 512 байт в SD-карту - уже усыпляю,

Имеется ввиду, запускаем ДМА, а задачу в sleep, то есть ОС будет к ней возвращаться с каким то своим достаточно большим интервалом, так?

Подытожим, у нас есть варианты:
1. усыпление процесса и возврат к нему с долгими интервалами для проверки дождались или нет (ожидание чего-то очень долгого)
2. это прерывание на окончание ожидания и в нем какой-то симафор, что позволяет ожидающую задачу усыпить до появления симафора. (если надо подождать среднюю длительность)
3. это долбим проверку интервала прямо в задаче циклом. В некоторых ОС будут переключать задачи по временным интервалам, если ожидание затянется, а в некоторых все задачи будут ждать эту. (ожидаем чего-то очень короткого)

правильные варианты?

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

Не понятно как это решить в универсальной библиотеке
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Apr 14 2015, 18:40
Сообщение #27


Ally
******

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



Цитата(Golikov A. @ Apr 14 2015, 21:16) *
Мне как-то внутренне кажется устраивать заопарк прерываний в ОС не верно.


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

Нельзя надеятся, что RTOS облегчит написание низкоуровневых драйверов.
Наоборот она их усложняет.

Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний.
Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA.
Сами прерывания это прерывания уровня ядра.
Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 15 2015, 03:04
Сообщение #28


Гуру
******

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



Цитата(AlexandrY @ Apr 15 2015, 00:40) *
Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний.
Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA.

Иногда (при необходимости быстрой работы со сложной периферией) получаются очень сложные автоматы состояний со множеством состояний (десятками) и сложными переходами между ними.
Код становится трудночитаем, ведь программирование в стиле автоматов состояний гораздо хуже читается чем линейный код.
В таких случаях я иногда применяю подход "а-ля ISR-псевдозадача":
создаю отдельный контекст (стек), при завершении очередной транзакции с периферией (получении прерывания от неё, от DMA или от таймера), внутри ISR переключаюсь на этот контекст, выполняю
участок кода до след. запроса к периферии (после которого следует обратное переключение контекста на исходный стек ISR с выходом из ISR). И по завершении этого запроса - опять вход в
ISR-псевдозадачу.
Получается простой хорошо читаемый линейный код вместо леса автомата состояний.
Надо только не забывать про уровни приоритетов ISR, участвующих в этом (на NVIC). Можно просто сделать все одного уровня.

Цитата(AlexandrY @ Apr 15 2015, 00:40) *
Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных.

О готовности данных, или освобождении какого-то ресурса (занятого буфера или флага в API доступа к драйверу, работающему на уровне прерываний) и т.п..
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 15 2015, 03:59
Сообщение #29


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

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



Цитата(Golikov A. @ Apr 14 2015, 23:16) *
Имеется ввиду, запускаем ДМА, а задачу в sleep, то есть ОС будет к ней возвращаться с каким то своим достаточно большим интервалом, так?

Не в sleep, а в wait(). В ожидание объекта синхронизации (event, mutex, ...). А объект синхронизации взводится в прерывании по окончании передачи. В этом случае ОС не будет возвращаться к ожидающей задаче с каким-бы то ни было интервалом - задача будет спать чётко до момента окончания передачи. И затем практически сразу проснётся.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Apr 15 2015, 04:46
Сообщение #30


Ally
******

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



Цитата(jcxz @ Apr 15 2015, 06:04) *
Иногда (при необходимости быстрой работы со сложной периферией) получаются очень сложные автоматы состояний со множеством состояний (десятками) и сложными переходами между ними.
Код становится трудночитаем, ведь программирование в стиле автоматов состояний гораздо хуже читается чем линейный код.
В таких случаях я иногда применяю подход "а-ля ISR-псевдозадача":
создаю отдельный контекст (стек), при завершении очередной транзакции с периферией (получении прерывания от неё, от DMA или от таймера), внутри ISR переключаюсь на этот контекст, выполняю
участок кода до след. запроса к периферии (после которого следует обратное переключение контекста на исходный стек ISR с выходом из ISR). И по завершении этого запроса - опять вход в
ISR-псевдозадачу.
Получается простой хорошо читаемый линейный код вместо леса автомата состояний.
Надо только не забывать про уровни приоритетов ISR, участвующих в этом (на NVIC). Можно просто сделать все одного уровня.


О готовности данных, или освобождении какого-то ресурса (занятого буфера или флага в API доступа к драйверу, работающему на уровне прерываний) и т.п..


В принципе не возражаю, только вот это - "хорошо читаемый" напрягает. Субъективизм же.
Во первых в скоростной периферии важнее хорошая отлаживаемость
Во вторых хорошо читаемый только короткий код.
Расположите все ISR связанные с одним автоматом в одном месте и получите короткий код, понятно откоментируйте и отформатируйте и получите отличную читаемость.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 15 2015, 05:02
Сообщение #31


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(AlexandrY @ Apr 14 2015, 21:40) *
Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний.
Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA.
Сами прерывания это прерывания уровня ядра.
Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных.


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

Сообщение отредактировал mantech - Apr 15 2015, 05:05
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 15 2015, 05:12
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



"не о чем" - было о другом...

конкретный пример SPI обмен:
опустить CS
послать запрос - 6 байт
дождаться ответа (ножки ОК, Есть данные, Ошибка) или таймаут
в случае наличия данных принять их - 4 байта
поднять CS

Хорошо звучит написать драйвер, без блокировок, без ожиданий циклами и так далее...
А на деле что?
Прерывания принят - отправлен байт по SPI - нет, единственный способ это проверять флаг что передатчик закончил. ДМА настраивать на обмен 6 байтами - глупо, а 2 ДМА для приема 4 еще глупее. Если нет FIFO как в STM все байты сразу не запихаешь. Растянуть цикл обмена на несколько миллисекунд - глупо.

Вот и получается что "надо драйвер написать чтобы все в прерывании делал и не тормозил" - не о чем...
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Apr 15 2015, 05:47
Сообщение #33


Ally
******

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



Цитата(Golikov A. @ Apr 15 2015, 08:12) *
ДМА настраивать на обмен 6 байтами - глупо, а 2 ДМА для приема 4 еще глупее.


Да, если недальновидно выбран микроконтроллер.

Я например сразу планирую сколько скоростных последовательных каналов будет в системе и прикидываю сколько каналов DMA понадобится.

Чем больше каналов DMA тем лучше чип заточен под RTOS.

Лучше всего здесь дела обстоять у Kinetis (32 канала), похуже у STM32F4 (16 каналов), еще хуже у LPC17xx (8 каналов)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 15 2015, 06:55
Сообщение #34


Гуру
******

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



Цитата(AlexandrY @ Apr 15 2015, 10:46) *
В принципе не возражаю, только вот это - "хорошо читаемый" напрягает. Субъективизм же.
Во первых в скоростной периферии важнее хорошая отлаживаемость
Во вторых хорошо читаемый только короткий код.
Расположите все ISR связанные с одним автоматом в одном месте и получите короткий код, понятно откоментируйте и отформатируйте и получите отличную читаемость.

Вот такая работа с SPI (вполне хорошо читаемая и короткая при построении драйвера на уровне OS-задачи или как я описывал - псевдозадачей (выглядит так же как с OS)):
Код
FlashRead();
n = N_PAGES;
do FlashWrite();
while (--n);

при описывании state-машиной превращается в дикий лес, из нескольких десятков шагов с вермишельной логикой ветвлений:
(учтите что здесь ещё надо расписать шаги внутри FlashRead()/FlashWrite(), с реализацией стека вызовов (стека state-переменных))
Код
while (1) {
  switch (state) {
    case STATE_0:
      StartActionRead(...);
      state = STATE_1;
      break;
    case STATE_1:
      n = N_PAGES;
    case STATE_2:
      StartActionWrite(...);
      state = STATE_3;
      break;
    case STATE_3:
      state = STATE_ERROR;
      if (!result) continue;
      state = STATE_2;
      if (--n) continue;
     ...
    case STATE_ERROR:
     ...
  ...
  }
break;
}

Особенно если учесть, что надо реализовать цикл(циклы), что внутри FlashWrite(), FlashRead() может быть несколько транзакций по SPI-шине с несколькими входами в ISR, могут быть циклы с проверкой условий и т.п.). Вообще если нужно сделать простейшую функцию (набор часто повторяемых действий) на базе state-машины.
Если взять любой код драйвера, работающий на базе задачи ОС с использованием её объектов синхронизации (для уведомления о завершениях транзакций от ISR), и попытаться его развернуть в
state-машину, то сразу видно какой получается малочитаемый код.

State-машиной ещё вполне нормально реализуются простые линейные последовательности шагов алгоритма, без ветвлений и вызовов функций. Не более того.
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 15 2015, 07:29
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Apr 15 2015, 09:55) *
при описывании state-машиной превращается в дикий лес

Для этого существует protothreads. Никакого дикого леса.
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 15 2015, 07:37
Сообщение #36


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(AlexandrY @ Apr 15 2015, 08:47) *
Лучше всего здесь дела обстоять у Kinetis (32 канала), похуже у STM32F4 (16 каналов), еще хуже у LPC17xx (8 каналов)

Тут дело даже не в "канальности".
У STM32F4 например к каждому каналу (точнее, стриму) привязано до 8 определённых источников/приёмников данных.
Поэтому если вы хотите использовать ДМА для 2-3-4 источников, привязанных к одному стриму, то вас может ждать облом.
Точнее, облом был бы неминуем, но один и тот же источних часто (но не всегда) привязан к двум стримам (а в целом они распределены хаотично), но всё же облом вероятен (я — уже). Нет и речи о том чтобы использовать хотя бы половину стримов.

А к примеру в "тупике эволюции" блэкфине каналы ДМА не привязаны к конкретной периферии.
При этом забавно, что там каналов чуть ли не больше чем источников данных :-)))
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 15 2015, 07:44
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



еще матрица шин, а потом доступ проца и каналы кроют друг друга, и к шине не достучишься...
ДМА - хорошо, но все же использовать надо с осторожностью.

Опять же иногда ДМА настроить дольше чем перепихать данные... LPC кстати имеет фифо - что здорово облегчает иногда дело, но все равно проблемы имеются...
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 15 2015, 08:42
Сообщение #38


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Golikov A. @ Apr 15 2015, 08:12) *
Вот и получается что "надо драйвер написать чтобы все в прерывании делал и не тормозил" - не о чем...


Ну вот зачем такие голословные утверждения?

Пример уарта делал, нужно передавать и принимать пакеты разной длины, делаю первое - в процедуре "инит" анализируется размер пакета на передачу, если пакет большой - запускаю ДМА, маленький, просто задаю глобальный счетчик, запускаю передачу - если ДМА, ждем флаг окончания, если счетчик, по прерыванию уарта уменьшаем и так до нуля, если событие передачи состоялось - генерю софт инт.

Прием - запускаю дма и счетчик таймаута, жду событий и генерю софтинт, что сложного? И не надо ждать в циклах и ступорить ось. Все работает по прерываниям в режиме полного автомата.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 15 2015, 09:07
Сообщение #39


Гуру
******

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



Цитата(Dr.Alex @ Apr 15 2015, 13:37) *
Поэтому если вы хотите использовать ДМА для 2-3-4 источников, привязанных к одному стриму, то вас может ждать облом.
Точнее, облом был бы неминуем, но один и тот же источних часто (но не всегда) привязан к двум стримам (а в целом они распределены хаотично), но всё же облом вероятен (я — уже). Нет и речи о том чтобы использовать хотя бы половину стримов.

Это одна из главных причин из-за которой недавно, при выборе МК для новой железки, мы отказались от STM32F4. Очень убого реализована периферия в нём - ни буферизации (FIFO) ни достаточного числа DMA-каналов для решения проблемы без FIFO. sad.gif

Цитата(Golikov A. @ Apr 15 2015, 13:44) *
Опять же иногда ДМА настроить дольше чем перепихать данные... LPC кстати имеет фифо - что здорово облегчает иногда дело, но все равно проблемы имеются...

LPC, Tiva имеют нормальные FIFO (UARTы, SPI, etc). STM32 экономит на пуговицах непонятно зачем, значительно ухудшая характеристики МК.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 15 2015, 09:47
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Прием - запускаю дма и счетчик таймаута, жду событий и генерю софтинт, что сложного?

ничего сложного нет, особенно если для примера взят интерфейс который сам работает...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 15 2015, 09:59
Сообщение #41


Гуру
******

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



Когда у человека появляется красивый инструмент, возникает непреодолимое желание его использовать. Иногда вопреки здравому смыслу. И старый тут же объявляется вне закона.
Смотрю различные драйвера обработки SPI - просто убивает. Порой визуально видно, что будет менее эффективно чем простой while.
При частоте проца 168МГц и работе SPI 22, байт вылетает за 61 такт. Обработчик прерывания на SPI это не 2 строки. Плюс вход/ выход. В чём прелесть?
Применение DMA порой ещё более натянуто. Я попробовал реализовать работу с флэшкой at45db. Правда у меня там разные режимы включая потоковую запись через разные буфера. Применение DMA существенно усложняет драйвер. Оценить выигрыш в производительности не представляется возможным. Оценить надёжность такой работы ... Да это надо целое исследование производить. При этом не надо забывать, что Ваше приложение не винда!!! Вам не нужно обеспечивать максимальную производительность. Вам надо обеспечить достаточную производительность. Как правило. Ну если не рассматривать вопросы потребления.
Применение автомата в некоторых случаях конечно оправдано и наиболее удобно.
А в целом нет универсального способа написания драйвера. Чего бы то ни было. Надо исходить из поставленной задачи.
Кидайте в меня палками, на SPI я применяю while. Не блокирующий. Кроме того у меня есть один поток на диагностику, где я пытаюсь контролировать в том числе зависание потока, а также анализирую зависание периферии. Там кстати автомат, так как я там всякие мелкие задачи в один поток собираю чтобы не плодить.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 15 2015, 10:29
Сообщение #42


Гуру
******

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



Цитата(SasaVitebsk @ Apr 15 2015, 15:59) *
Смотрю различные драйвера обработки SPI - просто убивает. Порой визуально видно, что будет менее эффективно чем простой while.
При частоте проца 168МГц и работе SPI 22, байт вылетает за 61 такт. Обработчик прерывания на SPI это не 2 строки. Плюс вход/ выход. В чём прелесть?

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

Цитата(SasaVitebsk @ Apr 15 2015, 15:59) *
Применение DMA существенно усложняет драйвер. Оценить выигрыш в производительности не представляется возможным. Оценить надёжность такой работы ... Да это надо целое исследование производить.

Ошибаетесь. Всего ПЛЮС несколько дополнительных строк на инициализацию, и МИНУС некоторое кол-во строк на цикл опроса состояний/программной пересылки и т.п.
В простых случаях по коду одинаково, но несравнимо быстрее с DMA.

Цитата(SasaVitebsk @ Apr 15 2015, 15:59) *
Кидайте в меня палками, на SPI я применяю while. Не блокирующий. Кроме того у меня есть один поток на диагностику, где я пытаюсь контролировать в том числе зависание потока, а также анализирую зависание периферии. Там кстати автомат, так как я там всякие мелкие задачи в один поток собираю чтобы не плодить.

Ваш while убъёт все нижележащие по приоритету задачи. Особенно если там надо не один-два байта переслать.
Для многозадачной среды - это зло.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 15 2015, 17:41
Сообщение #43


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Apr 15 2015, 12:07) *
Это одна из главных причин из-за которой недавно, при выборе МК для новой железки, мы отказались от STM32F4. Очень убого реализована периферия в нём - ни буферизации (FIFO) ни достаточного числа DMA-каналов для решения проблемы без FIFO.


Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще...
Вот никогда эти фифо не использовал, муторно с ними, работал с 5 уартами и 2 спи одновременно, по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис. Никаких проблем не испытывал, либо, принимал по прерываниям, либо дма, для больших пакетов.

Тут, по моему, искусственно создают бурю в стакане воды...
Go to the top of the page
 
+Quote Post
den_po
сообщение Apr 15 2015, 19:06
Сообщение #44


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(mantech @ Apr 15 2015, 22:41) *
Вот никогда эти фифо не использовал, муторно с ними

Да нет же, практически то же самое, что и без фифо, только в обработчиках прерываний не по одному байту бросается, а сколько влезло
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение Apr 15 2015, 19:08
Сообщение #45


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

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(mantech @ Apr 15 2015, 20:41) *
Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще...

Достаточно неудачно выбрать 3-4 периферийных блока чтобы стримы ДМА пересеклись.
А для ЦОС - да, уже пытаюсь использовать.

Цитата(mantech @ Apr 15 2015, 20:41) *
по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис.

Для ПЛИС 100 МБпс это ничто. Отличный способ сделать совершенно неоптимальное устройство.
Можно мне показать такой "коммуникационный процессор"? Чтобы 1-2МБ флеши, 256КБ срамы, корпус 10х10х0.6?
Задача ещё и в том чтобы обрабатывать эти потоки на минимальной частоте ядра. Для моей текущей задачи разница в потреблении на частоте 168 и 84 очень существенна. Надеюсь вообще уложиться в 42.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 16 2015, 02:16
Сообщение #46


Гуру
******

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



Цитата(mantech @ Apr 15 2015, 23:41) *
Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще...
Вот никогда эти фифо не использовал, муторно с ними, работал с 5 уартами и 2 спи одновременно, по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис.

Не для ЦОС (хотя и она там возможно в каком-то количестве будет чуть позже), но в устройстве нужно 5-6 UART (одновременно работающих и при этом желательно - не перегружающих систему прерываниями в десятки кГц) + 2 одновременно работающих SPI (20-40МГц). Это как минимум то, что в STM32 придётся делать с DMA. В старых устройствах на LPC17x примерно то же самое работает занимая всего 4 DMA-канала (2 SPI), а UART-ы без DMA нормально работают, так как имеют FIFO. Да и SPI-каналы имеют FIFO, так что, как я понимаю, меньше занимают шину блочными пересылками.
А в новом устройстве планируется более интенсивный поток по SPI-каналам (к тому-же - реалтаймовый). По этой причине в основном и отказались от STM32.
Как тут уже написали - работать с FIFO - то же самое что и без, практически никакой разницы, только частота обслуживания может быть в 16 раз меньше.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 16 2015, 04:59
Сообщение #47


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Apr 16 2015, 05:16) *
Как тут уже написали - работать с FIFO - то же самое что и без, практически никакой разницы, только частота обслуживания может быть в 16 раз меньше.


Это только в "тепличных" условиях. В моем случае была поддержка протоколов с пакетами разной длины от 6 до 1000 байт, причем длина указывается в первых байтах, без таймаутов, там же и ИД-пакета, которые нужно парсить "на лету", тут все фифы только вредят, и работа уартов на 115200 не сильно замедляет систему, если конечно, не нагружать прерывания чем-то еще, кроме приема...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 16 2015, 05:05
Сообщение #48


Гуру
******

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



Цитата(jcxz @ Apr 15 2015, 13:29) *
Прелесть в том, что по SPI обычно не по одному байту пересылают, а десятки и сотни за транзакцию.

У меня по SPI 2 устройства: at45db и АЦП.
1. Во втором случае надо передавать 2 байта и получать 4.
2. В случае работы с флэшкой то же не всё шикарно. Если не выравнивать флэшку на границу страницы, то надо выполнять кучу работы. Грузить страницу, заполнять, записывать. Для всего этого требуется разные команды. У меня идёт в основном запись архивов и ошибок. Как правило требуется забота с малыми объёмами данных.
Я прикидывал, вариант драйвера с DMA. Для меня это очень значительное усложнение.

Плюс поясните мне пожалуйста. Вот я записываю информацию во флэшку. Потом мне надо ждать готовности флэшки. Как это обойти с помощью DMA?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 16 2015, 07:02
Сообщение #49


Гуру
******

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



Цитата(mantech @ Apr 16 2015, 10:59) *
Это только в "тепличных" условиях. В моем случае была поддержка протоколов с пакетами разной длины от 6 до 1000 байт, причем длина указывается в первых байтах, без таймаутов, там же и ИД-пакета, которые нужно парсить "на лету", тут все фифы только вредят, и работа уартов на 115200 не сильно замедляет систему, если конечно, не нагружать прерывания чем-то еще, кроме приема...

Ну да... 11520*6UART*2(TX/RX) итого частота прерываний ==138240Гц, т.е. - прерывания с периодом 7.2мкс конечно не нагружают никак систему wink.gif
Про случай когда надо работать всего с одним UART-ом - тут нет вопросов.
А ведь бывают ещё и бОльшие скорости по UART.
У нас тоже по всем UART-каналам идёт обмен по протоколам с размером кадров переменной длины. FIFO не мешает этому никак.

Цитата(SasaVitebsk @ Apr 16 2015, 11:05) *
Плюс поясните мне пожалуйста. Вот я записываю информацию во флэшку. Потом мне надо ждать готовности флэшки. Как это обойти с помощью DMA?

Когда нужно всего пару байт - никто не мешает использовать обмен по прерываниям: записать в FIFO сразу все 1...8 слов, а потом получить 1..N прерываний и вычитать.
Можно комбинировать (я так делаю при малых размерах транзакции по SPI, полностью влезающей в размер FIFO): настраиваю DMA только на приёмный канал, записываю в TX.FIFO сразу все байты (программно), а потом по окончании приёма всего пакета получаю ОДНО прерывание завершения DMA (без ожидания таймаута по завершению).
Готовность AT45DB никак не надо обходить. Считывать регистр состояния согласно документации. Хоть программно, хоть с DMA.
Никто не мешает смешивать работу через DMA с программным обменом, хоть одновременно, хоть поочередно.
В зависимости от SCLK и её соотношения с частотой CPU, можно хоть программно записать в SPI необходимую команду чтения статуса и ждать поллингом завершения приёма
(допустимо при большой SCLK, когда такое ожидание приёма занимает мало тактов и выигрыш от освобождения процессора на время передачи невелик или нету его),
хоть записать программно, настроив DMA на приём ответа и генерацию прерывания по завершению (если SCLK много меньше частоты CPU и если ждать поллингом, то
надолго займёшь CPU впустую).
На МК без FIFO всё гораздо хуже, так как нельзя записать целиком посылку в FIFO, настроив только RX.DMA.

Мы много используем AT45DB. Передача данных в драйверах идёт через DMA, опрос состояния - как я описал (у нас SCLK=25...30МГц).
Под рукой сейчас нет исходника с AT45DB, но вот подобная операция с nRF24L01+ (чтение регистра nRF24L01+ - короткая SPI-транзакция):
CODE
static void ActSSP(int cmd, int len, int stepNew)
{
Pclr(PIN_NRF_CS); //CS=low
isrStep = stepNew;
volatile HwRegsSSP *ssp = &concatAB(SSP, nSSP_nrf);
HwRegsDMA::T_CH volatile *ch = &DMA.CH[DMA_CH_nrf_RX];
//DMA-канал DMA_CH_nrf_RX статически привязан к данному SPI (nSSP_nrf), так что адрес источника (ch->SRC) и ch->LLI устанавливаются в инит-коде и каждый раз их писать не надо.
//Всё программирование DMA для запуска транзакции занимает 3 строчки кода ниже, настройка регистров: ch->DST, ch->CTL и старт RX.DMA: ch->CFG.
ch->DST = &sh.regIO.status;
ch->CTL = len + sizeof(sh.regIO.status) | 1 << 12 | B27 | B31;
ch->CFG = B0 | (DMA_REQ_nrf_RX >> 4) << 1 | 2 << 11 | B14 | B15;
ssp->CR[1] = B1; //включаем SPI-канал
__DMB();
ssp->DR = cmd; //старт передачи (и приёма)
}

static uint RegRead(REG reg)
{
ActSSP((int)reg + CMD_R_REGISTER, 1, IS_GAP);
concatAB(SSP, nSSP_nrf).DR = 0; //запись хвоста (для приёма значения регистра)
NrfCtxSw(); //переключение контекста в фоновую задачу с ожиданием завершающего DMA-IRQ, который делает CS=high
return sh.regIO.val[0];
}

Код
#define concatAB_(a, b) a##b
#define concatAB(a, b) concatAB_(a, b)


Это код для LPC17xx.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 16 2015, 07:26
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
которые нужно парсить "на лету", тут все фифы только вредят,

Это не верно!
Они вредят только в одном случае, при неожиданном разрыве обмена их надо очищать от старых пакетов... И в LPC для уарта они сделали очистку, а для SSP нет, приходиться 8 слов читать чтобы точно передатчик был пусть, в случае слейва это ложиться на внешнее устройство...

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

FIFO - благо

Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 16 2015, 09:23
Сообщение #51


Гуру
******

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



Цитата(jcxz @ Apr 16 2015, 10:02) *
Готовность AT45DB никак не надо обходить. Считывать регистр состояния согласно документации. Хоть программно, хоть с DMA.

Подскажите а в чём преимущество, если я готовность буду через DMA получать?
Просто мозг закипает.
Кто-нибудь приведёт расчёт доказывающий эффективность такой работы?
Для меня совершенно очевидна потеря производительности процессора в данном случае. Плюс явное усложнение читаемости программы. Плюс существенное замедление процесса записи флэшки.
По-моему необходимо рассчитывать производительность системы в целом. Не всегда имеет смысл передавать управление другой задаче. Учитывая, что время переключения с задачи на задачу фиксированное и зависит от выбранной ОС и особенностей процессора, чем меньше будет тик ОСи тем больше потери будут на обслуживание работы ОСи. Но тем быстрее будет реакция системы. Поэтому необходим какой-то компромисс. Но в любом случае что вызов прерывания, что передача управления другой задаче это многие десятки тактов. Если анализ занимает меньшее время, или сопоставим, нет смысла этим заниматься.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 16 2015, 16:42
Сообщение #52


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Golikov A. @ Apr 16 2015, 10:26) *
Это не верно!
Они вредят только в одном случае, при неожиданном разрыве обмена их надо очищать от старых пакетов... И в LPC для уарта они сделали очистку, а для SSP нет, приходиться 8 слов читать чтобы точно передатчик был пусть, в случае слейва это ложиться на внешнее устройство...


Тогда объясните алгоритм приема пакета с фифо, где 1й байт ИД, который нужно фильтровать, затем адрес, то-же самое, и длина, по которой определяется буфер, а в конце еще и КС??
Причем длина, как правило, не кратна фифо. Таймауты использовать нельзя!

Цитата(SasaVitebsk @ Apr 16 2015, 12:23) *
Подскажите а в чём преимущество, если я готовность буду через DMA получать?
Просто мозг закипает.


По своей памяти, с флешкой работал странично, т.е. запихиваю 264 байта, через дма, затем жду отмены бизи, потом опять...

Если флешка побайтная - то дма не нужен, только для чтения и блоками.

Цитата(jcxz @ Apr 16 2015, 10:02) *
Ну да... 11520*6UART*2(TX/RX) итого частота прерываний ==138240Гц, т.е. - прерывания с периодом 7.2мкс конечно не нагружают никак систему


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

И 130кгц прерываний, для векторного nvic - это немного. Тут все зависит от "кривости" обработчика wink.gif

Сообщение отредактировал mantech - Apr 16 2015, 16:43
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 16 2015, 17:06
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Тогда объясните алгоритм приема пакета с фифо, где 1й байт ИД, который нужно фильтровать, затем адрес, то-же самое, и длина, по которой определяется буфер, а в конце еще и КС??
Причем длина, как правило, не кратна фифо. Таймауты использовать нельзя!


такой же как и без FIFO. Только разница вот в чем. На 115200 время передачи 1 символа ~87 мкСек, а 16 символов уже 1.3 мСек. То есть если у вас нет фифо, то вы нигде не можете висеть дольше 87 мкСек, потому что иначе уже полученный символ затрется следующим, а если фифо есть, то у вас уже 1.3 миллисекунда есть в запасе до того как начнут гибнуть пришедшие символы.

Можно сразу сделать опрос по таймеру с 1 мСек интервалами, и ничего гарантированно не потеряется а нагрузка в 16 раз меньше чем по прерыванием на каждый символ.

FIFO ничего не меняет в логике, кроме того что создает запас на всякие непредвиденные случаи.
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 16 2015, 18:31
Сообщение #54


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Golikov A. @ Apr 16 2015, 20:06) *
FIFO ничего не меняет в логике, кроме того что создает запас на всякие непредвиденные случаи.


Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится.



Цитата(Golikov A. @ Apr 16 2015, 20:06) *
Можно сразу сделать опрос по таймеру с 1 мСек интервалами,


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

ЗЫ. Лично мое мнение - фифо использовать хоть как-то удобно только под небольшие пакеты кратной длины, остальное либо прерывания, либо дма.

Сообщение отредактировал mantech - Apr 16 2015, 18:33
Go to the top of the page
 
+Quote Post
den_po
сообщение Apr 16 2015, 18:48
Сообщение #55


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(mantech @ Apr 16 2015, 23:31) *
Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится.

Таймаут в 3-4 символа -- это слишком много? Что это за устройство у вас такое?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 17 2015, 02:27
Сообщение #56


Гуру
******

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



Цитата(SasaVitebsk @ Apr 16 2015, 15:23) *
Подскажите а в чём преимущество, если я готовность буду через DMA получать?
...
Учитывая, что время переключения с задачи на задачу фиксированное и зависит от выбранной ОС и особенностей процессора, чем меньше будет тик ОСи тем больше потери будут на обслуживание работы ОСи. Но тем быстрее будет реакция системы. Поэтому необходим какой-то компромисс. Но в любом случае что вызов прерывания, что передача управления другой задаче это многие десятки тактов. Если анализ занимает меньшее время, или сопоставим, нет смысла этим заниматься.

Вы мой пост вообще читали или сразу отвечать начали? wink.gif
Я вообще-то там и написал, что в зависимости от соотношения частот CPU и SCLK SPI (сколько тактов CPU займёт SPI-транзакция) и от размера транзакции и нужно определять, что эффективнее - через DMA, или по прерываниям или вообще поллингом (если SCLK - велика, а транзакция == 1-2 байта).

Кстати, если речь зашла о AT45DB, то насколько помню там есть возможность быстрого чтения статуса: при активном сигнале CS и отсутствии обмена по SPI, она на линии MISO держит статус занятости. И достаточно просто прочитать состояние пина.
Хотя - может путаю с другой ИС? Уже не помню, давно работал с ней....

Цитата(mantech @ Apr 17 2015, 00:31) *
Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится.

Что за протокол такой кривой, что 3-4 символа задержка для него обрушивает обмен? На помойку его! wink.gif
Если таймаут ответа такой короткий, то получается и ответ надо формировать в ISR, а перед этим значит надо и распарсить принятый кадр (на который отвечаем), а значит и парсер входящих кадров
(и собственно вся обработка протокола) должен быть в ISR.
Вот собственно Вы сами и ответили на свой-же вопрос про 130кГц прерываний biggrin.gif
Так построенная работа (обработка протокола в ISR) да ещё для нескольких каналов параллельно и завалит всю вашу систему wink.gif
Пока Вы будете формировать ответ с таймаутом 3-4 символа в ISR, в это время по другому каналу (работающему без FIFO) произойдёт потеря байтов.

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

Цитата(mantech @ Apr 17 2015, 00:31) *
ЗЫ. Лично мое мнение - фифо использовать хоть как-то удобно только под небольшие пакеты кратной длины, остальное либо прерывания, либо дма.

Главный плюс FIFO: кратное снижение необходимой частоты обслуживания хоть процессором (снижение частоты прерываний) хоть DMA (пакетные пересылки по шине, меньше её занятость).

Цитата(mantech @ Apr 16 2015, 22:42) *
И 130кгц прерываний, для векторного nvic - это немного. Тут все зависит от "кривости" обработчика wink.gif

Немного, когда CPU нечем больше заниматься...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 17 2015, 05:11
Сообщение #57


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь,

А... дело в том что фифо всегда 16 символов, оно не настраиваемо. А прерывание можно настроить на 1 символ, половину фифо, все фифо.

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

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


Для SPI slave без фифо или ДМА вообще нельзя, внешнее устройство делает клоки и вам надо успевать пихать данные, тут выходное фифо вам дает хоть какую-то свободу а без него, только ДМА иначе тупо долбить флаг что ушел очередной байт и мигом пихать новый, и не моги ни на что отвлекаться...
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 17 2015, 05:17
Сообщение #58


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Apr 17 2015, 05:27) *
Вот собственно Вы сами и ответили на свой-же вопрос про 130кГц прерываний
Так построенная работа (обработка протокола в ISR) да ещё для нескольких каналов параллельно и завалит всю вашу систему


Не буду впадать в тупой спор, просто скажу, что кроме уартов на интах, работает файловая система, сетевой стек, парсер биткода виртуальной задачи, работа с кучей периферии, включая несколько каналов 1wire(кто в теме, тот знает, как этот протокол чувствителен к задержкам)и еще много чего... И самое главное - все работает и "не жужжит". Зависнуть все может только из-за кривости самого программиста.

Цитата(Golikov A. @ Apr 17 2015, 08:11) *
Потом настраиваем прерывание на 1 символ, ставим ему не высокий приоритет и все.лекаться...


Дак какой тогда выигрыш-то, кроме дополнительных настроек? Я же говорю, что выигрыш есть, если в протоколе байты передаются кратными пакетами, на которые настроен триггер фифо. Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика?? На частоте 160 МГц?? И за это время что можно потерять?? Ничего не терялось никогда.
Go to the top of the page
 
+Quote Post
den_po
сообщение Apr 17 2015, 05:37
Сообщение #59


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(Golikov A. @ Apr 17 2015, 10:11) *
А... дело в том что фифо всегда 16 символов, оно не настраиваемо. А прерывание можно настроить на 1 символ, половину фифо, все фифо.

Не особо понимаю, к чему это (просто конкретный пример?), но на всякий случай замечу, что на некоторых МК размер фифо настраивается, а ещё фифо умеют генерить прерывание таймаута.

Наверное я кривовато выразился про настройку размера, да.

Сообщение отредактировал den_po - Apr 17 2015, 05:41
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 17 2015, 05:57
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Если фифо железное, то глубина фифо определена жестко, вопрос в том на какой наполненности мы узнаем что там что-то есть. Если только можно увеличить глубину одного фифо за счет другого... но это экзотика какая-то ИМХО.

Цитата
И самое главное - все работает и "не жужжит"

Ну можно только вам позавидовать. Я бы переживал за систему у которой практически все на прерываниях висит...

Цитата
Дак какой тогда выигрыш-то, кроме дополнительных настроек?

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

Цитата
Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика??

А обработка общего буфера где? А как же про ответ за время 2-3 символов?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 17 2015, 07:01
Сообщение #61


Гуру
******

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



Цитата(mantech @ Apr 17 2015, 11:17) *
Дак какой тогда выигрыш-то, кроме дополнительных настроек? Я же говорю, что выигрыш есть, если в протоколе байты передаются кратными пакетами, на которые настроен триггер фифо. Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика?? На частоте 160 МГц?? И за это время что можно потерять?? Ничего не терялось никогда.

Какие пару байт? Передёргиваете. Вы писали про размер кадра немного меньше размера FIFO. Его проверить надо (валидность всех полей, CRC, etc), прогнать полученный кадр по всем веткам протокола обмена надо (а он может быть многоуровневый) и только после этого можно будет формировать ответ (который тоже нужно сформировать (CRC и т.п.)).
А представьте теперь, что как раз в это время когда Вы это всё будете делать, по другому UART пришло ещё пару байт. А если ещё в этот момент и по 3-му и по 4-му UARTам ...?
Вероятность всё меньше и меньше, но это только говорит о том, что такие ситуации будут происходить редко, и будет Ваша система работать-работать, но иногда глючить
(терять байты, нарушаться связь при идеальной линии и т.п.).

И вот не надо рассказывать про 160МГц, здесь вроде не маркетологи сидят, а кое-кто даже даташиты на МК почитывает wink.gif
У Вас ПО из ОЗУ работает? Или всё-таки из флешь? А скорость флешь с ростом частоты CPU не повышается, как была около 20МГц, так и осталась даже на STM32F4.
Так что - работало-работало Ваше ПО в фоне, горя не знало, заполнило кеш строками из фоновой задачи, тут вдруг пришло прерывание от UART и полезло оно вытаскивать команды из флешь, медленно и печально на 20МГц-ах...
А ему надо успеть за 2-3 символа кучу работы обмолотить. Опа... smile3009.gif
Хоть техасцы в Tiva сделали шину к флешь в 2 раза пошире - там быстрее должно вытаскивать команды из флешь....
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 17 2015, 08:50
Сообщение #62


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Apr 17 2015, 10:01) *
Какие пару байт? Передёргиваете. Вы писали про размер кадра немного меньше размера FIFO. Его проверить надо (валидность всех полей, CRC, etc), прогнать полученный кадр по всем веткам протокола обмена надо (а он может быть многоуровневый) и только после этого можно будет формировать ответ (который тоже нужно сформировать (CRC и т.п.)).


CRC считается по таблице - это недолго, определить ИД и длину еще быстрее, и флеш не такой уж медленный, как кажется, во первых 64 или 128 битный доступ, плюс конвеер, скорость почти не ограничивает, если не делать умопомрачительных ветвлений.
И протокол не настолько "тупой", много чего делается до начала передачи (ответы подтверждения, запроса идентификации вновь подключенных устройств и т.д.)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 17 2015, 09:42
Сообщение #63


Гуру
******

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



Цитата(mantech @ Apr 17 2015, 14:50) *
CRC считается по таблице - это недолго, определить ИД и длину еще быстрее, и флеш не такой уж медленный, как кажется, во первых 64 или 128 битный доступ, плюс конвеер, скорость почти не ограничивает, если не делать умопомрачительных ветвлений.

CRC - это для примера. Может быть, что угодно для проверки валидности кадра.
64-битный доступ к флешь увеличивает скорость флешь всего в 2 раза (даже на линейном коде без ветвлений в случае последовательности 4-байтовых инструкций) с 20 до 40МГц (эквивалентных).
Для 160МГц без тормозов на линейном 4-байтовом коде, нужна шина 256бит к флешь-памяти. Как сделано в Tiva.

PS: Впрочем - тред уже совсем ушёл в сторону. Вас не переубедить похоже, да и нафик wink.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 17 2015, 11:19
Сообщение #64


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



А еще любое прерывание - это сброс всех конвейеров...
Go to the top of the page
 
+Quote Post
mantech
сообщение Apr 17 2015, 17:17
Сообщение #65


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Apr 17 2015, 12:42) *
64-битный доступ к флешь увеличивает скорость флешь всего в 2 раза (даже на линейном коде без ветвлений в случае последовательности 4-байтовых инструкций) с 20 до 40МГц (эквивалентных).

PS: Впрочем - тред уже совсем ушёл в сторону. Вас не переубедить похоже, да и нафик wink.gif


Для справки, в стм флеш шина 128бит и частота 30МГц. Подружитесь с математикой и посчитайте, сколько времени выполняется одна инструкция при этих частотах, и сопоставте со временем между приемом символов...
ЗЫ Для обработки моего "неудачного" протокола требуется от 25 до 40 машинных инструкций, вот и прикинте, если интересно, а переубеждать меня не надо, я не зеленый студент, и проектов дофига сделал, причем все работают как надо rolleyes.gif

Сообщение отредактировал mantech - Apr 17 2015, 17:17
Go to the top of the page
 
+Quote Post
Эдди
сообщение Apr 23 2015, 09:47
Сообщение #66


Знающий
****

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



Если кому интересно, можно глянуть на систему управления спектрографом. Я ее с использованием opencm3 делал.
Вполне удобная библиотека. Правда, часть вещей все равно лучше напрямую регистрами делать...
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 6 2015, 04:10
Сообщение #67


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



А позвольте некропостнуть и вступить в полемику по поводу высокоуровневых либ а-ля Cube.
Я сейчас много об этом думаю, а тут на тему наткнулся, прочитал 5 страниц.
Насколько я понял, большинство не переносит Cube по причине сложности (читай - простоты использования и универсальности). Ее верхний уровень куда выше верхнего уровня той же stdlib и уж подавно opencm3, поэтому напрямую их сравнивать как бы не совсем корректно.
Я не претендую на правоту, скорее хочу взвесить все за и против.

Вот, к примеру, надо мне передать 100 байт по UART. Раньше пользовался stdlib, в прерывании вызывал функцию, которая хранит пойнтер на массив, индексирует его и отдает очередной байт. Позже появилось желание не писать это в каждом проекте, а создать либу верхнего уровня для UART. Потом был SPI и так далее. В cube сделано то же самое, только универсально (и я хочу верить, ее проверяли, во всяком случае, версии новые выходят): есть готовый обработчик прерываний, досылающий массив, и вызывающий калбек поле полной отправки.
Да, код из-за этого большой. Конечно, если я буду делать максимально маленькое или максимально быстрое приложение, ни о каком cube речи не идет. Возможно, иногда даже поллингом получится передать быстрее, чем через прерывания или DMA.
Объясните, чем он так плох? И чем хорошо использовать opencm3, который не намного удобней работы с регистрами для человека, хорошо знакомого с камнем?
Go to the top of the page
 
+Quote Post
Эдди
сообщение Oct 6 2015, 05:43
Сообщение #68


Знающий
****

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



Вкратце: CUBE — признак идиота. Это как ардуйня. Только даже хуже.
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 6 2015, 05:46
Сообщение #69


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(Эдди @ Oct 6 2015, 11:43) *
Вкратце: CUBE — признак идиота. Это как ардуйня. Только даже хуже.

А Вы попробуйте не вкратце, если не сложно.
Где граница между признаком идиота и библиотекой? Графические библиотеки тоже под запретом? А готовые ОС?
Если что, я не о программе Cube, а о библиотеке, что она использует. STM позиционирует ее как замену stdperiph_lib.

Сообщение отредактировал drozel - Oct 6 2015, 05:47
Go to the top of the page
 
+Quote Post
mantech
сообщение Oct 6 2015, 06:27
Сообщение #70


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(drozel @ Oct 6 2015, 07:10) *
Объясните, чем он так плох? И чем хорошо использовать opencm3, который не намного удобней работы с регистрами для человека, хорошо знакомого с камнем?


Да ни чем не плох, просто всегда удивляюсь, когда кто-нибудь решает, что можно ничего не зная о камне, как правило, не читая доков, просто взять какой-нить визард, типа куба и пр... и "написать" на нем прогу любой сложности, за день или меньше... Так-то фиг с ним, пускай пишет, только потом она, почему-то не работает!!! Вот почему, блин?!

По мне, можно писать на чем угодно, сам писал с использованием либ от СТ, но при этом хотя-бы чуток разбираться в камне и уметь читать код этих либ, тогда и понимание, "почему...", придет само собой.

Цитата(Эдди @ Oct 6 2015, 08:43) *
Вкратце: CUBE — признак идиота. Это как ардуйня. Только даже хуже.


Скажем так, если "программист" считает, что на кубе можно все "написать" от и до, то да - признак идиота, а если его использовать, как вспомогательный инструмент к голове - то полезная вещь.
ЗЫ. А на счет ардуины - не стоит так категорично, иногда нужно сделать просто и быстро - почему и нет?? Сам себе сделал что-то подобное на МХ6 с графикой, типа виндовой - для есложных приложений с гуем - самое оно biggrin.gif

Сообщение отредактировал mantech - Oct 6 2015, 06:31
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 6 2015, 06:28
Сообщение #71


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Вот вам на пальцах:

Ну берем SPI, настраиваем по кубовски на ДМА слейв прием, все там подключаем, запускаем, вроде как работает.

Идем дальше, хотим сделать так, буфер 1024 байта, заполняется по ДМА, время от времени проверяем его и если в нем уже есть полное сообщение (определяется по размеру сообщения в заголовке и по тому сколько байт приняло ДМА), забираем сообщение и перенастриваем ДМА на прием нового сообщения. Казалось бы все функции есть, и тут на тебе!

В процедуре завершения ДМА обмена вставлен таймаут аж на кучу миллисекунд. Ну е мое! И более того он еще забит одной единой коснтантой, и от него едут все остальные таймауты, И таймер нужен кубовский, который не просто считает а вызывает еще доп функции тормозя весь процесс... И начинаешь это все преписывать, допиливая библиотечные файлы, и в итоге для того чтобы сделать что-то с нормальной производительностью надо все руками переписать, сломав всю предложенную логику куба. И что от него остается?

Ну дальше мы добавляем кучу ошибок ввиде переменных у которых забили valotile и следовательно при оптимизации отличной от none половина задержек виснет насмерть. Дальше добавляем задержки через while которые убивают RTOS если вдруг до нее дойдет.

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

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


Все естественно ИМХО.





Go to the top of the page
 
+Quote Post
mantech
сообщение Oct 6 2015, 06:34
Сообщение #72


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(Golikov A. @ Oct 6 2015, 09:28) *
К этому так же надо добавить наличие просто ошибок, коих немало в кубе, то есть не оглядываясь его использовать во взрослом проекте нельзя. А если мне надо его весь прочитать и перелопатить, то почему бы мне не сделать свою нормальную библиотеку?

Все естественно ИМХО.


Дак так и получается, если делать не один проект, то все-равно дорабатываешь либы под себя и убираешь ошибки. Но ИМХО, писать с нуля, например усб стеки - ну это для отпетых "гурманов" biggrin.gif
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 6 2015, 07:11
Сообщение #73


Гуру
******

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



Мне кажется пример для UART вы неудачный выбрали. ))
Дело в том, что написать универсальный обработчик UART, на мой взгляд, нецелесообразно.
С одной стороны сам USART позволяет слишком многое, а с другой стороны законченный драйвер должен обеспечивать хотя бы канальный уровень (ведущий/ведомый, контрольная сумма, контроль приёма сообщений) и сетевой (определение маршрута и логическая адресация). А это для разных протоколов существенно отличается. То есть универсальный или не получится или будет слишком громоздкий, избыточный.
Кроме того значительно чаще интересен не "универсальный драйвер для одного типа МК (например STM32F4)", а драйвер для целого семейства. И здесь начинают проявляться особенности периферии. Посмотрите мануалы для F0/F1/F3/F4 контроллеров STM. Вроде похожи, но ... Кое где предусмотрена обработка полудуплекса, а где-то нет. Где то есть аппаратная обработка логичесской адресации. Разная обработка LIN протоколов. Ещё всякие особенности ...
Причём сама работа с железом у вас составит максимум 1% от библиотеки. Думаю меньше на самом деле. И она проста до безобразия. Вам просто надо почитать описание самих регистров.
Вот и получается ...
С одной стороны - прочитать описание регистров контроллера и написать универсальную (по возможности) библиотеку своего протокола.
С другой стороны - прочитать описание библиотеки КУБ или другой, со всеми взаимоувязками (так как там одна написана через другую) и, опять же, написать библиотеку своего протокола.
...
Так ответьте мне. В чём выигрыш? Я вот просто не пойму.
У меня создаётся впечатление, что библиотеками пользуются те, кто сами вообще ничего не пишут. А берут готовый пример с просторов инета, и прикручивают что-то своё с косяками.
...
Некоторыми библиотеками я пользуюсь сам. Например Ethernet. Но думаю, там то же самое. Просто недостаток моих знаний и времени. Я уверен, что если переписать это всё под себя то работать будет комфортней намного.
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 6 2015, 07:17
Сообщение #74


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(mantech @ Oct 6 2015, 09:34) *
Но ИМХО, писать с нуля, например усб стеки - ну это для отпетых "гурманов" biggrin.gif

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

Цитата(SasaVitebsk @ Oct 6 2015, 10:11) *
У меня создаётся впечатление, что библиотеками пользуются те, кто сами вообще ничего не пишут. А берут готовый пример с просторов инета, и прикручивают что-то своё с косяками.

+1. Запустить UART - это вообще тривиально. А режимы там разные могут быть, как верное подмечено, то есть рассчитывать на то, что чудо-библиотека всё сделает сама, не стоит. Если UART пугает, то, может, и подходить к МК не нужно?

Цитата(SasaVitebsk @ Oct 6 2015, 10:11) *
Например Ethernet. Но думаю, там то же самое. Просто недостаток моих знаний и времени. Я уверен, что если переписать это всё под себя то работать будет комфортней намного.

Я думаю, самому делать TCP - неблагодарное занятие. Читать все эти RFC (а их много), отлаживать алгоритмы в реальных условиях (а эти условия могут быть сильно разные) - куча работы. Если кто-то это уже проделал, глупо повторять этот же путь снова.
Go to the top of the page
 
+Quote Post
mantech
сообщение Oct 6 2015, 07:30
Сообщение #75


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(scifi @ Oct 6 2015, 10:17) *
Конечно, если при выдирании выясняется, что там всё со всем связано тысячью нитей, то становится грустно...


Прямо в точку!! rolleyes.gif
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 6 2015, 08:18
Сообщение #76


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(scifi @ Oct 6 2015, 13:17) *
+1. Запустить UART - это вообще тривиально.

Ну тривиально, тривиально. Также, как и SPI. Может я неправильно устроен, но, когда я таскаю из проекта в проект вывод printf в UART/USB, мне хочется запихать это уже в законченный .c + .h и подключать, как модуль.
А ведь периферии много. И UARTов может быть много, а это, как правильно подметили, 1% от серьезной программы. Код неплохо было бы иметь читаемый, а не CR |= 0x01b1;

Сообщение отредактировал drozel - Oct 6 2015, 08:21
Go to the top of the page
 
+Quote Post
ViKo
сообщение Oct 6 2015, 08:49
Сообщение #77


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

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



Цитата(drozel @ Oct 6 2015, 11:18) *
Код неплохо было бы иметь читаемый, а не CR |= 0x01b1;

Например:
Код
  USART2->CR1 =
    USART_CR1_SBK        * 0 |    // Send Break
    USART_CR1_RWU        * 0 |    // Receiver wakeup
    USART_CR1_RE        * 1 |    // Receiver Enable
    USART_CR1_TE        * 1 |    // Transmitter Enable
    USART_CR1_IDLEIE    * 0 |    // IDLE Interrupt Enable
    USART_CR1_RXNEIE    * 1 |    // RXNE Interrupt Enable
    USART_CR1_TCIE        * 0 |    // Transmission Complete Interrupt Enable
    USART_CR1_TXEIE        * 0 |    // TE Interrupt Enable
    USART_CR1_PEIE        * 0 |    // PE Interrupt Enable
    USART_CR1_PS        * 0 |    // Parity Selection - Even
    USART_CR1_PCE        * 0 |    // Parity Control Enable
    USART_CR1_WAKE        * 0 |    // Wakeup method
    USART_CR1_M        * 0 |    // Word length: 1 Start bit, 8 Data bits, n Stop bit
    USART_CR1_UE        * 1 |    // USART Enable
    USART_CR1_OVER8        * 0;    // USART Oversampling by 8 enable
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 6 2015, 10:58
Сообщение #78


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Дак так и получается, если делать не один проект, то все-равно дорабатываешь либы под себя и убираешь ошибки. Но ИМХО, писать с нуля, например усб стеки - ну это для отпетых "гурманов"

не путайте теплое с мягким....

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

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






Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 6 2015, 12:01
Сообщение #79


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Сабж нормальный. Но API в некоторых местах не нравится.
Именно, gpio , rcc и dma
Нужно более юзабельные вещи.
gpio вообще хорошо бы кросс-платформенным сделать
т.е. настройка пинов как в SPL - с одним аргументом указателем на структуру.
Структура является надмножеством всех известных опций для нескольких архитектур.

rcc - управление клоками и ресетом - лучше с привязкой к адресу периферии.
dma - как бы тоже, чтобы канал и стрим выбирало само исходя из указанного адреса периферии.
в принципе - небольшая табличка во флеше решает проблемы с необходимостью лазать по даташиту.

Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 7 2015, 03:28
Сообщение #80


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(_Pasha @ Oct 6 2015, 18:01) *
dma - как бы тоже, чтобы канал и стрим выбирало само исходя из указанного адреса периферии.
в принципе - небольшая табличка во флеше решает проблемы с необходимостью лазать по даташиту.

Ну так это и есть библиотека более высокого уровня. Что-то вроде того и реализовано в Cube, но, говорят много ошибок и недоработок.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 7 2015, 04:45
Сообщение #81


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(drozel @ Oct 7 2015, 06:28) *
Ну так это и есть библиотека более высокого уровня. Что-то вроде того и реализовано в Cube, но, говорят много ошибок и недоработок.

Из куба один раз попробовал запустить что-то с usb, быстро перехотелось.

Высокого уровня... вот например - годами одна и та же функция настройки
Код
int uart_setup( // >0 - configured yet 0-service busy <0 - error
    char n,// which one
    baud_t baud, // may be long or int32
    char bits,      // ['5'..'9']
    char parity,  // ['E','O','N']
    char stops); // ['1','2']

не включает в себя экзотику типа multiprocessor mode или 1.5 стопа
но я что-то не припомню когда ими пользовался...



Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 8 2015, 09:24
Сообщение #82


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Люди, помогите с либой.
Пытаюсь завести USB CDC с libopencm3 и вот этим примером.
Я допускаю, что туплю, библиотека написана с каким то жонглированием указателями, которое мне пока непривычно + пришлось немного портировать на IAR, т.к. либа содержит много директив от GCC. На данный момент USB поднимается, но устройство не опознается, PID и VID комп видит нулевые.
Конкретный вопрос:
Код
usbd_device *usbd_init(const usbd_driver *driver,
               const struct usb_device_descriptor *dev,
               const struct usb_config_descriptor *conf,
               const char **strings, int num_strings,
               uint8_t *control_buffer, uint16_t control_buffer_size)
{
    usbd_device *usbd_dev;

    usbd_dev = driver->init();

    usbd_dev->driver = driver;
    usbd_dev->desc = dev;
    usbd_dev->config = conf;
    usbd_dev->strings = strings;
    usbd_dev->num_strings = num_strings;
    usbd_dev->ctrl_buf = control_buffer;
    usbd_dev->ctrl_buf_len = control_buffer_size;

    usbd_dev->user_callback_ctr[0][USB_TRANSACTION_SETUP] =
        _usbd_control_setup;
    usbd_dev->user_callback_ctr[0][USB_TRANSACTION_OUT] =
        _usbd_control_out;
    usbd_dev->user_callback_ctr[0][USB_TRANSACTION_IN] =
        _usbd_control_in;

    int i;
    for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) {
        usbd_dev->user_callback_set_config[i] = NULL;
    }

    return usbd_dev;
}

Что при этом возвращает функция? Указатель на локальную переменную (стек)?
Ведь переменная локальная, выделена не динамически. Я просто в ступоре.

---
UPD все, наладил, проблема была у меня.
Тем не менее, прошу ликбеза по си..

Сообщение отредактировал drozel - Oct 8 2015, 10:10
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 8 2015, 10:34
Сообщение #83


Гуру
******

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



Цитата(drozel @ Oct 8 2015, 12:24) *
Что при этом возвращает функция? Указатель на локальную переменную (стек)?

Функция возвращает указатель на структуру типа usbd_device. То есть фактически, на адрес в памяти, где находится переменная.
Цитата
Ведь переменная локальная, выделена не динамически. Я просто в ступоре.

Локальная - не есть выделенная динамически. Локальная выделяется на стеке и уничтожается при выходе из процедуры (точнее становится непредсказуемой). Выделена динамически, значит размещена на куче. Она уничтожается только явно процедурой free.
В данном случае локально объявляется указатель. Далее запускается driver->init(), что похоже динамически выделяет память и инициализирует структуру. П/п возвращает этот указатель.
В чём вопрос?
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 8 2015, 16:41
Сообщение #84


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(SasaVitebsk @ Oct 8 2015, 16:34) *
В чём вопрос?

Да, запарился с этой либой, затупил.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 8 2015, 18:53
Сообщение #85


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



usbd_device *usbd_init
возвращает указатель на static а не локальную.
usbd_dev = driver->init(); здесь он получает указатель

этот статик хранится в физике типа usb_f103.c и иже с ними
просто он там потому что самое большое число связей с ним именно там.
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 9 2015, 01:57
Сообщение #86


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Да, уже нашел, спасибо. Просто непривычно: вместо того, чтоб сделать ее глобальной делают ее глобальным статиком и передают указатель через череду фукнций.
Более правильно, согласен.
В стдлибе от СТМ кстати, именно глобальные структуры

Сообщение отредактировал drozel - Oct 9 2015, 02:00
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 9 2015, 09:11
Сообщение #87


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(drozel @ Oct 9 2015, 04:57) *
Да, уже нашел, спасибо. Просто непривычно: вместо того, чтоб сделать ее глобальной делают ее глобальным статиком и передают указатель через череду фукнций.
Более правильно, согласен.

Ну это такой сиплюсплюс из костылей: "класс" логики работает с "классом" физического драйвера через указатель на последний.
Если понимать принципы C++, всё понятно и очевидно.
Но работать всё равно неудобно - IDE не "прыгает" при чтении кода к соотв. функции, да и ошибиться при заполнении структуры с указателями куда легче...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 12 2015, 11:10
Сообщение #88


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Почти мигрировал с stdlib и cube на сабж.
Остался вопрос, нужна помощь.
Где файл, прописывающий в память таблицу векторов прерываний? В stdlib был стартап файл на асме, здесь уже перерыл все, в упор не вижу.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 12 2015, 11:40
Сообщение #89


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(drozel @ Oct 12 2015, 14:10) *
Почти мигрировал с stdlib и cube на сабж.
Остался вопрос, нужна помощь.
Где файл, прописывающий в память таблицу векторов прерываний? В stdlib был стартап файл на асме, здесь уже перерыл все, в упор не вижу.

это содержимое папки dispatch и далее по дефайну.



собирайте сразу в статик либу. гемора потом вообще 0.0%
правда, я перед этим выдрал из usb отдельно SCSI и компильнул либы без него.
потому что msc полно сюрпризов.
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 12 2015, 11:55
Сообщение #90


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(_Pasha @ Oct 12 2015, 17:40) *
это содержимое папки dispatch и далее по дефайну.

Там 2 файла: vector_chipset.c и vector_nvic.c
Первый инклудит аналогичный файл из папки f4 (в моем случае), который просто включает сопроцессор:
Код
static void pre_main(void)
{
    /* Enable access to Floating-Point coprocessor. */
    SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11);
}


Второй соответственно ищет vector_nvic.c в папке семейства, но его там нет.

Зато есть зацепка в папке scripts, скрипт irq2nvic_h, вроде на питоне (судя по строке #!/usr/bin/env python), содержащий, помимо всего прочего,такие строки
Код
"""Generate an nvic.h header from a small JSON file describing the interrupt
numbers.

Code generation is chosen here because the resulting C code needs to be very
repetetive (definition of the IRQ numbers, function prototypes, weak fallback
definition and vector table definition), all being very repetitive. No portable
method to achive the same thing with C preprocessor is known to the author.
(Neither is any non-portable method, for that matter.)"""


Я на питоне не силен, скачал интерпретатор под винду, пытаюсь его как-то запустить. Пока неудачно, но это вопрос скорее в тему по питону.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 12 2015, 12:14
Сообщение #91


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(drozel @ Oct 12 2015, 14:55) *
Зато есть зацепка в папке scripts, скрипт irq2nvic_h, вроде на питоне (судя по строке #!/usr/bin/env python), содержащий, помимо всего прочего,такие строки
Код
"""Generate an nvic.h header from a small JSON file describing the interrupt
numbers.

Code generation is chosen here because the resulting C code needs to be very
repetetive (definition of the IRQ numbers, function prototypes, weak fallback
definition and vector table definition), all being very repetitive. No portable
method to achive the same thing with C preprocessor is known to the author.
(Neither is any non-portable method, for that matter.)"""


Я на питоне не силен, скачал интерпретатор под винду, пытаюсь его как-то запустить. Пока неудачно, но это вопрос скорее в тему по питону.


держите для F4


CODE
/* This file is part of the libopencm3 project.
*
* It was generated by the irq2nvic_h script.
*
* This part needs to get included in the compilation unit where
* blocking_handler gets defined due to the way #pragma works.
*/


/** @defgroup CM3_nvic_isrpragmas_STM32F4 User interrupt service routines (ISR) defaults for STM32 F4 series
@ingroup CM3_nvic_isrpragmas

@{*/

#pragma weak nvic_wwdg_isr = blocking_handler
#pragma weak pvd_isr = blocking_handler
#pragma weak tamp_stamp_isr = blocking_handler
#pragma weak rtc_wkup_isr = blocking_handler
#pragma weak flash_isr = blocking_handler
#pragma weak rcc_isr = blocking_handler
#pragma weak exti0_isr = blocking_handler
#pragma weak exti1_isr = blocking_handler
#pragma weak exti2_isr = blocking_handler
#pragma weak exti3_isr = blocking_handler
#pragma weak exti4_isr = blocking_handler
#pragma weak dma1_stream0_isr = blocking_handler
#pragma weak dma1_stream1_isr = blocking_handler
#pragma weak dma1_stream2_isr = blocking_handler
#pragma weak dma1_stream3_isr = blocking_handler
#pragma weak dma1_stream4_isr = blocking_handler
#pragma weak dma1_stream5_isr = blocking_handler
#pragma weak dma1_stream6_isr = blocking_handler
#pragma weak adc_isr = blocking_handler
#pragma weak can1_tx_isr = blocking_handler
#pragma weak can1_rx0_isr = blocking_handler
#pragma weak can1_rx1_isr = blocking_handler
#pragma weak can1_sce_isr = blocking_handler
#pragma weak exti9_5_isr = blocking_handler
#pragma weak tim1_brk_tim9_isr = blocking_handler
#pragma weak tim1_up_tim10_isr = blocking_handler
#pragma weak tim1_trg_com_tim11_isr = blocking_handler
#pragma weak tim1_cc_isr = blocking_handler
#pragma weak tim2_isr = blocking_handler
#pragma weak tim3_isr = blocking_handler
#pragma weak tim4_isr = blocking_handler
#pragma weak i2c1_ev_isr = blocking_handler
#pragma weak i2c1_er_isr = blocking_handler
#pragma weak i2c2_ev_isr = blocking_handler
#pragma weak i2c2_er_isr = blocking_handler
#pragma weak spi1_isr = blocking_handler
#pragma weak spi2_isr = blocking_handler
#pragma weak usart1_isr = blocking_handler
#pragma weak usart2_isr = blocking_handler
#pragma weak usart3_isr = blocking_handler
#pragma weak exti15_10_isr = blocking_handler
#pragma weak rtc_alarm_isr = blocking_handler
#pragma weak usb_fs_wkup_isr = blocking_handler
#pragma weak tim8_brk_tim12_isr = blocking_handler
#pragma weak tim8_up_tim13_isr = blocking_handler
#pragma weak tim8_trg_com_tim14_isr = blocking_handler
#pragma weak tim8_cc_isr = blocking_handler
#pragma weak dma1_stream7_isr = blocking_handler
#pragma weak fsmc_isr = blocking_handler
#pragma weak sdio_isr = blocking_handler
#pragma weak tim5_isr = blocking_handler
#pragma weak spi3_isr = blocking_handler
#pragma weak uart4_isr = blocking_handler
#pragma weak uart5_isr = blocking_handler
#pragma weak tim6_dac_isr = blocking_handler
#pragma weak tim7_isr = blocking_handler
#pragma weak dma2_stream0_isr = blocking_handler
#pragma weak dma2_stream1_isr = blocking_handler
#pragma weak dma2_stream2_isr = blocking_handler
#pragma weak dma2_stream3_isr = blocking_handler
#pragma weak dma2_stream4_isr = blocking_handler
#pragma weak eth_isr = blocking_handler
#pragma weak eth_wkup_isr = blocking_handler
#pragma weak can2_tx_isr = blocking_handler
#pragma weak can2_rx0_isr = blocking_handler
#pragma weak can2_rx1_isr = blocking_handler
#pragma weak can2_sce_isr = blocking_handler
#pragma weak otg_fs_isr = blocking_handler
#pragma weak dma2_stream5_isr = blocking_handler
#pragma weak dma2_stream6_isr = blocking_handler
#pragma weak dma2_stream7_isr = blocking_handler
#pragma weak usart6_isr = blocking_handler
#pragma weak i2c3_ev_isr = blocking_handler
#pragma weak i2c3_er_isr = blocking_handler
#pragma weak otg_hs_ep1_out_isr = blocking_handler
#pragma weak otg_hs_ep1_in_isr = blocking_handler
#pragma weak otg_hs_wkup_isr = blocking_handler
#pragma weak otg_hs_isr = blocking_handler
#pragma weak dcmi_isr = blocking_handler
#pragma weak cryp_isr = blocking_handler
#pragma weak hash_rng_isr = blocking_handler
#pragma weak fpu_isr = blocking_handler
#pragma weak uart7_isr = blocking_handler
#pragma weak uart8_isr = blocking_handler
#pragma weak spi4_isr = blocking_handler
#pragma weak spi5_isr = blocking_handler
#pragma weak spi6_isr = blocking_handler
#pragma weak sai1_isr = blocking_handler
#pragma weak lcd_tft_isr = blocking_handler
#pragma weak lcd_tft_err_isr = blocking_handler
#pragma weak dma2d_isr = blocking_handler

/**@}*/

/* Initialization template for the interrupt vector table. This definition is
* used by the startup code generator (vector.c) to set the initial values for
* the interrupt handling routines to the chip family specific _isr weak
* symbols. */

#define IRQ_HANDLERS \
[NVIC_NVIC_WWDG_IRQ] = nvic_wwdg_isr, \
[NVIC_PVD_IRQ] = pvd_isr, \
[NVIC_TAMP_STAMP_IRQ] = tamp_stamp_isr, \
[NVIC_RTC_WKUP_IRQ] = rtc_wkup_isr, \
[NVIC_FLASH_IRQ] = flash_isr, \
[NVIC_RCC_IRQ] = rcc_isr, \
[NVIC_EXTI0_IRQ] = exti0_isr, \
[NVIC_EXTI1_IRQ] = exti1_isr, \
[NVIC_EXTI2_IRQ] = exti2_isr, \
[NVIC_EXTI3_IRQ] = exti3_isr, \
[NVIC_EXTI4_IRQ] = exti4_isr, \
[NVIC_DMA1_STREAM0_IRQ] = dma1_stream0_isr, \
[NVIC_DMA1_STREAM1_IRQ] = dma1_stream1_isr, \
[NVIC_DMA1_STREAM2_IRQ] = dma1_stream2_isr, \
[NVIC_DMA1_STREAM3_IRQ] = dma1_stream3_isr, \
[NVIC_DMA1_STREAM4_IRQ] = dma1_stream4_isr, \
[NVIC_DMA1_STREAM5_IRQ] = dma1_stream5_isr, \
[NVIC_DMA1_STREAM6_IRQ] = dma1_stream6_isr, \
[NVIC_ADC_IRQ] = adc_isr, \
[NVIC_CAN1_TX_IRQ] = can1_tx_isr, \
[NVIC_CAN1_RX0_IRQ] = can1_rx0_isr, \
[NVIC_CAN1_RX1_IRQ] = can1_rx1_isr, \
[NVIC_CAN1_SCE_IRQ] = can1_sce_isr, \
[NVIC_EXTI9_5_IRQ] = exti9_5_isr, \
[NVIC_TIM1_BRK_TIM9_IRQ] = tim1_brk_tim9_isr, \
[NVIC_TIM1_UP_TIM10_IRQ] = tim1_up_tim10_isr, \
[NVIC_TIM1_TRG_COM_TIM11_IRQ] = tim1_trg_com_tim11_isr, \
[NVIC_TIM1_CC_IRQ] = tim1_cc_isr, \
[NVIC_TIM2_IRQ] = tim2_isr, \
[NVIC_TIM3_IRQ] = tim3_isr, \
[NVIC_TIM4_IRQ] = tim4_isr, \
[NVIC_I2C1_EV_IRQ] = i2c1_ev_isr, \
[NVIC_I2C1_ER_IRQ] = i2c1_er_isr, \
[NVIC_I2C2_EV_IRQ] = i2c2_ev_isr, \
[NVIC_I2C2_ER_IRQ] = i2c2_er_isr, \
[NVIC_SPI1_IRQ] = spi1_isr, \
[NVIC_SPI2_IRQ] = spi2_isr, \
[NVIC_USART1_IRQ] = usart1_isr, \
[NVIC_USART2_IRQ] = usart2_isr, \
[NVIC_USART3_IRQ] = usart3_isr, \
[NVIC_EXTI15_10_IRQ] = exti15_10_isr, \
[NVIC_RTC_ALARM_IRQ] = rtc_alarm_isr, \
[NVIC_USB_FS_WKUP_IRQ] = usb_fs_wkup_isr, \
[NVIC_TIM8_BRK_TIM12_IRQ] = tim8_brk_tim12_isr, \
[NVIC_TIM8_UP_TIM13_IRQ] = tim8_up_tim13_isr, \
[NVIC_TIM8_TRG_COM_TIM14_IRQ] = tim8_trg_com_tim14_isr, \
[NVIC_TIM8_CC_IRQ] = tim8_cc_isr, \
[NVIC_DMA1_STREAM7_IRQ] = dma1_stream7_isr, \
[NVIC_FSMC_IRQ] = fsmc_isr, \
[NVIC_SDIO_IRQ] = sdio_isr, \
[NVIC_TIM5_IRQ] = tim5_isr, \
[NVIC_SPI3_IRQ] = spi3_isr, \
[NVIC_UART4_IRQ] = uart4_isr, \
[NVIC_UART5_IRQ] = uart5_isr, \
[NVIC_TIM6_DAC_IRQ] = tim6_dac_isr, \
[NVIC_TIM7_IRQ] = tim7_isr, \
[NVIC_DMA2_STREAM0_IRQ] = dma2_stream0_isr, \
[NVIC_DMA2_STREAM1_IRQ] = dma2_stream1_isr, \
[NVIC_DMA2_STREAM2_IRQ] = dma2_stream2_isr, \
[NVIC_DMA2_STREAM3_IRQ] = dma2_stream3_isr, \
[NVIC_DMA2_STREAM4_IRQ] = dma2_stream4_isr, \
[NVIC_ETH_IRQ] = eth_isr, \
[NVIC_ETH_WKUP_IRQ] = eth_wkup_isr, \
[NVIC_CAN2_TX_IRQ] = can2_tx_isr, \
[NVIC_CAN2_RX0_IRQ] = can2_rx0_isr, \
[NVIC_CAN2_RX1_IRQ] = can2_rx1_isr, \
[NVIC_CAN2_SCE_IRQ] = can2_sce_isr, \
[NVIC_OTG_FS_IRQ] = otg_fs_isr, \
[NVIC_DMA2_STREAM5_IRQ] = dma2_stream5_isr, \
[NVIC_DMA2_STREAM6_IRQ] = dma2_stream6_isr, \
[NVIC_DMA2_STREAM7_IRQ] = dma2_stream7_isr, \
[NVIC_USART6_IRQ] = usart6_isr, \
[NVIC_I2C3_EV_IRQ] = i2c3_ev_isr, \
[NVIC_I2C3_ER_IRQ] = i2c3_er_isr, \
[NVIC_OTG_HS_EP1_OUT_IRQ] = otg_hs_ep1_out_isr, \
[NVIC_OTG_HS_EP1_IN_IRQ] = otg_hs_ep1_in_isr, \
[NVIC_OTG_HS_WKUP_IRQ] = otg_hs_wkup_isr, \
[NVIC_OTG_HS_IRQ] = otg_hs_isr, \
[NVIC_DCMI_IRQ] = dcmi_isr, \
[NVIC_CRYP_IRQ] = cryp_isr, \
[NVIC_HASH_RNG_IRQ] = hash_rng_isr, \
[NVIC_FPU_IRQ] = fpu_isr, \
[NVIC_UART7_IRQ] = uart7_isr, \
[NVIC_UART8_IRQ] = uart8_isr, \
[NVIC_SPI4_IRQ] = spi4_isr, \
[NVIC_SPI5_IRQ] = spi5_isr, \
[NVIC_SPI6_IRQ] = spi6_isr, \
[NVIC_SAI1_IRQ] = sai1_isr, \
[NVIC_LCD_TFT_IRQ] = lcd_tft_isr, \
[NVIC_LCD_TFT_ERR_IRQ] = lcd_tft_err_isr, \
[NVIC_DMA2D_IRQ] = dma2d_isr


питон можно портабл взять
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Oct 12 2015, 12:43
Сообщение #92


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(drozel @ Oct 12 2015, 14:10) *
Где файл, прописывающий в память таблицу векторов прерываний? В stdlib был стартап файл на асме, здесь уже перерыл все, в упор не вижу.


Я пользуюсь гибридом - USB'шный стек на libopencm3, а всё остальное - стандарные ST'шные описания регистров (на мой взгляд, они удобнее. И компилятор их лучше понимает) и стандартный же стартап.
Почему авторы библиотеки пошли своим путём и наплодили ещё и своих имён для регистров - непонятно...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 12 2015, 17:14
Сообщение #93


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(esaulenka @ Oct 12 2015, 18:43) *
Я пользуюсь гибридом - USB'шный стек на libopencm3, а всё остальное - стандарные ST'шные описания регистров (на мой взгляд, они удобнее.

А функции работы с периферией? Или все в регистры пишете?
Go to the top of the page
 
+Quote Post
Эдди
сообщение Oct 12 2015, 18:14
Сообщение #94


Знающий
****

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



Быстрее по даташиту с регистрами разобраться, нежели перелопачивать код opencm3 в поисках нужного функционала!
Сам я и так, и так делаю: где некритично или нежирно, использую функции opencm3, а где критично и/или жирно — регистры.
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 13 2015, 03:33
Сообщение #95


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(_Pasha @ Oct 12 2015, 18:14) *
держите для F4

Спасибо. Но это ведь h, а где тот самый vector.c, который должен помещать таблицу в память?
Код
#elif defined(STM32F4)
#    include "../stm32/f4/vector_nvic.c"

По этому пути его нет и непохоже, что он генерится этим же скриптом.
Цитата(Эдди @ Oct 13 2015, 00:14) *
Быстрее по даташиту с регистрами разобраться, нежели перелопачивать код opencm3 в поисках нужного функционала!

Не согласен я с этим. Я смотрю, людям волю дай, они скажут "быстрее свой МК сделать, чем разбираться с даташитом на этот".
Сложность железа растет. Раньше программы для ПК на асме писали, теперь функциями ОС пользуются.
Если есть нормальная библиотека, ей надо пользоваться. А изобретение велосипедов и мнение "все дураки, сам сделаю лучше" - чисто славянская черта. Имхо, конечно.
Но это не значит. что я не знаю регистры и делаю все вслепую, а когда функция не работает, пугаюсь и плАчу. И вообще, это оффтоп.


Сообщение отредактировал drozel - Oct 13 2015, 03:37
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 13 2015, 04:58
Сообщение #96


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(drozel @ Oct 13 2015, 06:33) *
Спасибо. Но это ведь h, а где тот самый vector.c, который должен помещать таблицу в память?

я не пойму две вещи
1. чем Вы пользуетесь, что так упорно не можете найти cm3/vector.c
есть understand, eclipse тупо grep, в конце концов...
Код
grep -r IRQ_HANDLERS *

2. зачем этот закат солнца вручную, если можно вызвать make -n для того мейкфайла и посмотреть что ж там такое вызывается. и поттом смело со списком собирать то же самое, например в кейле

Сообщение отредактировал _Pasha - Oct 13 2015, 04:59
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 13 2015, 07:58
Сообщение #97


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(_Pasha @ Oct 13 2015, 10:58) *
я не пойму две вещи
1. чем Вы пользуетесь, что так упорно не можете найти cm3/vector.c

Ну grep мне недоступен (винда), но искил я и эклипсом, и тотал командером.
Качал либу отсюда. Если уверены, что я туплю, пожалуйста, ткните носом. vector_chipset.c не считается, там только включение сопроцессора, вызов этой функции тоже должен помещаться стартап-файлом в начало памяти.
Цитата(_Pasha @ Oct 13 2015, 10:58) *
2. зачем этот закат солнца вручную, если можно вызвать make -n для того мейкфайла и посмотреть что ж там такое вызывается. и поттом смело со списком собирать то же самое, например в кейле

Как сказать.. GCC я никогда не пользовался, пользуюсь иаром. Думал, либа нормально поднимется. Если для того, чтобы использовать либу, надо поставить GCC и посмотреть, что делает мейк, то это уже какой-то cranky.gif
С другой стороны, повод научиться пользоваться GCC, можно даже либу собрать в статическую...
Go to the top of the page
 
+Quote Post
Эдди
сообщение Oct 13 2015, 08:26
Сообщение #98


Знающий
****

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



Цитата(drozel @ Oct 13 2015, 10:58) *
Если уверены, что я туплю, пожалуйста, ткните носом.

Код
ls lib/stm32/f4/vector.c
lib/stm32/f4/vector.c

Пример makefile для F1 можно у меня в репах на гитхабе/сосфорже/битбакете/гитлабе посмотреть (stm32samples).
Go to the top of the page
 
+Quote Post
drozel
сообщение Oct 13 2015, 08:35
Сообщение #99


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(Эдди @ Oct 13 2015, 14:26) *
Код
ls lib/stm32/f4/vector.c
lib/stm32/f4/vector.c

Это у Вас в папке или в репе на гитхабе?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 13 2015, 08:39
Сообщение #100


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Как сказать.. GCC я никогда не пользовался, пользуюсь иаром. Думал, либа нормально поднимется. Если для того, чтобы использовать либу, надо поставить GCC и посмотреть, что делает мейк, то это уже какой-то

это вы не соглашались что через регистры было бы быстрееsm.gif?
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 21:13
Рейтинг@Mail.ru


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