Отговори на тема  [ 15 мнения ] 
Реализация на опашка 
Автор Съобщение
Ранг: Напреднал
Ранг: Напреднал
Аватар

Регистриран на: Нед Сеп 17, 2006 12:00 pm
Мнения: 450
Местоположение: Plovdiv
Мнение Реализация на опашка
Здравейте, как се реализира списък тип опашка на асемблер за ПИК? Интересува ме идеята само, аз мисля така да стане: организирам си един масив и две променливи за начало и край, където съответно ще се чете и записва. Проблемът, обаче е, че опашката постепенно ще се "движи" към единия край. Може да се направи да бъде цикличен списъка, т.е, чрез делене по модул да се връща края на опашката обратно в началото на масива, така ли се прави по принцип?


Пет Юли 06, 2007 12:16 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пон Дек 12, 2005 6:03 pm
Мнения: 263
Местоположение: София
Мнение 
Аз скоро правих подобно нещо. Отделих си 32 байта памет. Една променлива пойнтер за писане, една за четене. В irq се пише, в main прога се чете. Ако писането = четенето - main-а чака. Не е необходимо деление, защото се ползват 4 бита и с AND се маскират. Не съм следил за край на опашката (презаписване на стойност, която да не е изчетена) защото по тайминг е предвидено да не се случва.


Пет Юли 06, 2007 1:15 pm
Профил ICQ YIM
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Юни 05, 2006 1:48 pm
Мнения: 4906
Местоположение: където небето среща земята, ракията е Jameson, а бирата Guinness
Мнение Re: Реализация на опашка
MidNighT_SpiRiT написа:
Здравейте, как се реализира списък тип опашка на асемблер за ПИК? Интересува ме идеята само, аз мисля така да стане: организирам си един масив и две променливи за начало и край, където съответно ще се чете и записва. Проблемът, обаче е, че опашката постепенно ще се "движи" към единия край. Може да се направи да бъде цикличен списъка, т.е, чрез делене по модул да се връща края на опашката обратно в началото на масива, така ли се прави по принцип?

имаш в предвид кръгов буфер ли как се пише ? или друго?

_________________
... ако трети ден не ти се работи... това означава, че е сряда !


Пет Юли 06, 2007 2:07 pm
Профил
Ранг: Напреднал
Ранг: Напреднал
Аватар

Регистриран на: Нед Сеп 17, 2006 12:00 pm
Мнения: 450
Местоположение: Plovdiv
Мнение 
Да, кръгов буфер, защото не виждам друг начин как да реализирам опашката.
Интересно ми е дали има някакво елегантно решение.


Пет Юли 06, 2007 3:20 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пон Дек 12, 2005 6:03 pm
Мнения: 263
Местоположение: София
Мнение 
еми и аз за кръгов говоря. или нещо друго съм му сторил :)?


Пет Юли 06, 2007 3:28 pm
Профил ICQ YIM
Ранг: Напреднал
Ранг: Напреднал
Аватар

Регистриран на: Нед Сеп 17, 2006 12:00 pm
Мнения: 450
Местоположение: Plovdiv
Мнение 
Ще помисля върху твоята идея, мерси! :)


Пет Юли 06, 2007 8:48 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пет Юни 29, 2007 10:59 pm
Мнения: 113
Мнение Re: Реализация на опашка
MidNighT_SpiRiT написа:
Здравейте, как се реализира списък тип опашка на асемблер за ПИК? Интересува ме идеята само, аз мисля така да стане: организирам си един масив и две променливи за начало и край, където съответно ще се чете и записва. Проблемът, обаче е, че опашката постепенно ще се "движи" към единия край. Може да се направи да бъде цикличен списъка, т.е, чрез делене по модул да се връща края на опашката обратно в началото на масива, така ли се прави по принцип?


