Прошу подсказать по коду
- Войдите на сайт для отправки комментариев
Пнд, 28/10/2019 - 15:47
читал про цикличный буфер, где в примере был код
#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, то что-то произойдет, но что произойдет не написано. Даже цикла нет никакого. Я просто не пойму какая миссия у данной строчки. Желательно в нормальном объяснении.
я думаю что если ind_in станет равен, BUF_MASK, то что-то произойдет, но что произойдет не написано.
А если немного полумать? Если у нас есть буфер размером BUF_MASK+1 - то что должно произойти, когда индекс приблизится к BUF_MASK - особенно если вспомнить. что буфер у нас ЦИКЛИЧЕСКИЙ?
ну например достигла переменная ind_in значения BUF_MASK, это означает что массив( он же буфер) buffer[ind_in++] заполнился. и что дальше то? я и без этого кода знаю, что массив имеет длину в 64 символа. что-то тут ни так. точнее что-то я не не правильно понял.
VeD - а вы вообще в курсе, как работает кольцевой буфер? - что отличает кольцевой от любого другого? - похоже что нет.
Когда индекс такого буфера доходит до BUF_MASK - это вовсе не означет, что он заполнился, это всего лишь значит, что следующая запись в буфер пойдет с позиции 0. А буфер при этом может содержать всего пару байтов. а может и вовсе быть пустым.
сейчас нашел такое "Теперь становится понятным, почему при размере буфера 256 байт и байтовом индексе не нужна операция наложения маски - переход в ноль индекса при достижении конца буфера происходит автоматически." значит код нужен чтоб очистить буфер? если так, то как это происходит?
64 в двоичном виде это 00111111, если ind_in тоже будет равна 00111111 то вывод будет такой же. данные все равно будут поступать в буфер, но это будет переполнение массива. как этот код обнуляет, мне не ясно.
да особо то инфы про это нету. чтоб понятно было. прочитал что это как стек, первый пришел, первый вышел. типа старые данные затираются новыми. как я понял.
значит код нужен чтоб очистить буфер? если так, то как это происходит?
нет, код не для этого, буфер никто не чистит. да и зачем? - у нас есть указатель на актуальные данные в буфере - тот самый индекс, и еще длина данных в буфере (не путать с длиной буфера), а что там в остальном буфере - не имеет значение.
64 в двоичном коде не 00111111 , и ind_in никогда не бывает равен 64 - из этих двух ошибок совсем неверный результат
типа старые данные затираются новыми. как я понял.
так и есть. и что непонятно?
туплю на простых вещах вроде. смешно конечно. но факт есть факт
так я говорю. не понятен принцип работы той маски
туплю на простых вещах вроде. смешно конечно. но факт есть факт
если вы понимаете, что означает (арифметически) указанная строчка - попробуйте рассчитать результат при разных значениях in_ind - менее 64, 64 и более 64
только акууратнее с двоичными данными, а то вы там 64 в двоичном коде неправильно посчитали
Так он и не понимает )) а рисовать единички и нолики видимо всем лениво :)
Это такой хитрожопый (на самом деле нет, но для новичков - да) приём, чтобы обнулить указатель кольцевого буфера.
эту строчку можно прочитать, как вот такой вот оператор И:
Соответственно, когда ind_in подходит к концу размера буфера, она обнуляется, и следующая запись будет в buffer[0].
PS там ещё есть char byte - переменная с именем типа, кто-то применяет патроны калибра, как у Кобэйна :)
как я понял. 64 в двоичном 10000000 63 в двоичном 00111111 в итоге 10000000 & 00111111=0000000 если б=массив достигнет заполненности, или как там, то он обнулится
да все теперь понятно. мне нужно было суть показать, на пальцах так сказать.
благодарю вас за объяснения
массив достигнет заполненности, или как там, то он обнулится
вы снова путаете массив и его индекс - а это крайне важно. Индекс обнулится, ИНДЕКС! - а массив не обнуляется, в нем могут быть актуальные данные.
Весь смысл этого "хитрожопого приема", как сказал коллега - именно в том чтобы массив никогда не заполнялся и его не надо было бы чистить - а только писать и писать.
пример, записываем строчку "raketa" при начальном значении in_ind = 62
Строчка запишется так:
точно, переменная ind_in же обнулится. запись пойдет уже в нулевой индекс. 00000001 & 001111111 b и будет двигаться так дальше. потом в первый, во второй и так до 63. или до 64 ? хотя это уже не важно. главное, что теперь я понял суть. Пока с кем-нибудь не поговоришь, ничего не поймешь. это про меня.
как оказалось. все так просто. чувствую себя идиотом. который не может закрыть крышку на бутылке :)