Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Достъп до масив във флаша при AVR GCC?
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=6193
Страница 1 от 2

Автор:  Ники [ Вто Окт 21, 2008 11:12 am ]
Заглавие:  Достъп до масив във флаша при AVR GCC?

В файла avr-libc-user-manual.pdf приложен към WINAVR, е описано че константите записани във флаш паметта са достъпни по същия начин както константите записани във RAM. Но се натъкнах на проблем при използването на следния код:

<avr/pgmspace.h>
...
unsigned char array[3] PROGMEM =// или unsigned char array[3] __attribute__((progmem))
{
0x01,0x02,0x03
}
...
void read_array(void)
{
int i;
for(i=0;i<3;i++)
printf("%u ",array[i]);
}

Не се извеждат стойностите от масива, а някакви случайни числа, предполагам не от флаша а от рама, поне инструкцията която се вижда в дизасемблера е за зареждане от рам.

При заместване на директния достъп до елемент от масива, със специална функция pgm_read_byte(ptr) (от pgmspace.h),се принтват вече правилните стойности от масива:

void read_array(void)
{
int i;
int *ptr=&(array[0]);

for(i=0;i<3;i++)
printf("%u ",pgm_read_byte(ptr++));
}



Какво му е специалното на масив във флаша при AVR GCC, че се налага използването на допълнителна функция, извън нормалния начин за достъп до масива?

Автор:  woody [ Вто Окт 21, 2008 11:13 am ]
Заглавие:  Re: Достъп до масив във флаша при AVR GCC?

Ники написа:
Какво му е специалното на масив във флаша при AVR GCC, че се налага използването на допълнителна функция, извън нормалния начин за достъп до масива?


Различно адресно пространство.

Автор:  Ники [ Вто Окт 21, 2008 11:23 am ]
Заглавие:  Re: Достъп до масив във флаша при AVR GCC?

woody написа:

Различно адресно пространство.


Благодаря за скоростния отговор :)

Ще се примиря с тази особеност за момента, но само да изчистя объркването което получавам от User-manual-a и реалността, да не се опитвам да използвам масивите от флаша във АVR GCC по нормалния начин?

Не познавам много среди/процесори, но при C30 (GCC) PIC24, пак имаме различни адресни пространства и масивите се ползват без проблеми с нормалния достъп до елементи от тях!?

Автор:  setoy [ Вто Окт 21, 2008 11:33 am ]
Заглавие: 

Не познавам конкретно този компилатор, но това ми се вижда ужасно криво 8O Чак не е за вярване.. А ако обявиш масива като const? Има ли промяна?

Автор:  danov [ Вто Окт 21, 2008 11:39 am ]
Заглавие: 

Код:
printf_P ("%u ",array[i]);


Разгледай stdio.h, има дефинирани функциите printf_P, scanf_P, ...

Автор:  Ники [ Вто Окт 21, 2008 11:42 am ]
Заглавие: 

setoy написа:
Не познавам конкретно този компилатор, но това ми се вижда ужасно криво 8O Чак не е за вярване.. А ако обявиш масива като const? Има ли промяна?


Ще свикна и с подобна кривотия, ще се преживее, но ме човърка да разбера дали аз не пропускам нещо от особеностите на този компилатор.

А относно 'const', за каквото се се сетих опитвах, но вади някакви грешки.

За да е ясно, при декларирането на масива по описания по-горе начин, наистина той е разположен във флаша, и е достъпен, въпреки непопулярния начин...за момента.

danov написа:
Код:
printf_P ("%u ",array[i]);


Разгледай stdio.h, има дефинирани функциите printf_P, scanf_P, ...


Проблема ми не е в принтването на масива, това го дадох само за пример във темата тук, реално във програмата си не го ползвам дори.

Вълнуваме използването на масива като цяло, във всички възможни ситуации.

Автор:  woody [ Вто Окт 21, 2008 11:50 am ]
Заглавие:  Re: Достъп до масив във флаша при AVR GCC?

Ники написа:
... да не се опитвам да използвам масивите от флаша във АVR GCC по нормалния начин?


Няма нормален начин. :D

Понеже имаш различни адресни пространства е очевидно че указател от 16-бита няма как да е ясно към кое точно сочи. Има решения (Keil 8051) в които указателят се увеличава за да включва и информация за адресното пространство, но това е за сметка на памет и скорост.

Свикни да имаш функции които очакват указател към данни или код (флаш).

Ники написа:
Не познавам много среди/процесори, но при C30 (GCC) PIC24, пак имаме различни адресни пространства и масивите се ползват без проблеми с нормалния достъп до елементи от тях!?


Това е според порта на GCC, а освен това ти решава проблема само ако правиш достъп до масиви директно като "val = code_array[index]". Указателите пак не е ясно за къде са.

Автор:  Ники [ Вто Окт 21, 2008 11:57 am ]
Заглавие:  Re: Достъп до масив във флаша при AVR GCC?

woody написа:
...

Няма нормален начин. :D


...


