<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Работа с кольцевым буфером</title>
		<description>Обсуждение Работа с кольцевым буфером</description>
		<link>https://microsin.ru/programming/avr/ring-buffer.html</link>
		<lastBuildDate>Sat, 13 Jun 2026 18:19:28 +0300</lastBuildDate>
		<generator>JComments</generator>
		<atom:link href="https://microsin.ru/component/option,com_jcomments/format,raw/limit,10/object_group,com_content/object_id,1098/task,rss/" rel="self" type="application/rss+xml" />
		<item>
			<title>StF написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-7777</link>
			<description><![CDATA[Рассмотрим буфер на 512 1-байтовых элементов . Пусть хвост =11 (позиция откуда читаем), голова =1 (позиция куда пишем). Очевидно что в этом случае количество элементов в буфере будет: (голова-хвост) &511 =502 элемента. При обратной ситуации (хвост=1, голова=11) (11-1)& 511 =10 элементов. Что лучше подходит чем формула в статье с маркировкой UPD100920. Можно избежать пересечения индексов начала и конца при записи, проверяя заполненность буфера перед записью по условию: (голова-хвост)% (размер-1) == sizeof(буфер)-1. Т. е. если хвост на 0, голова на 511,исходя из алгоритма записи в статье - в буфере 511 байт. Таким способом мы жертвуем 1 байтом при сравнении выше, но избегаем ситуации пересечения головы и хвоста при записи.]]></description>
			<dc:creator>StF</dc:creator>
			<pubDate>Tue, 09 Oct 2018 15:08:53 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-7777</guid>
		</item>
		<item>
			<title>Tonal написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-6547</link>
			<description><![CDATA[Различить ситуации, когда буфер пуст и полон при idxIN==idxOUT, можно простым и элегантным способом. Нужно использовать индексы буфера вдвое большего размера, и все. Для удобства в примере заменил прединкремент постинкрементом . #define BUF_MASK0 (BUF_SIZE-1) #define BUF_MASK1 (2*BUF_SIZE-1) buffer[idxIN & BUF_MASK0] = value; idxIN++ &= BUF_MASK1; value = buffer[idxOUT & BUF_MASK0]; idxOUT++ &= BUF_MASK1; функция idxDiff вернет правильное значение при полном буфере.]]></description>
			<dc:creator>Tonal</dc:creator>
			<pubDate>Mon, 18 Jun 2018 04:20:31 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-6547</guid>
		</item>
		<item>
			<title>Vatslav написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-5359</link>
			<description><![CDATA[Давайте разделять тип применяемого буфера и методы определения достоверности сообщений. Переполнить можно ЛЮБОЙ буфер. Это никак не меняет его принцип. Если писать в быстрее, чем читать - проблема не в типе буфера, а в некорректном проектировании протокола обмена, или недостаточной скорости обработки. В конкретной ситуации, когда буфер заполнен и сейчас, вот, должны сравняться хвост и голова - я ввожу проверку перед записью. Если в протоколе предусмотрена работа с коллизиями - производитель данных получит ошибку на последний отосланный пакет. Как он дальше будет с этим жить - не относится к типу буфера вообще. от слова совсем. P.S. Можете применить шину CAN и забирать сообщения только тогда, когда буфер способен их проглотить. Всё остальное CAN сделает за вас на аппаратном уровне. он будет обрабатывать ошибку переполнения буфера драйвера и долбить сообщение аж пока не передаст его.]]></description>
			<dc:creator>Vatslav</dc:creator>
			<pubDate>Fri, 17 Nov 2017 13:27:04 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-5359</guid>
		</item>
		<item>
			<title>ivanr написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-2779</link>
			<description><![CDATA[Ситуация, когда буфер кольцевой буфер заполнен полностью никак не отличается от ситуации, когда он пуст, следовательно не будет работать, если читать медленнее, чем писать, собственно об этом Вы уже написали. Вопрос в том, как сделать, чтобы ситуации различались? Придется вводить флаги и при каждой записи и чтении сперва проверять флаги, потом выставлять? microsin: достоинство кольцевого буфера именно в его простоте и скорости. Единственное условие, которое нужно выполнить, чтобы такой буфер работал - не допускать его переполнения, т. е. делать выборку значений быстрее, чем значения записываются в буфер. Если нужно что-то кроме этого функционала, то это уже не будет кольцевой буфер, а что-то другое (FIFO, стек, очередь и т. д.), что не имеет смысла здесь обсуждать.]]></description>
			<dc:creator>ivanr</dc:creator>
			<pubDate>Sun, 17 May 2015 20:31:25 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-2779</guid>
		</item>
		<item>
			<title>Игорь написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-2180</link>
			<description><![CDATA[А если 256 ячеек мало, и нужно индексы использовать 2-х байтовые, то тогда как будет выглядеть организация такого буфера? microsin: абсолютно так же, на принцип работы кольцевого буфера это никак не повлияет. Помните только, что выгоднее всего использовать для размера буфера число в степени N двойки (размер буфера = 2^N). Для организации закольцовывания индекса при инкременте достаточно накладывать на индекс маску, равную (2^N)-1.]]></description>
			<dc:creator>Игорь</dc:creator>
			<pubDate>Sat, 31 May 2014 19:56:54 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-2180</guid>
		</item>
		<item>
			<title>a791 написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-1654</link>
			<description><![CDATA[ Совсем забыть? И для индексов volatile не нужно?]]></description>
			<dc:creator>a791</dc:creator>
			<pubDate>Wed, 21 Mar 2012 17:04:38 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-1654</guid>
		</item>
		<item>
			<title>kek написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-1470</link>
			<description><![CDATA[Не совсем верно. Кольцевой буфер используется в классической задаче "производителя"-"потребителя" (см. например здесь: http://www.cs.mtu.edu/~shene/NSF-3/e-Book/MONITOR/ProducerConsumer-1/MON-example-buffer-1.html). При переполнении буфера производитель должен быть заблокирован, разблокироватьс я он может по сигналу от потребителя, когда последний извлечет данные из буфера. Недостоверными данные буфера при переполнении и последующем прекращении заполнения станут только в одном случае: если буфер обязан содержать чисто реалтаймовые данные: скажем, измерения за BUF_SIZE моментов времени вплоть до текущего момента. Но тогда задача еще проще: можно иметь один индекс для записи и считывать весь буфер целиком при необходимости обработки. Индекс записи в таком случае покажет границу между самыми новыми и самыми старыми данными. microsin: при обмене с квитированием, т. е. с блокировкой/разблокировкой передатчика данных (с управлением потоком данных от потребителя) кольцевой буфер может быть не нужен, так как всегда гарантируется, что приемник готов принять данные в нужное время. Повторяю еще раз, на всякий случай - в этой статье подобная ситуация с блокировкой/разблокировкой передатчика данных - НЕ РАССМАТРИВАЕТСЯ .]]></description>
			<dc:creator>kek</dc:creator>
			<pubDate>Fri, 02 Sep 2011 15:58:24 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-1470</guid>
		</item>
		<item>
			<title>kek написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-1469</link>
			<description><![CDATA[Если буфер заполнится до конца, то индексы idxIN и idxOUT сравняются. И тогда функция idxDiff() вернет не BUF_SIZE, а 0. Не говоря уже о том, что u8 idxDiff (u8 idxIN, u8 idxOUT) в принципе не может вернуть BUF_SIZE, равный 256... То же самое относится и к фразе "Если догнал - значит, считывать из буфера больше нечего". На самом деле, или нечего, или буфер заполнен до конца. Если принять за постулат, что буфер опустошается всегда быстрее, чем заполняется, то это не важно. Но что если что-то пойдет не так, как мы предполагаем? Скажем, потеряна связь с потребителем данных, символы не извлекаются из кольца, а производитель продолжает писать данные: средств для идентификации переполнения ведь нет в принципе! За границу мы, конечно, не выйдем, но вот последовательно сть чтения накопленных данных будет искажена. microsin: Вы во всем правы, и об этом в статье явно не пишется только потому, что буфер КОЛЬЦЕВОЙ, и если запись в буфер будет идти быстрее чтения, то буфер переполнится, и данные в нем будут недостоверны. В этом случае не только нельзя применить кольцевой буфер, но и невозможно синхронизироват ь процессы по передаваемым данным, если не отбрасывать пакеты. Описание такого поведения программы выходит за рамки статьи, статья только про принцип работы с КОЛЬЦЕВЫМ БУФЕРОМ. Повторяю снова - говорить о кольцевом буфере, когда скорость входящего потока данных превышает скорость исходящего - совершенно бессмысленно.]]></description>
			<dc:creator>kek</dc:creator>
			<pubDate>Fri, 02 Sep 2011 15:10:06 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-1469</guid>
		</item>
		<item>
			<title>10199 написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-1096</link>
			<description><![CDATA[Ранее придумал нечто похожее на Ваш пример, только у меня было 2 строки char и два указателя. Один указывал на строку приема, второй - на строку, которую надо обработать. После некоторой возни с синхронизацией этих потоков все работало достаточно шустро :) microsin: вся прелесть кольцевого буфера в том, что про синхронизацию можно вообще забыть, как про страшный сон. При работе с кольцевым буфером нужно только соблюсти два условия - средняя скорость записи в буфер должна быть меньше средней скорости чтения из него, и размер буфера должен быть достаточно большим для того, чтобы не терялись записываемые за один раз (до операции чтения) данные.]]></description>
			<dc:creator>10199</dc:creator>
			<pubDate>Tue, 22 Feb 2011 16:50:38 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-1096</guid>
		</item>
		<item>
			<title>AlexQt написал:</title>
			<link>https://microsin.ru/programming/avr/ring-buffer.html#comment-848</link>
			<description><![CDATA[Как лучше контролировать корректность записываемых данных, то есть случай, когда записывается больше данных, чем осталось места в буфере. microsin: никак, потому что кольцевой буфер не предназначен для такого случая. Использование кольцевого буфера автоматически подразумевает условие, что СРЕДНЯЯ скорость записи в кольцевой буфер ВСЕГДА МЕНЬШЕ СРЕДНЕЙ скорости чтения из кольцевого буфера.]]></description>
			<dc:creator>AlexQt</dc:creator>
			<pubDate>Wed, 03 Nov 2010 16:27:43 +0300</pubDate>
			<guid>https://microsin.ru/programming/avr/ring-buffer.html#comment-848</guid>
		</item>
	</channel>
</rss>
