| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| FIFO буфер за команди http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=750 |
Страница 1 от 2 |
| Автор: | Nikola Kirov [ Сря Юни 08, 2005 9:56 pm ] |
| Заглавие: | FIFO буфер за команди |
Значи първо да опиша какво искам да направя. Искам да организирам FIFO буфер в които да имам указатели към функции и съответните им входни аргументи. Целта на занятието е някои процедури на прекъсвания да записват указател към функция и входни аргументи в опашката на буфера. A в main() да имам цикъл които последователно да вади указателите от буфера и да извиква функциите като им дава съответните аргументи. Ако се работи само с функции без входни аргументи ми е ясно. Ако се работи само с функции с един тип аргументи с малко експерименти ще го наглася някак. Но как стои въпроса ако искам този буфер да поддържа и функции с различен тип входни аргументи и каква е стандартната реализация в C? |
|
| Автор: | danov [ Сря Юни 08, 2005 10:20 pm ] | |||||||||
| Заглавие: | Re: FIFO буфер за команди | |||||||||
Чак стандартна реализация - не знам да има. Но може да направиш всички функции да имат един аргумент - указател към структура, която съдържа параметрите. По този начин ще е лесно да си направиш FIFO-то. |
||||||||||
| Автор: | Nikola Kirov [ Сря Юни 08, 2005 10:30 pm ] |
| Заглавие: | |
Трябва ми по универсално решение. Да мога да работя с до 2 аргумента и без аргумент. Ако ги направя всички функции да си вадят сами параметрите от структура това ще ми усложни живота с поставянето на параметрите в тая структура при задаването на параметрите на функцията. Това ли ми е единственото решение? |
|
| Автор: | ¶ [ Чет Юни 09, 2005 12:11 am ] | |||||||||
| Заглавие: | ||||||||||
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; } Доколкото разбирам обаче ти трябва реализация на горните макроси за микроконтролери, а не си спомням да съм срещал в който и да Ц компилатор такава реализация за микроконтролери. |
||||||||||
| Автор: | Nikola Kirov [ Чет Юни 09, 2005 12:39 am ] |
| Заглавие: | |
Въртеше ми се в главата че съм виждал нещо такова. И затова повдигнах въпроса. Само дето не се поддържа от IAR. Явно ще се гърча да го измислям някак си.Малко неприятна задача за новобранец в програмирането,но така се учел човек. |
|
| Автор: | ¶ [ Чет Юни 09, 2005 12:52 am ] |
| Заглавие: | |
Това, което ти предлага колегата Danov, е удачно решение, само че при различни по тип аргументи трябва полетата в структурата да са union. Ако нямаш параметър, указателя към структурата ти е NULL, ако е 1 параметър, указателя е различен от NULL и първото поле -union в структурата ти е валидно, при 2 второто и т.н. Това че ще попълваш тези параметри преди извикването на дадена функци не е чак толкова голям проблем. Например CCS C компилатора за ПИК, дори и един параметър от тип int8 да има дадена функция, ще го предаде през регистър, а не през акумулатора, както бих го направил на асемблер. Ако извикаш една функция 100 пъти, ти изразходва 100 байта повече памет, затова се принуждавам за често извикваните функции да си правя макроси, с които да предавам променливата през акумулатора. |
|
| Автор: | Цецо [ Чет Юни 09, 2005 9:12 am ] |
| Заглавие: | |
Пирев, що да изразходва памет. Набеди ги да са Ауто - те в стека. Е ако не барзаш и програмната памет не ти е кът. Иначе - глобални. Абе то при микроконтролерите от тоя калибър (8 бита, до 16К флаш, до 3К рам) то човек рядко си позволява да прави такива еквилибристики като указатели към функции и пр. Там С- то си е просто по прегледен асемблер. |
|
| Автор: | Реконструктор [ Чет Юни 09, 2005 9:52 am ] |
| Заглавие: | |
До колко тоя CSS е ANSI-съвместим? Поддържа ли malloc & free? |
|
| Автор: | Nikola Kirov [ Чет Юни 09, 2005 12:17 pm ] |
| Заглавие: | |
Поддържа malloc & free. А като ви се налага да правите опашка от задачи как го правите. На мен ми доиде само този метод на ум но това не означава че няма друг по добър. Подобна опашка от задачи ми се вижда много добра алтернатива на RTOS за контролерите. Нещата които трябва да се изпълняват веднага се правят направо в функциите на прекъсванията а всичко останало,особенно по бавни задачи като писане по дисплея,запис в някакво устроиство с последователен интерфеис или нещо подобно отива на опашката с задачи. Така се решава и проблема когато 2 задачи ползват едни и същи I/O ресурси,те просто се изпълняват последователно. Това разбира се когато има достатъчно памет. |
|
| Автор: | Цецо [ Чет Юни 09, 2005 1:46 pm ] |
| Заглавие: | |
Ами то твойто си е много близко до cooperative RTOS, да не казвам че е същото. Много задачи които се изпълняват самосточтелно и сами определят кога да приключат. |
|
| Автор: | danov [ Чет Юни 09, 2005 2:23 pm ] | |||||||||
| Заглавие: | stdarg | |||||||||
gcc поддържа stdarg - поне за avr и msp430. |
||||||||||
| Автор: | Nikola Kirov [ Чет Юни 09, 2005 2:56 pm ] |
| Заглавие: | |
Че RTOS не поддържа ли различни нишки като превключва между тях и разпределя ресурсите на процесора между тях. Идеята тук е да имаме само една нишка която да е опашка от команди. |
|
| Автор: | ¶ [ Чет Юни 09, 2005 3:03 pm ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Заглавие: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
Имах предвид следното:
CCS компилатора прави следното:
вътре SomeFunc изглежда така:
Докато, пишейки на асемблер, правя следното:
, при което SomeFunc изглежда така:
Друг C компилатор за PIC-ове, този на Knudsen ( CC5X ) такова извикване го прави винаги през акумулатора. Наскоро се ядосвах на това викане на подпрограми на CCS, защото една стара програма на асемблер, трябваше да я преработя на C, за да мога по-лесно да добавям нови неща, едвам успях да я събера в PIC16F872, разликата м/у асемблер и CCS C се оказа около 350 байта в полза на асемблера. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Автор: | 0x00 [ Чет Юни 09, 2005 4:24 pm ] | |||||||||
| Заглавие: | ||||||||||
Не съм много advanced в програмирането за MCUs, но: @Nikola Kirov: Защо до ти се усложнява живота при решението с указателите към структурата? Дефинирай си извикваща ф-я int callPop(int a, int b) и си работи с нея. Самата ф-я може да записва параметрите на предварително определен адрес (например глобални temp1 и temp2), след това вика ф-ята от опашката. Всяка ф-я от списъка я дефинираш като int foo(void), а в самите ф-ии:
retrieveParams може да ги декларираш като макрос, за да избегнеш overhead-a от извикване но ф-я (прехвърлянето на параметри, etc). Мисля това решение е добър компромис м/у бързодействие и леснота (има ли такава дума? И без това, в другия случай ще трябва да typecast-ваш pointer-а към всяка отделна ф-я. П.С Всъщност този компилатор подържа ли naked ф-ии? |
||||||||||
| Автор: | Цецо [ Чет Юни 09, 2005 7:02 pm ] |
| Заглавие: | |
Пирев, така е защото използваш статични променливи. Всеки С компилатор поддържа статични и динамични промнливи. Вторите се блъскат в стека, и се унищожават извън функцията. Разбира се динамични могат да са само локални променливи, които нямат значение от вън на функцията. Са друг е въпроса на CCS как му е сетнато по дефаулт, сигурно е на статични, щото 16ката няма много ресурси за стек. И затова по презумпция маа в регистрите за всяка променлива - локална или глобална. Моя компилатор има и тип overlay, това са статични променливи които ползват общ регистър, е не едновремнно. Но това май няма отношение по темата. |
|
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|