Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Динамично оразмеряване на буфер
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=16344
Страница 1 от 2

Автор:  stoyanoff [ Нед Фев 03, 2019 7:25 pm ]
Заглавие:  Динамично оразмеряване на буфер

Здравейте! Имам заделена някаква памет за даден порт. Примерно 40к. В най-простия случай трябва да направя нещо такова:
Код:
unsigned char incomeBuff[20k];
unsigned char outcomeBuff[20k];

Проблемът е, че това е крайно не ефективно. Ако входният поток се състои само от кратки съобщения примерно по 100 байта, няма смисъл от тези 20к и би било полезно да ги прехвърля към изходния буфер. И обратно.
Това, което съм виждал, е да се заделя просто един общ буфер, както в случая 40к и всеки процес да си пълни самосиндикално. Въпросът е как да го реализирам, защото единият ми буфер се пълни от UART. Сиреч в прекъсване!
Може ли да споделите опит?
Благодаря!

Автор:  TheWizard [ Нед Фев 03, 2019 7:47 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

нещо нищо не разбрах
за RX-а може RingBuffer

Автор:  syscop [ Нед Фев 03, 2019 7:54 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Не е ли по-добре да имаш сравнително равни по дължина съобщения? Ще може по-лесно да си планираш разхода на памет. Иначе винаги може да ползваш malloc/free.

Автор:  stoyanoff [ Нед Фев 03, 2019 7:55 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Аз ринга съм го направил. За друго говоря. С прости думи - искам да съхранявам двата потока(входен и изходен) в един буфер, като всеки поток си заема толкова място, колкото му трябва. Примерно единият пълни от клетка 0 към клетка n, а другият поток пълни от n към 0. И ако единият поток има моментна нужда от повече място да може да използва пълноценно цялата памет, а не да е ограничен до половината налично място, както в примера горе(само 20к от 40к).

ПП: Не става! У-вото ми е пасивно и тези неща ги решава потребителя. В случаите в които го използваме масово, единият буфер е по-голям от другия, защото входните съобщения са много по-кратки от изходните. Обаче така не е особено ефективно. На практика ако се промени дължината на съобщенията трябва да се оразмерят на ново буферите. Искам да е нещо универсално...

Автор:  TheWizard [ Нед Фев 03, 2019 8:16 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

heap - malloc - free
queue

винаги ли са подредени RX-TX, RX-TX, RX-TX

Автор:  slav4o.com [ Нед Фев 03, 2019 8:50 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Ами декларирай си един голям масив. Това ти е паметта. Вече на твоите функции които я ползват задаваш откъде до къде вътре в масива да цикли (ако е кръгов буфер). Дали с указатели дали с индекси от масива - имаш 2 променливи индекс начало и индекс край за всеки буфер. Тези променливи може да ги... променяш динамично. Съответно, мисля е ясно, разликата ти определя дължината. Кога и как ще ги сменяш, ти си знаеш.
п.п. ебаси PIC-а 40 килобайта рам 8O

Автор:  stoyanoff [ Нед Фев 03, 2019 9:21 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

TheWizard написа:
винаги ли са подредени RX-TX, RX-TX, RX-TX

Не!
ПП: Ами всъщност има 256к, но съм го разделил на 6 порта х40к

Автор:  gicho [ Нед Фев 03, 2019 10:19 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Ама вЕрно ли трябва да държиш всичкото накуп? Какви са данните, толкова ли не могат да се обработват преди да е дошъл целия пакет?
Те джъмбо фреймовете на гигабита са по 10К, ти 40К фрейм 8O Това през какво влиза/излиза при теб - етернет, сериен, SPI, ...?

Автор:  slav4o.com [ Нед Фев 03, 2019 10:23 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Ами една идея/съвет: по принцип не зная дали ти е критично предаването. Ако не е то може да използваш само един буфер за предаване. Ако за приемане трябва да си в готовност, то за предаване е достатъчно един, няма закъде да бързаш, почистваш си къщиката и започваш да предаваш.

Автор:  stoyanoff [ Пон Фев 04, 2019 9:14 am ]
Заглавие:  Re: Динамично оразмеряване на буфер

Реших да оставя този проблем на потребителя, като му дам да си настойва размера на входния и изходния буфер. Тук идва въпросът как се прави това.
Wizard, как да заделям място в рамта спрямо променлива, която се чете от EEPROM?

Автор:  bobihot [ Пон Фев 04, 2019 11:23 am ]
Заглавие:  Re: Динамично оразмеряване на буфер

Когато аз си ги организирам- изходните фреймове са блокове с дължината на данните, които изпращам. Преди това са напълнени да речем с данни от АЦП. Като са готови и пакетирани да речем с СРЦ, ги подавам към подпрограмката за изпращане, която наглася адресите за ТХ буфера и брояча- дължината му. Така не заделям допълнителна памет и не прехвърлям данни от буфер в буфер. Като прочета байт- го проверявам, дали е начало/част активна команда/данни и тогава го слагам във входен буфер. Като е готов-потвърден входният блок, че е готов, го пращам за обработка. Така приети данни да ги държа някъде си- само ако дуиното да речем си пълни буфер и аз от време на време да го проверявам.

Автор:  gicho [ Пон Фев 04, 2019 12:02 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Заделянето динамично (runtime) се прави с някакъв алокатор - в стандартната библиотека това е malloc функцията. Тя очаква някъде из линкер скриптовете да има обявена област наречена heap (често е от последния използвам адрес до края на рам-та, така хем се ползва всичката неизползвана памет, хем автоматично се мести началото според какво си напълнил от статични).
Реално си е проблемът от началото на топика - да имаш един общ голям буфер (в случая това става heap-а) и да можеш да искаш от него парчета. Твоето беше по-специфично понеже говореше за две парчета и движението им едно към друго - можеш да си го реализираш.
Иначе има доста готови имплементации на heap, т.е. алокатори. Във freertos има няколко и се избират, можеш да имаш и повече от един. Разгледай ги и ако искаш зачети какви са проблемите, до които се стига при ползване на динамична памет.
Това което bobihot казва е по-смисленото и затова те питах що държиш такива големи пакети - докато обработваш идващия стрийм сваляш някаква опаковка протоколна, при което можеш да си трупаш стейт някакъв (на хедър съм, в данните съм, на 50-ти байт от данните съм, на чексума в края съм). А когато си в специфичния "идват данни" можеш (и трябва) да ги консумираш веднага вместо да чакаш.

Автор:  slav4o.com [ Пон Фев 04, 2019 12:48 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

Съвсем ще го закопаете човека с тези алоци и малоци.
Паметта си я заделя много лесно:
char memory[240k];
От тук нататък въпроса е как ще работи с нея:
Код:
#define UART1RxLen = 10 000; // примерно 10 килобайта
#define UART2RxLen = 15 625; // примерно 15 килобайта
............
#define UARTnRxLen = xxxxxx; // някакви си килобайти
#define UARTTxLen = 9000; // примерно 9 килобайта

unsigned long UART1RxStart = 0; //
unsigned long UART1RxEnd = UART1RxStart + UART1RxLen - 1;
unsigned long UART2RxStart = UART1RxEnd + 1;
unsigned long UART2RxEnd = UART2RxStart + UART2RxLen - 1;
......................
unsigned long UARTTxStart = UARTnRxEnd + 1;
unsigned long UARTTxEnd = UARTTxStart + UARTTxLen - 1;

Това са индексите. Разбира се когато се сменят размерите на буферите UARTnRxLen трябва да са променливи а другите индекси трябва да се преизчислят. Например в някаква функция.

Автор:  TheWizard [ Пон Фев 04, 2019 1:19 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

явно нямаш ОС
нямам си на идея защо обединяваш всички UART буфери в един HEAP
предполагам, че в RX-а получаваш данни в прекъсването и искаш да обработваш данните извън прекъсването

Автор:  gicho [ Пон Фев 04, 2019 1:23 pm ]
Заглавие:  Re: Динамично оразмеряване на буфер

@slavcho: Не че нещо, ама човекОт говореше за динамично (след изчитане от еепром) оразмеряване, но явно говориш примерно.
И да, същото става и с malloc, и да, има овърхед, има и капани покрай ползването. За тия цели има други имплементации (pool примерно) има различни подходи за организиране на heap-а, има и подходи с zero copy (@bobicat подхода, scatter-gather).
Интересен вариант може да се види в LwIP - там се вижда как се процедира когато има предварително информация за MTU на данните.

Страница 1 от 2 Часовете са според зоната UTC + 1 час [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/