Ето ти обща схема на моята реализация. Имаш началния адрес на буфера в паметта. Две променливи, които наричам индекси и предствляват отместването от началото на буфера съответно при четене и при запис в буфера. Допълнително една променлива, наричам я брояч и представлява броя на наличните байтове в буфера. Когато правя PUSH в буфера вземам указателя за начало на буфера + индекса за запис и на получения адрес записвам байта, инкрементирам брояча и индекса и правя проверка дали индекса не е надхвърлил стойност по-голяма от дължината на буфера. Един трик вместо тази проверка: ако например дължината на буфера си определил да е 64 (0х40) просто можеш да направиш AND на Index с (дължина на буфер -1) или Index AND 0x3F. Ясно ти е, че когато Index стане над 63 след това действие отново е нула. Съответно когато правиш POP - четеш съдържанието на (начало на буфер + индекс за четене) инкремент на индекса за четене, декремент на общия брояч и отново трика с индекса. Разбира се при PUSH правиш проверка на брояча дали не е достигнал стойност дължина на буфера (трик:например в случая Counter AND 0xC0 ти дава ZF=0 ако брояча е 64 или по-голям), съответно при POP проверяваш дали брояча е 0, за да не се получи съответно препълване или препразване. Брояча съм го сложил защото често проверявам има ли наличност в буфера и така е по-лесно и по-бързо.

Едно уточнение: Ясно е, че ако дължината на буфера не е равна на някоя степен на 2, тези трикове не работят и трябва да правиш по-дълги проверки.


Съб Юли 07, 2007 10:52 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
Още по-бързо решение е указателят да сочи директно адреса на клетката от масива, а не индекса му. Така се пропуска едно събиране.


Нед Юли 08, 2007 9:28 am
Профил ICQ
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пет Юни 29, 2007 10:59 pm
Мнения: 113
Мнение 
bateAz написа:
Още по-бързо решение е указателят да сочи директно адреса на клетката от масива, а не индекса му. Така се пропуска едно събиране.


Така е - пропуска се едно събиране, но се добавя според мен по-дълга процедура по проверка дали указателя не е достигнал края на опашката. Ще трябва да се направи поне едно изваждане и една проверка за по-малко, докато в моя случай имаш едно събиране и един AND. Или пък да извадиш поинтера с началото на буфера и с разликата да работиш както аз с индекса, но после пак трябва да събереш с началото на буфера. Освен ако нямаш нещо друго предвид си мисля, че твоя случай не е по-кратък. Ето в този пример си личи липсата на индексна адресация в PIC (поне доколкото имам спомен).

Поправка: За да бъда точен май в PIC18 вкараха някакви индексни указатели със специални инструкции имитиращи индексната адресация. Вярно, че беше някаква жалка история със сума ти цикли на инструкция, но вършеха работа. Само за сравнение MSP на TI на 8 MHz постига по-добра производителност ot PIC18 на 40 MHz. Едно че инструкциите му като цяло отнемат по-малко цикли, друго че 7-те вида адресация и 11-те регистъра с общо предназначение (акумулатори) предоставят по-голяма гъвкавост при писане на програмите. Разбира се да не забравяме, че единият е 8 битов а другия 16.


Нед Юли 08, 2007 11:38 am
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пет Фев 17, 2006 9:17 am
Мнения: 765
Местоположение: Стара Загора
Мнение 
Тука май бъркаш. В PIC18 няма да видиш по-дълги от 2 цикъла инструкциии. За MSP430 има и такива по 5-6 цикъла. Няма как да е по-производителен :? Колкото за опашката - явно все по един и същи начин се прави - оттама нататък е въпрос на техника и на вкус
Код:
struct _buf{
int8 buffer[800];
int8 *read,*write;
int16 cnt;
int8 flag;
} buf;
#define initBuf() buf.read=buf.write=buf.buffer;buf.cnt=0;buf.flag=0
#define Endbuf buf.buffer+sizeof(buf.buffer)
int8 readBuf(void){
int8 tmp;
tmp=*buf.read++;

if (buf.read>=Endbuf) buf.read=buf.buffer;
buf.cnt--;
return tmp

}

