|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:10 am
|
Страница 1 от 1
|
[ 15 мнения ] |
|
| Автор |
Съобщение |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
 Реализация на опашка
Здравейте, как се реализира списък тип опашка на асемблер за ПИК? Интересува ме идеята само, аз мисля така да стане: организирам си един масив и две променливи за начало и край, където съответно ще се чете и записва. Проблемът, обаче е, че опашката постепенно ще се "движи" към единия край. Може да се направи да бъде цикличен списъка, т.е, чрез делене по модул да се връща края на опашката обратно в началото на масива, така ли се прави по принцип?
|
| Пет Юли 06, 2007 12:16 pm |
|
 |
|
darkyp
Ранг: Ориентиран
Регистриран на: Пон Дек 12, 2005 6:03 pm Мнения: 263 Местоположение: София
|
Аз скоро правих подобно нещо. Отделих си 32 байта памет. Една променлива пойнтер за писане, една за четене. В irq се пише, в main прога се чете. Ако писането = четенето - main-а чака. Не е необходимо деление, защото се ползват 4 бита и с AND се маскират. Не съм следил за край на опашката (презаписване на стойност, която да не е изчетена) защото по тайминг е предвидено да не се случва.
|
| Пет Юли 06, 2007 1:15 pm |
|
 |
|
MYXATA
Ранг: Форумен бог
Регистриран на: Пон Юни 05, 2006 1:48 pm Мнения: 4906 Местоположение: където небето среща земята, ракията е Jameson, а бирата Guinness
|
 Re: Реализация на опашка
имаш в предвид кръгов буфер ли как се пише ? или друго?
_________________ ... ако трети ден не ти се работи... това означава, че е сряда !
|
| Пет Юли 06, 2007 2:07 pm |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
Да, кръгов буфер, защото не виждам друг начин как да реализирам опашката.
Интересно ми е дали има някакво елегантно решение.
|
| Пет Юли 06, 2007 3:20 pm |
|
 |
|
darkyp
Ранг: Ориентиран
Регистриран на: Пон Дек 12, 2005 6:03 pm Мнения: 263 Местоположение: София
|
еми и аз за кръгов говоря. или нещо друго съм му сторил  ?
|
| Пет Юли 06, 2007 3:28 pm |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
Ще помисля върху твоята идея, мерси! 
|
| Пет Юли 06, 2007 8:48 pm |
|
 |
|
Yanek
Ранг: Новодошъл
Регистриран на: Пет Юни 29, 2007 10:59 pm Мнения: 113
|
 Re: Реализация на опашка
Ето ти обща схема на моята реализация. Имаш началния адрес на буфера в паметта. Две променливи, които наричам индекси и предствляват отместването от началото на буфера съответно при четене и при запис в буфера. Допълнително една променлива, наричам я брояч и представлява броя на наличните байтове в буфера. Когато правя 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 |
|
 |
|
bateAz
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 4:11 pm Мнения: 3750 Местоположение: София
|
Още по-бързо решение е указателят да сочи директно адреса на клетката от масива, а не индекса му. Така се пропуска едно събиране.
|
| Нед Юли 08, 2007 9:28 am |
|
 |
|
Yanek
Ранг: Новодошъл
Регистриран на: Пет Юни 29, 2007 10:59 pm Мнения: 113
|
Така е - пропуска се едно събиране, но се добавя според мен по-дълга процедура по проверка дали указателя не е достигнал края на опашката. Ще трябва да се направи поне едно изваждане и една проверка за по-малко, докато в моя случай имаш едно събиране и един AND. Или пък да извадиш поинтера с началото на буфера и с разликата да работиш както аз с индекса, но после пак трябва да събереш с началото на буфера. Освен ако нямаш нещо друго предвид си мисля, че твоя случай не е по-кратък. Ето в този пример си личи липсата на индексна адресация в PIC (поне доколкото имам спомен).
Поправка: За да бъда точен май в PIC18 вкараха някакви индексни указатели със специални инструкции имитиращи индексната адресация. Вярно, че беше някаква жалка история със сума ти цикли на инструкция, но вършеха работа. Само за сравнение MSP на TI на 8 MHz постига по-добра производителност ot PIC18 на 40 MHz. Едно че инструкциите му като цяло отнемат по-малко цикли, друго че 7-те вида адресация и 11-те регистъра с общо предназначение (акумулатори) предоставят по-голяма гъвкавост при писане на програмите. Разбира се да не забравяме, че единият е 8 битов а другия 16.
|
| Нед Юли 08, 2007 11:38 am |
|
 |
|
setoy
Ранг: Почетен член
Регистриран на: Пет Фев 17, 2006 9:17 am Мнения: 765 Местоположение: Стара Загора
|
Тука май бъркаш. В PIC18 няма да видиш по-дълги от 2 цикъла инструкциии. За MSP430 има и такива по 5-6 цикъла. Няма как да е по-производителен  Колкото за опашката - явно все по един и същи начин се прави - оттама нататък е въпрос на техника и на вкус
Не много оптимално, но за сметка на това почти универсално.
edit: Така е в понеделник сутрин преди второто кафе... 
Последна промяна setoy на Пон Юли 09, 2007 2:03 pm, променена общо 2 пъти
|
| Пон Юли 09, 2007 9:37 am |
|
 |
|
danov
Ранг: Минаващ
Регистриран на: Вто Ное 16, 2004 4:43 pm Мнения: 85 Местоположение: София
|
Ако беше и вярно 
|
| Пон Юли 09, 2007 11:39 am |
|
 |
|
Cekins
Ранг: Форумен бог
Регистриран на: Сря Апр 20, 2005 12:02 pm Мнения: 9119 Местоположение: Разград
|
Yanek не, че твърдя че пика е по-бърз от някой друг или по-бавен от трети, но в 18-та серия - 18F452 примерно, има 3 (три) регистъра за индиректно адресиране на паметта, които след като запишеш в двата адреса на клетката (без превключване на банки) което отнема 2 (два) цикъла, в следващя 1 (един) цикъл четеш (или пишеш) от/в друг регистър в Access паметта (пак без превключване на банки) стойността на адресираната клетка. Това просто информативно де. Между другото е доста удобно. При по-проста опашка може директно да си ползваш примерно младшия поинтер за следене. А и между другото тези регистри имат и възможност след четене/писане сами да се увеличават/намаляват. Не е върха ама се е нещо  Пък и става за 1-2 цикъла, не е като да са сума ти.
|
| Пон Юли 09, 2007 2:11 pm |
|
 |
|
Yanek
Ранг: Новодошъл
Регистриран на: Пет Юни 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 |
|
 |
|
Cekins
Ранг: Форумен бог
Регистриран на: Сря Апр 20, 2005 12:02 pm Мнения: 9119 Местоположение: Разград
|
Това, че компилатора го ползва така си е работа на компилатора. Реално погледнато индиректното адресиране си действа бързо. А и пик на 40 си е 10MIPS. Като му свикне човек не е чак такъв гърч.
|
| Пон Юли 09, 2007 4:28 pm |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
ПИК-ът е 16-ка, затова ми трябва да е на асемблер. Мерси за идейте, това по-горе на Yanek ще свърши работа
Мога да пиша на С и С++ за PC, обаче още не съм започнал да пиша на високо ниво за микроконтролери. Малко ми е странно да не знам какво точно става ако пиша на C вместо на асемблер, но в скоро време ще трябва да се хващам..
|
| Пон Юли 09, 2007 9:44 pm |
|
|
|
Страница 1 от 1
|
[ 15 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 5 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|