Прошу подсказать по коду

VeD
Offline
Зарегистрирован: 21.02.2016

читал про цикличный буфер, где в примере был код

#define BUF_SIZE 128
#define BUF_MASK (BUF_SIZE-1)
#define IN_BUF_SIZE 64
#define IN_BUF_MASK (IN_BUF_SIZE-1)

volatile char buffer[BUF_SIZE]="";
volatile char inbuf[IN_BUF_SIZE]="$"; //inner buffer of USART
volatile uint8_t ind_in=0, ind_out=0, rxind_out=0, rxind_in=0, mess = 0;

Запись строк или отдельных символов в буфер производилась обычными функциями:

//sending RS232 with interupt
void SendByte(char byte)
        {
        buffer[ind_in++] = byte;
        ind_in &= BUF_MASK;
        }

void SendStr(char *string)
        {
        while (*string!='\n')  //check if End
                {
                SendByte(*string);
                string++;
                }
        }

Вот мне не ясна строка 

ind_in &= BUF_MASK;

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

я думаю что если ind_in  станет равен,  BUF_MASK, то что-то произойдет, но что произойдет не написано. Даже цикла нет никакого. Я просто не пойму какая миссия у данной строчки. Желательно в нормальном объяснении. 

 

b707
Offline
Зарегистрирован: 26.05.2017

VeD пишет:

я думаю что если ind_in  станет равен,  BUF_MASK, то что-то произойдет, но что произойдет не написано.

А если немного полумать? Если у нас есть буфер размером BUF_MASK+1 - то что должно произойти, когда индекс приблизится к BUF_MASK - особенно если вспомнить. что буфер у нас ЦИКЛИЧЕСКИЙ?

VeD
Offline
Зарегистрирован: 21.02.2016

ну например достигла переменная  ind_in  значения BUF_MASK,  это означает что массив( он же буфер) buffer[ind_in++] заполнился. и что дальше то? я и без этого кода знаю, что массив имеет длину в 64 символа. что-то тут ни так. точнее что-то я не не правильно понял.

b707
Offline
Зарегистрирован: 26.05.2017

VeD - а вы вообще в курсе, как работает кольцевой буфер? - что отличает кольцевой от любого другого? - похоже что нет.

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

VeD
Offline
Зарегистрирован: 21.02.2016

сейчас нашел такое "Теперь становится понятным, почему при размере буфера 256 байт и байтовом индексе не нужна операция наложения маски - переход в ноль индекса при достижении конца буфера происходит автоматически." значит код нужен чтоб очистить буфер? если так, то как это происходит?

64 в двоичном виде это 00111111, если ind_in  тоже будет равна 00111111 то вывод будет такой же. данные все равно будут поступать в буфер, но это будет переполнение массива. как этот код обнуляет, мне не ясно.

VeD
Offline
Зарегистрирован: 21.02.2016

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

b707
Offline
Зарегистрирован: 26.05.2017

VeD пишет:

значит код нужен чтоб очистить буфер? если так, то как это происходит?

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

Цитата:
64 в двоичном виде это 00111111, если ind_in  тоже будет равна 00111111 то вывод будет такой же.

64 в двоичном коде не 00111111 , и ind_in никогда не бывает равен 64 - из этих двух ошибок совсем неверный результат

b707
Offline
Зарегистрирован: 26.05.2017

VeD пишет:

 типа старые данные затираются новыми. как я понял. 

так и есть. и что непонятно?

VeD
Offline
Зарегистрирован: 21.02.2016

туплю на простых вещах вроде. смешно конечно. но факт есть факт

VeD
Offline
Зарегистрирован: 21.02.2016

так я говорю. не понятен принцип работы той маски

b707
Offline
Зарегистрирован: 26.05.2017

VeD пишет:

туплю на простых вещах вроде. смешно конечно. но факт есть факт

если вы понимаете, что означает (арифметически) указанная строчка - попробуйте рассчитать результат при разных значениях in_ind - менее 64, 64 и более 64

только акууратнее с двоичными данными, а то вы там 64 в двоичном коде неправильно посчитали

negavoid
Offline
Зарегистрирован: 09.07.2016

Так он и не понимает )) а рисовать единички и нолики видимо всем лениво :)

Это такой хитрожопый (на самом деле нет, но для новичков - да) приём, чтобы обнулить указатель кольцевого буфера.

ind_in &= BUF_MASK;

эту строчку можно прочитать, как вот такой вот оператор И:

ind_in = ind_in & BUF_MASK;

Соответственно, когда ind_in подходит к концу размера буфера, она обнуляется, и следующая запись будет в buffer[0].

PS там ещё есть char byte - переменная с именем типа, кто-то применяет патроны калибра, как у Кобэйна :)

VeD
Offline
Зарегистрирован: 21.02.2016

как я понял. 64 в двоичном 10000000 63 в двоичном 00111111 в итоге 10000000 & 00111111=0000000 если б=массив достигнет заполненности, или как там, то он обнулится

VeD
Offline
Зарегистрирован: 21.02.2016

да все теперь понятно. мне нужно было суть показать, на пальцах так сказать. 

VeD
Offline
Зарегистрирован: 21.02.2016

благодарю вас за объяснения

b707
Offline
Зарегистрирован: 26.05.2017

VeD пишет:

массив достигнет заполненности, или как там, то он обнулится

вы снова путаете массив и его индекс - а это крайне важно. Индекс обнулится, ИНДЕКС! - а массив не обнуляется, в нем могут быть актуальные данные.

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

b707
Offline
Зарегистрирован: 26.05.2017

пример, записываем строчку "raketa" при начальном значении in_ind = 62

Строчка запишется так:

buf[62] = 'r';
buf[63] = 'a';
// тут in_ind & BUF_MASK станет равным нулю
buf[0] = 'k';
buf[1] = 'e';
buf[2] = 't';
buf[3] = 'a';

 

VeD
Offline
Зарегистрирован: 21.02.2016

точно, переменная ind_in же обнулится.  запись пойдет уже в нулевой индекс. 00000001 & 001111111 b  и будет двигаться так дальше. потом в первый, во второй и так до 63. или до 64 ? хотя это уже не важно. главное, что теперь я понял суть. Пока с кем-нибудь не поговоришь, ничего не поймешь. это про меня.

VeD
Offline
Зарегистрирован: 21.02.2016

как оказалось. все так просто. чувствую себя идиотом. который не может закрыть крышку на бутылке :)