void writeBuf(int8 a){
if (buf.cnt>sizeof(buf.buffer)
    {buf.flag=1;return}
    *buf.write++=a;
    if (buf.write>=Endbuf) buf.write=buf.buffer;
    buf.cnt++;

}




Не много оптимално, но за сметка на това почти универсално.

edit: Така е в понеделник сутрин преди второто кафе... :oops:


Последна промяна setoy на Пон Юли 09, 2007 2:03 pm, променена общо 2 пъти



Пон Юли 09, 2007 9:37 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
setoy написа:
Код:

#define initBuf() buf.read=buf.read=buf.buffer;buf.cnt=0;buf.flag=0

Код:

    if (buf.write>=Endbuf) buf.read=buf.buffer;
    buf.cnt++;

Не много оптимално, но за сметка на това почти универсално.

Ако беше и вярно :)


Пон Юли 09, 2007 11:39 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение 
Yanek не, че твърдя че пика е по-бърз от някой друг или по-бавен от трети, но в 18-та серия - 18F452 примерно, има 3 (три) регистъра за индиректно адресиране на паметта, които след като запишеш в двата адреса на клетката (без превключване на банки) което отнема 2 (два) цикъла, в следващя 1 (един) цикъл четеш (или пишеш) от/в друг регистър в Access паметта (пак без превключване на банки) стойността на адресираната клетка. Това просто информативно де. Между другото е доста удобно. При по-проста опашка може директно да си ползваш примерно младшия поинтер за следене. А и между другото тези регистри имат и възможност след четене/писане сами да се увеличават/намаляват. Не е върха ама се е нещо :) Пък и става за 1-2 цикъла, не е като да са сума ти.


Пон Юли 09, 2007 2:11 pm
Профил ICQ
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пет Юни 29, 2007 10:59 pm
Мнения: 113
Мнение 
Да, вярно е заблудил съм се. И въпреки това си направих една проба. Един и същи код с компилатор на IAR изпробвах за PIC и MSP. Специално тази ф-ия която пробвах наистина се оказа, че MSP на 8 MHz е с 42% по-бавно от PIC18 на 40 MHz. Ето и функцията:

typedef unsigned char BOOL;
#define FALSE 0x00
#define TRUE 0xFF

#define BUFSIZE 64
volatile unsigned char ucCharBuffer[BUFSIZE];
volatile unsigned char ucWriteIndex=0;
volatile unsigned char ucCharCount=0;



BOOL PushChar(unsigned char ucByte)
{
if ((ucCharCount & ~(BUFSIZE-1))!=0)return FALSE;

ucCharBuffer[ucWriteIndex++] = ucByte;
ucWriteIndex &= BUFSIZE-1;
ucCharCount++;
return TRUE;

}

Edit: Да, писал съм на 452 и 458. Тъй като ползвах смесен код на С и Asm имам спомен, че MCC18 ползваше единият индексен (или както му беше името) регистър твърдо забит на някоя RAM банка, като стек. После беше едно прехвърляне и вадене на резултата и на входните променливи от него. Другите 2 вече нямам спомен как използвах, но определено си бяха котешки каваци при употребата им. Минаха 3 години и нямам бистър спомен, но на MSP-то и на HCS12 направо се родих. Пак ползвам на места смесен код, но някак си се чувствам свободен. Инак съм писал около 4 години на PIC. Професионално разбира се.


Пон Юли 09, 2007 2:32 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение 
Това, че компилатора го ползва така си е работа на компилатора. Реално погледнато индиректното адресиране си действа бързо. А и пик на 40 си е 10MIPS. Като му свикне човек не е чак такъв гърч.


Пон Юли 09, 2007 4:28 pm
Профил ICQ
Ранг: Напреднал
Ранг: Напреднал
Аватар

Регистриран на: Нед Сеп 17, 2006 12:00 pm
Мнения: 450
Местоположение: Plovdiv
Мнение 
ПИК-ът е 16-ка, затова ми трябва да е на асемблер. Мерси за идейте, това по-горе на Yanek ще свърши работа :)
Мога да пиша на С и С++ за PC, обаче още не съм започнал да пиша на високо ниво за микроконтролери. Малко ми е странно да не знам какво точно става ако пиша на C вместо на асемблер, но в скоро време ще трябва да се хващам..


Пон Юли 09, 2007 9:44 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 15 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 5 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни