Easyelectronics.ru

Электроника для всех
Текущее время: 29 сен 2020, 03:33

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 98 ]  На страницу Пред.  1, 2, 3, 4
Автор Сообщение
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:39 
Старожил
Аватара пользователя

Зарегистрирован: 06 ноя 2013, 16:07
Сообщения: 711
Откуда: Германия
void1509 писал(а):
что значит "неатомарность" на восьмибитниках ? восьмибитники разве многопроцессорные ?


Они много-поточные (прерывания).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:39 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 705
2Axill и в чем проблема - тип объявлен unsigned. Можете отнять 0 - 0xFFFF получите результат 1.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:48 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 705
2dev они и называют прерывания потому что выполнение программы прерывается, регистры заносятся в стек, выполняется подпрограмма прерывания, после чего регистры восстанавливаются из стека и продолжается выполнение прерванной программы. К тому же прерывания можно запрещать, если очень надо. Но в данном случае не вижу нужды.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:48 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5358
void1509 писал(а):
2Axill и в чем проблема - тип объявлен unsigned. Можете отнять 0 - 0xFFFF получите результат 1.


завожу буфер на 8 байт, заталкиваю туда один за другим байты и тут же вынимаю
на 9-й итерации tail будет равен 8, на 1000й итерации будет равен 1000, на 65535й будет равен 0
тоесть когда я в 65535й раз выну из буфера данные хвост станет указывать не на начало буфера, а не на его нулевой элемент
так же как и head через 65535е запихивание будет указывать на 0й элемент буфера, а вовсе не на первый свободный для записи


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:51 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3459
axill писал(а):
turnon писал(а):
Вот простая, красивая, портабельная реализация кольцевого буфера - http://kargs.net/code/fifo.c


каким образом ограничен выход хвоста за пределы буфера?

размер буфера - только степень двойки, соответственно остатку от деления переполнение через 8 или 16 степень двух никак не мешает.
но блин это онанизм какой-то, что с масками, а особенно с остатком от деления.
неужели целый сэкономленный такт ну может два по сравнению if (++tail >= size) tail = 0 того стоит?

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

Show fifo.h


Цитата:
axill
Например, он может вернуть наличие 231 байта, когда вы ждете наличие 16-ти при реальном наличии 5-ти, тем самым побуждая вас начать некоректное чтение...

в случае с восьмибитными МК и размерами буфера <256, не может.
восьмибитным МК буферы больше 256 обычно не нужны, там памяти столько нет, а >8 битные МК, переменные атомарно в память сохраняют, а не побайтно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:55 
Старожил
Аватара пользователя

Зарегистрирован: 06 ноя 2013, 16:07
Сообщения: 711
Откуда: Германия
void1509 писал(а):
2dev они и называют прерывания потому что выполнение программы прерывается, регистры заносятся в стек, выполняется подпрограмма прерывания, после чего регистры восстанавливаются из стека и продолжается выполнение прерванной программы. К тому же прерывания можно запрещать, если очень надо. Но в данном случае не вижу нужды.


См. выше в этом топике:
1. Основная программа грузит, к примеру, b->tail=0x00FF в регистры.
2. Инкрементирует: 0x0100.
3. Начинает писать назад в память, например сначала второй байт. В памяти b->tail=0x0000.
4. Прерывание. Читает из памяти b->tail=0x0000, пытается интерпретировать.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:58 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 705
не вижу проблемы. длина 8, таил 8, остаток от деления 8 на 8 будет 0 именно это и будет индекс в буфере. на 65536 итерации таил станет 0, остаток от деления 0 на 8 будет 0 и 65536 / 8 остаток будет 0 в чем проблема ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 01:58 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5358
_pv писал(а):
ну и городить кольцевой буфер макросами это тоже за гранью, в то время когда космические корабли бороздят ...

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 02:04 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 705
2dev если вы изменяете таил и в основной программе и в прерывании то можно на момент изменения запретить прерывания. Хотя подобного происходить не должно - прерывание меняет хеад, программа таил.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 02:10 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5358
void1509 писал(а):
не вижу проблемы. длина 8, таил 8, остаток от деления 8 на 8 будет 0 именно это и будет индекс в буфере. на 65536 итерации таил станет 0, остаток от деления 0 на 8 будет 0 и 65536 / 8 остаток будет 0 в чем проблема ?

ну да, не тот пример с размером 8
а с размером массива 9 будет ошибка
не вижу в описании этой библиотеки ничего про то, что размер должен быть степенью двойки


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 02:19 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 705
Этот метод они используют для размера буфера 64 байта, хотя я бы воспользовался маской - это просто быстрей по быстродействию, команда AND всяко быстрее чем остаток от деления считать. В остальном будет работать как часы, главное чтобы буфер размером кратном степени 2-оки


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 02:39 
Старожил

Зарегистрирован: 27 мар 2015, 01:22
Сообщения: 1951
aamonster писал(а):
vt340, путь хорош, но сейчас мы произнесём сакральную аббревиатуру из двух букв и призовём в тред Сами Знаете Кого :-)

Судя по четырём страницам, предлагаю аббревиатуру АД - Атомарный Доступ - тоже считать сакральной )

_________________
mcu.goodboard.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 02:49 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Товарищи... А нужно ли так извращаться и ограничивать буфер степенью двойки, чтобы выгодать два такта на нетак уж часто происходящем событии? UART - достаточно редко происходит.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 02:58 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 705
подобный подход позволяет сильно упростить расчет заполнения буфера (хеад - таил), а если буфер допустим 10 байт то немного усложняется контроль заполнения.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 03:05 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Не так уж сильно...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 04:10 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 2079
Если стоит head++ или tail++ без запрещения прерываний уже неправильно будет работать.
А если
buffer[head++] то и данные будут некорректные


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 10:34 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1127
Откуда: Германия
Mirmik писал(а):
Товарищи... А нужно ли так извращаться и ограничивать буфер степенью двойки, чтобы выгодать два такта на нетак уж часто происходящем событии? UART - достаточно редко происходит.

Это просто так кажется ;-) Все зависит от скорости. Например - делал тут железку, которая с 4х уартов собирает данные и на 5й отдает, и в другую сторону. Так вот - из-за количества уартов DMA каналов не хватило на все, один остался без, и как раз тот, который должен быть ооочень шустрым - около 1 Мбод. И на прерываниях. А объем данных довольно большой - каждые 100 мс по 4 КБ прокачивать.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 11:22 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 2079
Степень двойки не сильное ограничение, да и всё равно выравнивание займет эти байты до 4.
А если посмотреть в код, то можно еще оптимизацию навести.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 11:32 
Старожил
Аватара пользователя

Зарегистрирован: 06 ноя 2013, 16:07
Сообщения: 711
Откуда: Германия
void1509 писал(а):
2dev если вы изменяете таил и в основной программе и в прерывании то можно на момент изменения запретить прерывания. Хотя подобного происходить не должно - прерывание меняет хеад, программа таил.


Я его не изменяю в основной программе и в прерывании. Я его изменяю в одном месте и читаю в другом. При неблагоприятных условиях он читается некорректно. В данном случая нет никакой необходимости в запрете прерываний.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 04 май 2016, 19:37 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 2079
Это обычно называется mutex


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 05 май 2016, 00:22 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2795
Откуда: Санкт-Петербург
На мк всё же обстановка попроще, чем под виндой/макос/линухом: нет многопроцессорности, а в большинстве программ даже нет тредов - только прерывания. И если нет вложенных прерываний (которые тоже ещё умудриться сотворить надо) - то прерваться может только главный поток. Итого защищаться от чего-то надо только в нём.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Циклический(кольцевой) буфер.
СообщениеДобавлено: 10 май 2016, 15:06 
Заглядывает иногда

Зарегистрирован: 18 окт 2014, 00:39
Сообщения: 145
axill писал(а):
не вижу в описании этой библиотеки ничего про то, что размер должен быть степенью двойки


В примере использования есть:

/* note: must be a power of two! */
#define fifo_buffer_SIZE 64


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 05 июн 2016, 03:22 
Только пришел

Зарегистрирован: 29 янв 2015, 11:55
Сообщения: 13
Откуда: Москва
Сегодня прикрутил.
http://we.easyelectronics.ru/Soft/kolce ... ya-mk.html
Отлично выглядит atmega8


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 98 ]  На страницу Пред.  1, 2, 3, 4


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB