Отговори на тема  [ 17 мнения ]  Отиди на страница 1, 2  Следваща
FIFO буфер за команди 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение FIFO буфер за команди
Значи първо да опиша какво искам да направя.
Искам да организирам FIFO буфер в които да имам указатели към функции и съответните им входни аргументи.
Целта на занятието е някои процедури на прекъсвания да записват указател към функция и входни аргументи в опашката на буфера. A в main() да имам цикъл които последователно да вади указателите от буфера и да извиква функциите като им дава съответните аргументи.
Ако се работи само с функции без входни аргументи ми е ясно.
Ако се работи само с функции с един тип аргументи с малко експерименти ще го наглася някак. Но как стои въпроса ако искам този буфер да поддържа и функции с различен тип входни аргументи и каква е стандартната реализация в C?


Сря Юни 08, 2005 9:56 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение Re: FIFO буфер за команди
Nikola Kirov написа:
Но как стои въпроса ако искам този буфер да поддържа и функции с различен тип входни аргументи и каква е стандартната реализация в C?

Чак стандартна реализация - не знам да има. Но може да направиш всички функции да имат един аргумент - указател към структура, която съдържа параметрите. По този начин ще е лесно да си направиш FIFO-то.


Сря Юни 08, 2005 10:20 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
Трябва ми по универсално решение. Да мога да работя с до 2 аргумента и без аргумент. Ако ги направя всички функции да си вадят сами параметрите от структура това ще ми усложни живота с поставянето на параметрите в тая структура при задаването на параметрите на функцията.
Това ли ми е единственото решение?


Сря Юни 08, 2005 10:30 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Nikola Kirov написа:
Трябва ми по универсално решение. Да мога да работя с до 2 аргумента и без аргумент. Ако ги направя всички функции да си вадят сами параметрите от структура това ще ми усложни живота с поставянето на параметрите в тая структура при задаването на параметрите на функцията.
Това ли ми е единственото решение?


Syntax

#include <stdarg.h>
void va_start(va_list ap, lastfix);
type va_arg(va_list ap, type);
void va_end(va_list ap);

Description

Implement a variable argument list.
Some C functions, such as vfprintf and vprintf, take variable argument lists in addition to taking a number of fixed (known) parameters. The va_arg, va_end, and va_start macros provide a portable way to access these argument lists. They are used for stepping through a list of arguments when the called function does not know the number and types of the arguments being passed.
The header file stdarg.h declares one type (va_list) and three macros (va_start, va_arg, and va_end).

va_list: This array holds information needed by va_arg and va_end. When a called function takes a variable argument list, it declares a variable ap of type va_list.
va_start: This routine (implemented as a macro) sets ap to point to the first of the variable arguments being passed to the function. va_start must be used before the first call to va_arg or va_end.
va_start takes two parameters: ap and lastfix. (ap is explained under va_list in the preceding paragraph; lastfix is the name of the last fixed parameter being passed to the called function.)

va_arg: This routine (also implemented as a macro) expands to an expression that has the same type and value as the next argument being passed (one of the variable arguments). The variable ap to va_arg should be the same ap that va_start initialized.

Note: Because of default promotions, you cannot use char, unsigned char, or float types with va_arg.

The first time va_arg is used, it returns the first argument in the list. Each successive time va_arg is used, it returns the next argument in the list. It does this by first dereferencing ap, and then incrementing ap to point to the following item. va_arg uses the type to both perform the dereference and to locate the following item. Each successive time va_arg is invoked, it modifies ap to point to the next argument in the list.

va_end: This macro helps the called function perform a normal return. va_end might modify ap in such a way that it cannot be used unless va_start is recalled. va_end should be called after va_arg has read all the arguments; failure to do so might cause strange, undefined behavior in your program.

Return Value

va_start and va_end return no values; va_arg returns the current argument in the list (the one that ap is pointing to).

#include <stdio.h>
#include <stdarg.h>

/* calculate sum of a 0 terminated list */
void sum(char *msg, ...)
{
int total = 0;
va_list ap;
int arg;
va_start(ap, msg);
while ((arg = va_arg(ap,int)) != 0) {
total += arg;
}
printf(msg, total);
va_end(ap);
}

int main(void) {
sum("The total of 1+2+3+4 is %d\n", 1,2,3,4,0);
return 0;
}

Доколкото разбирам обаче ти трябва реализация на горните макроси за микроконтролери, а не си спомням да съм срещал в който и да Ц компилатор такава реализация за микроконтролери.


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

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
Въртеше ми се в главата че съм виждал нещо такова. И затова повдигнах въпроса. Само дето не се поддържа от IAR. :cry: А и като се замисля за реализацията наистина едва ли има някой компилатор за микроконтролери дето да го поддържа.
Явно ще се гърча да го измислям някак си.Малко неприятна задача за новобранец в програмирането,но така се учел човек.


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

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Това, което ти предлага колегата Danov, е удачно решение, само че при различни по тип аргументи трябва полетата в структурата да са union. Ако нямаш параметър, указателя към структурата ти е NULL, ако е 1 параметър, указателя е различен от NULL и първото поле -union в структурата ти е валидно, при 2 второто и т.н. Това че ще попълваш тези параметри преди извикването на дадена функци не е чак толкова голям проблем. Например CCS C компилатора за ПИК, дори и един параметър от тип int8 да има дадена функция, ще го предаде през регистър, а не през акумулатора, както бих го направил на асемблер. Ако извикаш една функция 100 пъти, ти изразходва 100 байта повече памет, затова се принуждавам за често извикваните функции да си правя макроси, с които да предавам променливата през акумулатора.


Чет Юни 09, 2005 12:52 am
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Пирев, що да изразходва памет. Набеди ги да са Ауто - те в стека. Е ако не барзаш и програмната памет не ти е кът. Иначе - глобални. Абе то при микроконтролерите от тоя калибър (8 бита, до 16К флаш, до 3К рам) то човек рядко си позволява да прави такива еквилибристики като указатели към функции и пр. Там С- то си е просто по прегледен асемблер.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Чет Юни 09, 2005 9:12 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
До колко тоя CSS е ANSI-съвместим? Поддържа ли malloc & free?


Чет Юни 09, 2005 9:52 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
Поддържа malloc & free.
А като ви се налага да правите опашка от задачи как го правите. На мен ми доиде само този метод на ум но това не означава че няма друг по добър.
Подобна опашка от задачи ми се вижда много добра алтернатива на RTOS за контролерите. Нещата които трябва да се изпълняват веднага се правят направо в функциите на прекъсванията а всичко останало,особенно по бавни задачи като писане по дисплея,запис в някакво устроиство с последователен интерфеис или нещо подобно отива на опашката с задачи. Така се решава и проблема когато 2 задачи ползват едни и същи I/O ресурси,те просто се изпълняват последователно. Това разбира се когато има достатъчно памет.


Чет Юни 09, 2005 12:17 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Ами то твойто си е много близко до cooperative RTOS, да не казвам че е същото. Много задачи които се изпълняват самосточтелно и сами определят кога да приключат.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Чет Юни 09, 2005 1:46 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение stdarg
Nikola Kirov написа:
А и като се замисля за реализацията наистина едва ли има някой компилатор за микроконтролери дето да го поддържа.


gcc поддържа stdarg - поне за avr и msp430.


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

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
Че RTOS не поддържа ли различни нишки като превключва между тях и разпределя ресурсите на процесора между тях. Идеята тук е да имаме само една нишка която да е опашка от команди.


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

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Цецо написа:
Пирев, що да изразходва памет. Набеди ги да са Ауто - те в стека. Е ако не барзаш и програмната памет не ти е кът. Иначе - глобални. Абе то при микроконтролерите от тоя калибър (8 бита, до 16К флаш, до 3К рам) то човек рядко си позволява да прави такива еквилибристики като указатели към функции и пр. Там С- то си е просто по прегледен асемблер.


Имах предвид следното:
Код:
void SomeFunc(int8 value);


CCS компилатора прави следното:
Код:
movf SomeRegister,W
movwf SomeFunc_ScratchMem
call SomeFunc


вътре SomeFunc изглежда така:
Код:
SomeFunc:
movf SomeFunc_ScratchMem,W
movwf OtherVariable
.....
return


Докато, пишейки на асемблер, правя следното:
Код:
movf SomeRegister,W
call SomeFunc

, при което SomeFunc изглежда така:
Код:
SomeFunc:
movwf OtherVariable
.....
return


Друг C компилатор за PIC-ове, този на Knudsen ( CC5X ) такова извикване го прави винаги през акумулатора. Наскоро се ядосвах на това викане на подпрограми на CCS, защото една стара програма на асемблер, трябваше да я преработя на C, за да мога по-лесно да добавям нови неща, едвам успях да я събера в PIC16F872, разликата м/у асемблер и CCS C се оказа около 350 байта в полза на асемблера.


Чет Юни 09, 2005 3:03 pm
Профил WWW
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Мар 18, 2005 4:14 pm
Мнения: 67
Местоположение: Русе.BG/Oldenburg.DE
Мнение 
Не съм много advanced в програмирането за MCUs, но:
@Nikola Kirov: Защо до ти се усложнява живота при решението с указателите към структурата? Дефинирай си извикваща ф-я int callPop(int a, int b) и си работи с нея. Самата ф-я може да записва параметрите на предварително определен адрес (например глобални temp1 и temp2), след това вика ф-ята от опашката. Всяка ф-я от списъка я дефинираш като int foo(void), а в самите ф-ии:
Код:
int fooNoParams(void)  {
//func. body
return result; 
}

int foo1Param(void) {
int paramA = retreiveParamA();
//func. body
return result;
}

int foo2Param(void) {
int paramA,paramB;
paramA = retrieveParams(&paramB);
//func. body
return result;
}

retrieveParams може да ги декларираш като макрос, за да избегнеш overhead-a от извикване но ф-я (прехвърлянето на параметри, etc). Мисля това решение е добър компромис м/у бързодействие и леснота (има ли такава дума? 8O ) на използване.

И без това, в другия случай ще трябва да typecast-ваш pointer-а към всяка отделна ф-я.

П.С Всъщност този компилатор подържа ли naked ф-ии?


Чет Юни 09, 2005 4:24 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Пирев, така е защото използваш статични променливи. Всеки С компилатор поддържа статични и динамични промнливи. Вторите се блъскат в стека, и се унищожават извън функцията. Разбира се динамични могат да са само локални променливи, които нямат значение от вън на функцията.
Са друг е въпроса на CCS как му е сетнато по дефаулт, сигурно е на статични, щото 16ката няма много ресурси за стек. И затова по презумпция маа в регистрите за всяка променлива - локална или глобална.
Моя компилатор има и тип overlay, това са статични променливи които ползват общ регистър, е не едновремнно.
Но това май няма отношение по темата.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Чет Юни 09, 2005 7:02 pm
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 17 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: jordan-bg и 9 госта


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

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