Програмата си ми работи добре и за момента, спокоен съм че не това я спира, но се опитвам да си почеша гъдела в главата от странния ми за момента начин.

Щом релефа на местността е такъв, ще се огъвам според него...

Автор:  woody [ Вто Окт 21, 2008 12:39 pm ]
Заглавие: 

Гледай в какъв код резултират опитите ти и ще свикнеш с релефите.

Автор:  Nikola Kirov [ Вто Окт 21, 2008 12:57 pm ]
Заглавие: 

Напиши си го на асемблер и ще разбереш защо имаш различни указатели към флаша и рама. Тогава няма да ти звучи криво :)

Автор:  setoy [ Вто Окт 21, 2008 1:36 pm ]
Заглавие: 

const или __attribute__((progmem)) сам по себе си не е ли достатъчен да му каже къде се намира? Иначе ясно че достъпа до флаш и рам става по различен начин :).

Автор:  Ники [ Вто Окт 21, 2008 1:55 pm ]
Заглавие: 

setoy написа:
const или __attribute__((progmem)) сам по себе си не е ли достатъчен да му каже къде се намира? Иначе ясно че достъпа до флаш и рам става по различен начин :).

точно това ми беше чуденето с тази тема, на компилатора му е указано къде се намира масива, няколко часа отидоха в разни опити да го лъжа, но си иска там специалните функции и тва е.
Иначе е ясно че константите може да се разполагат и в RAM или FLASH, според желанията/компромисите за скорост/код/обем и т.н.
Но след изрично указване къде се намират, защо не се възприемат и обработват от компилатора с нужните инструкции за правилен достъп но с обикновени изрази, отговорите дотук сочат в други посоки :)
Ок различни адресни пространства са, инструкциите за достъп също са различни, но е странно хрумването да бъдат разделени и начините за обработка на данни в тези адресни пространства, след като има възможност да се ползват без да се усеща разликата, поне при писането на кода.
Но всеки компилатор с неговите си отклонения...

Автор:  woody [ Сря Окт 22, 2008 11:27 am ]
Заглавие: 

Ники написа:
Но след изрично указване къде се намират, защо не се възприемат и обработват от компилатора с нужните инструкции за правилен достъп но с обикновени изрази, отговорите дотук сочат в други посоки :)
Ок различни адресни пространства са, инструкциите за достъп също са различни, но е странно хрумването да бъдат разделени и начините за обработка на данни в тези адресни пространства, след като има възможност да се ползват без да се усеща разликата, поне при писането на кода.
Но всеки компилатор с неговите си отклонения...


Проблемите са предимно в зад-кормилните устройства.

"const" указва че няма да го променяш, а не че трябва да е в специално пространство. В обичайните unix-дериватни компилатори това просто го засилва в отделна секция.

Прагмата инструктира линкера да го сложи в програмното пространство, но това не имплицира (в случая) интелигентност на компилатора.

И последно, как точно го виждаш това да работи с данни от различни адресни пространства:

Код:
char fun (char *a, char *b)
{
    return *a + *b;
}


Всичко си е логично и на мястото, но иска инвестиция в замисляне.

Автор:  Ники [ Сря Окт 22, 2008 12:19 pm ]
Заглавие: 

woody написа:
Проблемите са предимно в зад-кормилните устройства.

"const" указва че няма да го променяш, а не че трябва да е в специално пространство. В обичайните unix-дериватни компилатори това просто го засилва в отделна секция.

Прагмата инструктира линкера да го сложи в програмното пространство, но това не имплицира (в случая) интелигентност на компилатора.

И последно, как точно го виждаш това да работи с данни от различни адресни пространства:

Код:
char fun (char *a, char *b)
{
    return *a + *b;
}


Всичко си е логично и на мястото, но иска инвестиция в замисляне.


При мен за задкормилното устройство се съгласявам, че често генерира загуби на време от невнимание или недомисляне.

Относно примера ти за предаване на указатели параметри, няма да работи за насиви във флаша, не го знаех, но се убедих с отделеното време и дебъгера.

Считам че отделям нужното време и ще науча особеностите, но за интелигентността на компилатора имах предвид поне при директно обръщане като
...
array[n]
...
без предавани през стека указатели, можеше да се обръща към програмната памет, когато масива е деклариран там.

Но вече няма какво да пишем по въпроса, няколко часа скърцах за разлики от един и друг компилатор, проблема е решен и продължавам нататък.

Автор:  woody [ Сря Окт 22, 2008 12:34 pm ]
Заглавие: 

Ако трябваше да правя порт на GCC за подобна платформа също щях да оставя директния достъп до масивите както си е - "неинтелигентен". Помисли само какво щеще да се случи ако това работеше а пък указателите не работят, преди да я има тази тема - щеще да си много по-учуден че дори и бесен понеже нямаше и да подозираш за особеностите на различните адресни пространства. ;)

Виждам че имаш интерес, така че с времето ще разбереш за някои особености на 'C' и всичко около него и тогава всичко ще си дойде на мястото. Само не спирай мисловния процес. ](*,)

Успехи! :)

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/