| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Реализация на опашка http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=4473 |
Страница 1 от 1 |
| Автор: | MidNighT_SpiRiT [ Пет Юли 06, 2007 12:16 pm ] |
| Заглавие: | Реализация на опашка |
Здравейте, как се реализира списък тип опашка на асемблер за ПИК? Интересува ме идеята само, аз мисля така да стане: организирам си един масив и две променливи за начало и край, където съответно ще се чете и записва. Проблемът, обаче е, че опашката постепенно ще се "движи" към единия край. Може да се направи да бъде цикличен списъка, т.е, чрез делене по модул да се връща края на опашката обратно в началото на масива, така ли се прави по принцип? |
|
| Автор: | darkyp [ Пет Юли 06, 2007 1:15 pm ] |
| Заглавие: | |
Аз скоро правих подобно нещо. Отделих си 32 байта памет. Една променлива пойнтер за писане, една за четене. В irq се пише, в main прога се чете. Ако писането = четенето - main-а чака. Не е необходимо деление, защото се ползват 4 бита и с AND се маскират. Не съм следил за край на опашката (презаписване на стойност, която да не е изчетена) защото по тайминг е предвидено да не се случва. |
|
| Автор: | MYXATA [ Пет Юли 06, 2007 2:07 pm ] | |||||||||
| Заглавие: | Re: Реализация на опашка | |||||||||
имаш в предвид кръгов буфер ли как се пише ? или друго? |
||||||||||
| Автор: | MidNighT_SpiRiT [ Пет Юли 06, 2007 3:20 pm ] |
| Заглавие: | |
Да, кръгов буфер, защото не виждам друг начин как да реализирам опашката. Интересно ми е дали има някакво елегантно решение. |
|
| Автор: | darkyp [ Пет Юли 06, 2007 3:28 pm ] |
| Заглавие: | |
еми и аз за кръгов говоря. или нещо друго съм му сторил |
|
| Автор: | MidNighT_SpiRiT [ Пет Юли 06, 2007 8:48 pm ] |
| Заглавие: | |
Ще помисля върху твоята идея, мерси! |
|
| Автор: | Yanek [ Съб Юли 07, 2007 10:52 pm ] | |||||||||
| Заглавие: | Re: Реализация на опашка | |||||||||
Ето ти обща схема на моята реализация. Имаш началния адрес на буфера в паметта. Две променливи, които наричам индекси и предствляват отместването от началото на буфера съответно при четене и при запис в буфера. Допълнително една променлива, наричам я брояч и представлява броя на наличните байтове в буфера. Когато правя PUSH в буфера вземам указателя за начало на буфера + индекса за запис и на получения адрес записвам байта, инкрементирам брояча и индекса и правя проверка дали индекса не е надхвърлил стойност по-голяма от дължината на буфера. Един трик вместо тази проверка: ако например дължината на буфера си определил да е 64 (0х40) просто можеш да направиш AND на Index с (дължина на буфер -1) или Index AND 0x3F. Ясно ти е, че когато Index стане над 63 след това действие отново е нула. Съответно когато правиш POP - четеш съдържанието на (начало на буфер + индекс за четене) инкремент на индекса за четене, декремент на общия брояч и отново трика с индекса. Разбира се при PUSH правиш проверка на брояча дали не е достигнал стойност дължина на буфера (трик:например в случая Counter AND 0xC0 ти дава ZF=0 ако брояча е 64 или по-голям), съответно при POP проверяваш дали брояча е 0, за да не се получи съответно препълване или препразване. Брояча съм го сложил защото често проверявам има ли наличност в буфера и така е по-лесно и по-бързо. Едно уточнение: Ясно е, че ако дължината на буфера не е равна на някоя степен на 2, тези трикове не работят и трябва да правиш по-дълги проверки. |
||||||||||
| Автор: | bateAz [ Нед Юли 08, 2007 9:28 am ] |
| Заглавие: | |
Още по-бързо решение е указателят да сочи директно адреса на клетката от масива, а не индекса му. Така се пропуска едно събиране. |
|
| Автор: | Yanek [ Нед Юли 08, 2007 11:38 am ] | |||||||||
| Заглавие: | ||||||||||
Така е - пропуска се едно събиране, но се добавя според мен по-дълга процедура по проверка дали указателя не е достигнал края на опашката. Ще трябва да се направи поне едно изваждане и една проверка за по-малко, докато в моя случай имаш едно събиране и един AND. Или пък да извадиш поинтера с началото на буфера и с разликата да работиш както аз с индекса, но после пак трябва да събереш с началото на буфера. Освен ако нямаш нещо друго предвид си мисля, че твоя случай не е по-кратък. Ето в този пример си личи липсата на индексна адресация в PIC (поне доколкото имам спомен). Поправка: За да бъда точен май в PIC18 вкараха някакви индексни указатели със специални инструкции имитиращи индексната адресация. Вярно, че беше някаква жалка история със сума ти цикли на инструкция, но вършеха работа. Само за сравнение MSP на TI на 8 MHz постига по-добра производителност ot PIC18 на 40 MHz. Едно че инструкциите му като цяло отнемат по-малко цикли, друго че 7-те вида адресация и 11-те регистъра с общо предназначение (акумулатори) предоставят по-голяма гъвкавост при писане на програмите. Разбира се да не забравяме, че единият е 8 битов а другия 16. |
||||||||||
| Автор: | setoy [ Пон Юли 09, 2007 9:37 am ] | |||||||||
| Заглавие: | ||||||||||
Тука май бъркаш. В PIC18 няма да видиш по-дълги от 2 цикъла инструкциии. За MSP430 има и такива по 5-6 цикъла. Няма как да е по-производителен
Не много оптимално, но за сметка на това почти универсално. edit: Така е в понеделник сутрин преди второто кафе... |
||||||||||
| Автор: | danov [ Пон Юли 09, 2007 11:39 am ] | |||||||||||||||||||||||||||
| Заглавие: | ||||||||||||||||||||||||||||
Ако беше и вярно |
||||||||||||||||||||||||||||
| Автор: | Cekins [ Пон Юли 09, 2007 2:11 pm ] |
| Заглавие: | |
Yanek не, че твърдя че пика е по-бърз от някой друг или по-бавен от трети, но в 18-та серия - 18F452 примерно, има 3 (три) регистъра за индиректно адресиране на паметта, които след като запишеш в двата адреса на клетката (без превключване на банки) което отнема 2 (два) цикъла, в следващя 1 (един) цикъл четеш (или пишеш) от/в друг регистър в Access паметта (пак без превключване на банки) стойността на адресираната клетка. Това просто информативно де. Между другото е доста удобно. При по-проста опашка може директно да си ползваш примерно младшия поинтер за следене. А и между другото тези регистри имат и възможност след четене/писане сами да се увеличават/намаляват. Не е върха ама се е нещо |
|
| Автор: | Yanek [ Пон Юли 09, 2007 2:32 pm ] |
| Заглавие: | |
Да, вярно е заблудил съм се. И въпреки това си направих една проба. Един и същи код с компилатор на 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. Професионално разбира се. |
|
| Автор: | Cekins [ Пон Юли 09, 2007 4:28 pm ] |
| Заглавие: | |
Това, че компилатора го ползва така си е работа на компилатора. Реално погледнато индиректното адресиране си действа бързо. А и пик на 40 си е 10MIPS. Като му свикне човек не е чак такъв гърч. |
|
| Автор: | MidNighT_SpiRiT [ Пон Юли 09, 2007 9:44 pm ] |
| Заглавие: | |
ПИК-ът е 16-ка, затова ми трябва да е на асемблер. Мерси за идейте, това по-горе на Yanek ще свърши работа Мога да пиша на С и С++ за PC, обаче още не съм започнал да пиша на високо ниво за микроконтролери. Малко ми е странно да не знам какво точно става ако пиша на C вместо на асемблер, но в скоро време ще трябва да се хващам.. |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|